aboutsummaryrefslogtreecommitdiff
path: root/frontend/src
diff options
context:
space:
mode:
authorWolfboy248 <georgejvindkarlsen@gmail.com>2024-10-18 17:01:01 +0200
committerWolfboy248 <georgejvindkarlsen@gmail.com>2024-10-18 17:01:01 +0200
commitd9974ede3b3914377beb4b07d78885c48bd74aac (patch)
tree6ee6d0adfe62d3ec00dea21dc520dfa09eeaf005 /frontend/src
parentrefactor: upload run logic improvement (diff)
downloadlphub-d9974ede3b3914377beb4b07d78885c48bd74aac.tar.gz
lphub-d9974ede3b3914377beb4b07d78885c48bd74aac.tar.bz2
lphub-d9974ede3b3914377beb4b07d78885c48bd74aac.zip
refactor: delete run on profile
Diffstat (limited to 'frontend/src')
-rw-r--r--frontend/src/App.tsx7
-rw-r--r--frontend/src/api/Api.tsx6
-rw-r--r--frontend/src/api/Maps.tsx9
-rw-r--r--frontend/src/components/Login.tsx3
-rw-r--r--frontend/src/components/UploadRunDialog.tsx3
-rw-r--r--frontend/src/images/Images.tsx4
-rw-r--r--frontend/src/pages/Profile.tsx19
-rw-r--r--frontend/src/types/Map.tsx5
8 files changed, 48 insertions, 8 deletions
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index c34cbcf..a0725f3 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -11,6 +11,7 @@ import Maps from './pages/Maps';
11import User from './pages/User'; 11import User from './pages/User';
12import Homepage from './pages/Homepage'; 12import Homepage from './pages/Homepage';
13import UploadRunDialog from './components/UploadRunDialog'; 13import UploadRunDialog from './components/UploadRunDialog';
14import MapDeleteConfirmDialog from './components/MapDeleteConfirmDialog';
14import Rules from './pages/Rules'; 15import Rules from './pages/Rules';
15import About from './pages/About'; 16import About from './pages/About';
16import { Game } from './types/Game'; 17import { Game } from './types/Game';
@@ -18,6 +19,7 @@ import { API } from './api/Api';
18import Maplist from './pages/Maplist'; 19import Maplist from './pages/Maplist';
19import Rankings from './pages/Rankings'; 20import Rankings from './pages/Rankings';
20import { get_user_id_from_token, get_user_mod_from_token } from './utils/Jwt'; 21import { get_user_id_from_token, get_user_mod_from_token } from './utils/Jwt';
22import { MapDeleteEndpoint } from './types/Map';
21 23
22const App: React.FC = () => { 24const App: React.FC = () => {
23 const [token, setToken] = React.useState<string | undefined>(undefined); 25 const [token, setToken] = React.useState<string | undefined>(undefined);
@@ -29,6 +31,9 @@ const App: React.FC = () => {
29 const [uploadRunDialog, setUploadRunDialog] = React.useState<boolean>(false); 31 const [uploadRunDialog, setUploadRunDialog] = React.useState<boolean>(false);
30 const [uploadRunDialogMapID, setUploadRunDialogMapID] = React.useState<number | undefined>(undefined); 32 const [uploadRunDialogMapID, setUploadRunDialogMapID] = React.useState<number | undefined>(undefined);
31 33
34 const [confirmDialogOpen, setConfirmDialogOpen] = React.useState<boolean>(false);
35 const [currDeleteMapInfo, setCurrDeleteMapInfo] = React.useState<MapDeleteEndpoint>();
36
32 const _fetch_token = async () => { 37 const _fetch_token = async () => {
33 const token = await API.get_token(); 38 const token = await API.get_token();
34 setToken(token); 39 setToken(token);
@@ -79,7 +84,7 @@ const App: React.FC = () => {
79 <Sidebar setToken={setToken} profile={profile} setProfile={setProfile} onUploadRun={() => setUploadRunDialog(true)} /> 84 <Sidebar setToken={setToken} profile={profile} setProfile={setProfile} onUploadRun={() => setUploadRunDialog(true)} />
80 <Routes> 85 <Routes>
81 <Route path="/" element={<Homepage />} /> 86 <Route path="/" element={<Homepage />} />
82 <Route path="/profile" element={<Profile profile={profile} token={token} gameData={games} />} /> 87 <Route path="/profile" element={<Profile profile={profile} token={token} gameData={games} onDeleteRecord={() => setConfirmDialogOpen(true)} />} />
83 <Route path="/users/*" element={<User profile={profile} token={token} gameData={games} />} /> 88 <Route path="/users/*" element={<User profile={profile} token={token} gameData={games} />} />
84 <Route path="/games" element={<Games games={games} />} /> 89 <Route path="/games" element={<Games games={games} />} />
85 <Route path='/games/:id' element={<Maplist />}></Route> 90 <Route path='/games/:id' element={<Maplist />}></Route>
diff --git a/frontend/src/api/Api.tsx b/frontend/src/api/Api.tsx
index 0f0c4d3..d03d0ec 100644
--- a/frontend/src/api/Api.tsx
+++ b/frontend/src/api/Api.tsx
@@ -3,7 +3,7 @@ import { delete_token, get_token } from './Auth';
3import { get_user, get_profile, post_profile } from './User'; 3import { get_user, get_profile, post_profile } from './User';
4import { get_games, get_chapters, get_games_chapters, get_game_maps, get_search } from './Games'; 4import { get_games, get_chapters, get_games_chapters, get_game_maps, get_search } from './Games';
5import { get_official_rankings, get_unofficial_rankings } from './Rankings'; 5import { get_official_rankings, get_unofficial_rankings } from './Rankings';
6import { get_map_summary, get_map_leaderboard, get_map_discussions, get_map_discussion, post_map_discussion, post_map_discussion_comment, delete_map_discussion, post_record } from './Maps'; 6import { get_map_summary, get_map_leaderboard, get_map_discussions, get_map_discussion, post_map_discussion, post_map_discussion_comment, delete_map_discussion, post_record, delete_map_record } from './Maps';
7import { delete_map_summary, post_map_summary, put_map_image, put_map_summary } from './Mod'; 7import { delete_map_summary, post_map_summary, put_map_image, put_map_summary } from './Mod';
8import { UploadRunContent } from '../types/Content'; 8import { UploadRunContent } from '../types/Content';
9 9
@@ -38,6 +38,8 @@ export const API = {
38 post_record: (token: string, run: UploadRunContent) => post_record(token, run), 38 post_record: (token: string, run: UploadRunContent) => post_record(token, run),
39 39
40 delete_map_discussion: (token: string, map_id: string, discussion_id: number) => delete_map_discussion(token, map_id, discussion_id), 40 delete_map_discussion: (token: string, map_id: string, discussion_id: number) => delete_map_discussion(token, map_id, discussion_id),
41
42 delete_map_record: (token: string, map_id: number, record_id: number) => delete_map_record(token, map_id, record_id),
41 // Mod 43 // Mod
42 post_map_summary: (token: string, map_id: string, content: ModMenuContent) => post_map_summary(token, map_id, content), 44 post_map_summary: (token: string, map_id: string, content: ModMenuContent) => post_map_summary(token, map_id, content),
43 45
@@ -47,7 +49,7 @@ export const API = {
47 delete_map_summary: (token: string, map_id: string, route_id: number) => delete_map_summary(token, map_id, route_id), 49 delete_map_summary: (token: string, map_id: string, route_id: number) => delete_map_summary(token, map_id, route_id),
48}; 50};
49 51
50const BASE_API_URL: string = "/api/v1/" 52const BASE_API_URL: string = "https://lp.ardapektezol.com/api/v1/"
51 53
52export function url(path: string): string { 54export function url(path: string): string {
53 return BASE_API_URL + path; 55 return BASE_API_URL + path;
diff --git a/frontend/src/api/Maps.tsx b/frontend/src/api/Maps.tsx
index 6bdc3e6..8295cf2 100644
--- a/frontend/src/api/Maps.tsx
+++ b/frontend/src/api/Maps.tsx
@@ -97,4 +97,13 @@ export const post_record = async (token: string, run: UploadRunContent): Promise
97 }); 97 });
98 return response.data.message; 98 return response.data.message;
99 } 99 }
100}
101
102export const delete_map_record = async (token: string, map_id: number, record_id: number): Promise<boolean> => {
103 const response = await axios.delete(url(`maps/${map_id}/record/${record_id}`), {
104 headers: {
105 "Authorization": token,
106 }
107 });
108 return response.data.success;
100}; 109};
diff --git a/frontend/src/components/Login.tsx b/frontend/src/components/Login.tsx
index a8c5503..f27a63e 100644
--- a/frontend/src/components/Login.tsx
+++ b/frontend/src/components/Login.tsx
@@ -17,7 +17,8 @@ const Login: React.FC<LoginProps> = ({ setToken, profile, setProfile }) => {
17 const navigate = useNavigate(); 17 const navigate = useNavigate();
18 18
19 const _login = () => { 19 const _login = () => {
20 window.location.href = "/api/v1/login"; 20 setToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzExNjU1NTgsIm1vZCI6dHJ1ZSwic3ViIjoiNzY1NjExOTgxMzE2Mjk5ODkifQ.KoENjj6Z41-QQu1VKvgAiACsjLK7IoVWlJgrGdr6s24");
21 // window.location.href = "/api/v1/login";
21 }; 22 };
22 23
23 const _logout = () => { 24 const _logout = () => {
diff --git a/frontend/src/components/UploadRunDialog.tsx b/frontend/src/components/UploadRunDialog.tsx
index 08d4108..d42ffe7 100644
--- a/frontend/src/components/UploadRunDialog.tsx
+++ b/frontend/src/components/UploadRunDialog.tsx
@@ -172,6 +172,9 @@ const UploadRunDialog: React.FC<UploadRunDialogProps> = ({ token, open, onClose,
172 </> 172 </>
173 ) 173 )
174 } 174 }
175 <div className='search-container'>
176
177 </div>
175 <div className='upload-run-buttons-container'> 178 <div className='upload-run-buttons-container'>
176 <button onClick={_upload_run}>Submit</button> 179 <button onClick={_upload_run}>Submit</button>
177 <button onClick={() => onClose()}>Cancel</button> 180 <button onClick={() => onClose()}>Cancel</button>
diff --git a/frontend/src/images/Images.tsx b/frontend/src/images/Images.tsx
index 89b99c0..198431b 100644
--- a/frontend/src/images/Images.tsx
+++ b/frontend/src/images/Images.tsx
@@ -20,6 +20,7 @@ import img17 from './png/17.png';
20import img18 from './png/18.png'; 20import img18 from './png/18.png';
21import img19 from './png/19.png'; 21import img19 from './png/19.png';
22import img20 from './png/20.png'; 22import img20 from './png/20.png';
23import img21 from "./png/21.png";
23 24
24export const LogoIcon = logo; 25export const LogoIcon = logo;
25export const LoginIcon = login; 26export const LoginIcon = login;
@@ -43,4 +44,5 @@ export const YouTubeIcon = img16;
43export const SteamIcon = img17; 44export const SteamIcon = img17;
44export const HistoryIcon = img18; 45export const HistoryIcon = img18;
45export const SortIcon = img19; 46export const SortIcon = img19;
46export const UploadIcon = img20; \ No newline at end of file 47export const UploadIcon = img20;
48export const DeleteIcon = img21; \ No newline at end of file
diff --git a/frontend/src/pages/Profile.tsx b/frontend/src/pages/Profile.tsx
index e20d930..5e39308 100644
--- a/frontend/src/pages/Profile.tsx
+++ b/frontend/src/pages/Profile.tsx
@@ -1,21 +1,23 @@
1import React from 'react'; 1import React from 'react';
2import { Link, useLocation, useNavigate } from 'react-router-dom'; 2import { Link, useLocation, useNavigate } from 'react-router-dom';
3 3
4import { SteamIcon, TwitchIcon, YouTubeIcon, PortalIcon, FlagIcon, StatisticsIcon, SortIcon, ThreedotIcon, DownloadIcon, HistoryIcon } from '../images/Images'; 4import { SteamIcon, TwitchIcon, YouTubeIcon, PortalIcon, FlagIcon, StatisticsIcon, SortIcon, ThreedotIcon, DownloadIcon, HistoryIcon, DeleteIcon } from '../images/Images';
5import { UserProfile } from '../types/Profile'; 5import { UserProfile } from '../types/Profile';
6import { Game, GameChapters } from '../types/Game'; 6import { Game, GameChapters } from '../types/Game';
7import { Map } from '../types/Map'; 7import { Map } from '../types/Map';
8import { ticks_to_time } from '../utils/Time'; 8import { ticks_to_time } from '../utils/Time';
9import "../css/Profile.css"; 9import "../css/Profile.css";
10import { API } from '../api/Api'; 10import { API } from '../api/Api';
11import MapDeleteConfirmDialog from '../components/MapDeleteConfirmDialog';
11 12
12interface ProfileProps { 13interface ProfileProps {
13 profile?: UserProfile; 14 profile?: UserProfile;
14 token?: string; 15 token?: string;
15 gameData: Game[]; 16 gameData: Game[];
17 onDeleteRecord: () => void;
16} 18}
17 19
18const Profile: React.FC<ProfileProps> = ({ profile, token, gameData }) => { 20const Profile: React.FC<ProfileProps> = ({ profile, token, gameData, onDeleteRecord }) => {
19 21
20 const [navState, setNavState] = React.useState(0); 22 const [navState, setNavState] = React.useState(0);
21 const [pageNumber, setPageNumber] = React.useState(1); 23 const [pageNumber, setPageNumber] = React.useState(1);
@@ -58,6 +60,16 @@ const Profile: React.FC<ProfileProps> = ({ profile, token, gameData }) => {
58 } 60 }
59 }; 61 };
60 62
63 const _delete_submission = async (map_id: number, record_id: number) => {
64 onDeleteRecord();
65 const api_success = await API.delete_map_record(token!, map_id, record_id);
66 if (api_success) {
67 window.alert("Successfully deleted record");
68 } else {
69 window.alert("Error: Could not delete record");
70 }
71 };
72
61 React.useEffect(() => { 73 React.useEffect(() => {
62 if (!profile) { 74 if (!profile) {
63 navigate("/"); 75 navigate("/");
@@ -228,7 +240,8 @@ const Profile: React.FC<ProfileProps> = ({ profile, token, gameData }) => {
228 <span>{e.date.split("T")[0]}</span> 240 <span>{e.date.split("T")[0]}</span>
229 <span style={{ flexDirection: "row-reverse" }}> 241 <span style={{ flexDirection: "row-reverse" }}>
230 242
231 <button onClick={() => { window.alert(`Demo ID: ${e.demo_id}`) }}><img src={ThreedotIcon} alt="demo_id" /></button> 243 <button style={{marginRight: "10px"}} onClick={() => { window.alert(`Demo ID: ${e.demo_id}`) }}><img src={ThreedotIcon} alt="demo_id" /></button>
244 <button onClick={() => { _delete_submission(r.map_id, e.record_id) }}><img src={DeleteIcon}></img></button>
232 <button onClick={() => window.location.href = `/api/v1/demos?uuid=${e.demo_id}`}><img src={DownloadIcon} alt="download" /></button> 245 <button onClick={() => window.location.href = `/api/v1/demos?uuid=${e.demo_id}`}><img src={DownloadIcon} alt="download" /></button>
233 {i === 0 && r.scores.length > 1 ? <button onClick={() => { 246 {i === 0 && r.scores.length > 1 ? <button onClick={() => {
234 (document.querySelectorAll(".profileboard-record")[index % 20] as HTMLInputElement).style.height === "44px" || 247 (document.querySelectorAll(".profileboard-record")[index % 20] as HTMLInputElement).style.height === "44px" ||
diff --git a/frontend/src/types/Map.tsx b/frontend/src/types/Map.tsx
index 4a6b60e..4669e8b 100644
--- a/frontend/src/types/Map.tsx
+++ b/frontend/src/types/Map.tsx
@@ -101,3 +101,8 @@ interface MapSummaryDetailsRouteHistory {
101 date: string; 101 date: string;
102}; 102};
103 103
104export interface MapDeleteEndpoint {
105 map_id: number;
106 record_id: number;
107}
108