diff --git a/src/App.tsx b/src/App.tsx index 4b31d83..0f8dcb4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,7 +18,7 @@ export default function App() { return (
- + @@ -26,15 +26,15 @@ export default function App() { } /> - }> + }> } /> + } /> } /> } /> } /> - } /> - } /> - }/> + } /> + } /> } /> @@ -47,7 +47,7 @@ export default function App() { function AppLayout() { return <> -
- +
+ } \ No newline at end of file diff --git a/src/Fetcher.ts b/src/Fetcher.ts index b496894..05d8d47 100644 --- a/src/Fetcher.ts +++ b/src/Fetcher.ts @@ -10,6 +10,7 @@ export async function fetchAPI( url: string, payload: unknown, method = "POST", + redirectIfNotAuth: boolean = true, ): Promise { const session = getSession() @@ -30,12 +31,13 @@ export async function fetchAPI( body: JSON.stringify(payload), }) - return await handleResponse(session, response) + return await handleResponse(session, response, redirectIfNotAuth) } export async function fetchAPIGet( url: string, + redirectIfNotAuth: boolean = true, ): Promise { const session = getSession() @@ -55,20 +57,22 @@ export async function fetchAPIGet( headers, }) - return await handleResponse(session, response) + return await handleResponse(session, response, redirectIfNotAuth) } -async function handleResponse(session: Session, response: Response): Promise { +async function handleResponse(session: Session, response: Response, redirectIfNotAuth: boolean): Promise { // if we provided a token but still unauthorized, the token has expired if (response.status == 401) { + if (!redirectIfNotAuth) + return response redirect("/login") - saveSession({...session, urlTarget: location.pathname}) + saveSession({ ...session, urlTarget: location.pathname }) return response } const nextToken = response.headers.get("Next-Authorization")! const expirationDate = Date.parse(response.headers.get("Next-Authorization-Expiration-Date")!) - saveSession({...session, auth: {token: nextToken, expirationDate}}) + saveSession({ ...session, auth: { token: nextToken, expirationDate } }) return response } diff --git a/src/api/session.ts b/src/api/session.ts index 7e32776..fad80ad 100644 --- a/src/api/session.ts +++ b/src/api/session.ts @@ -1,6 +1,7 @@ export interface Session { auth?: Authentication urlTarget?: string + username?: string } export interface Authentication { diff --git a/src/pages/Editor.tsx b/src/pages/Editor.tsx index ffdbb64..afd4501 100644 --- a/src/pages/Editor.tsx +++ b/src/pages/Editor.tsx @@ -50,6 +50,7 @@ import BallAction from "../components/actions/BallAction" import { changePlayerBallState, getOrigin, removePlayer } from "../editor/PlayerDomains" import { CourtBall } from "../components/editor/CourtBall" import { useParams } from "react-router-dom" +import { DEFAULT_TACTIC_NAME } from "./NewTacticPage.tsx" const ERROR_STYLE: CSSProperties = { borderColor: "red", @@ -57,31 +58,12 @@ const ERROR_STYLE: CSSProperties = { const GUEST_MODE_CONTENT_STORAGE_KEY = "guest_mode_content" const GUEST_MODE_TITLE_STORAGE_KEY = "guest_mode_title" -const DEFAULT_TACTIC_NAME = "Nouvelle tactique" export interface EditorViewProps { tactic: Tactic onContentChange: (tactic: TacticContent) => Promise onNameChange: (name: string) => Promise } - -type EditorCreateNewAction = { type: "new", courtType: CourtType } -type EditorOpenAction = { type: "open" } - -type EditorAction = EditorCreateNewAction | EditorOpenAction - -export interface EditorPageProps { - action: EditorAction -} - -export default function EditorPage({ action }: EditorPageProps) { - console.log(action) - if (action.type === "new") { - return - } - return -} - interface TacticDto { id: number name: string @@ -89,14 +71,22 @@ interface TacticDto { content: string } +interface EditorPageProps { + guestMode: boolean +} -function EditorOpen() { - const { tacticId: idStr } = useParams() - const id = parseInt(idStr!) - +export default function EditorPage({ guestMode }: EditorPageProps) { const [tactic, setTactic] = useState() + const { tacticId: idStr } = useParams() + const id = guestMode ? -1 : parseInt(idStr!) useEffect(() => { + + if (guestMode) { + setTactic({id: -1, courtType: "PLAIN", content: "{\"components\": []}", name: DEFAULT_TACTIC_NAME}) + return + } + async function initialize() { console.log("initializing") const infoResponse = fetchAPIGet(`tactics/${id}`) @@ -109,7 +99,7 @@ function EditorOpen() { } initialize() - }, [id]) + }, [guestMode, id, idStr]) if (tactic) { return } -function EditorCreateNew({ courtType }: EditorCreateNewAction) { - const [id, setId] = useState() - - useEffect(() => { - async function initialize() { - const response = await fetchAPI("tactics", { - name: DEFAULT_TACTIC_NAME, - courtType - }, "POST") - const { id } = await response.json() - setId(id) - } - - initialize() - }, [courtType]) - - if (id) { - return - } - - return -} function EditorLoadingScreen() { return
Loading Editor, please wait...
@@ -165,13 +128,13 @@ export interface EditorProps { function Editor({ id, name, courtType, content }: EditorProps) { const isInGuestMode = id == -1 - const storage_content = localStorage.getItem(GUEST_MODE_CONTENT_STORAGE_KEY) + const storageContent = localStorage.getItem(GUEST_MODE_CONTENT_STORAGE_KEY) const editorContent = - isInGuestMode && storage_content != null ? storage_content : content + isInGuestMode && storageContent != null ? storageContent : content - const storage_name = localStorage.getItem(GUEST_MODE_TITLE_STORAGE_KEY) + const storageName = localStorage.getItem(GUEST_MODE_TITLE_STORAGE_KEY) const editorName = - isInGuestMode && storage_name != null ? storage_name : name + isInGuestMode && storageName != null ? storageName : name return (
@@ -30,18 +36,33 @@ export default function NewTacticPage() { } function CourtKindButton({ - name, - image, - redirect, -}: { + name, + image, + courtType, + }: { name: string image: string - redirect: string + courtType: CourtType }) { return (
(location.href = BASE + redirect)}> + onClick={useCallback(async () => { + + // if user is not authenticated + if (!getSession().auth) { + redirect(`/tactic/edit-guest`) + } + + const response = await fetchAPI("tactics", { + name: DEFAULT_TACTIC_NAME, + courtType, + }, "POST") + + const { id } = await response.json() + redirect(`/tactic/${id}/edit`) + + }, [courtType])}>
(session.username ?? null) useEffect(() => { - async function getUsername() { - const response = await fetchAPIGet("user") + async function loadUsername() { + const response = await fetchAPIGet("user", false) + + if (response.status == 401) { //if unauthorized + return + } + + console.log(session) + //TODO check if the response is ok and handle errors - const {name} = await response.json() - setUsername(name) + const { name: username } = await response.json() + saveSession({ ...session, username }) + setUsername(username) } - getUsername() - }, []) + + // if the user is authenticated and the username is not already present in the session, + if (session.auth && !session.username) + loadUsername() + + + }, [session]) return (
-
+
{ + if (username) { + redirect("/settings") + return + } + saveSession({...session, urlTarget: location.pathname}) + redirect("/login") + }}> {/* */} - { - location.pathname = BASE + "/settings" - }} - /> -

{username}

+ +

{username ?? "Log In"}

diff --git a/src/style/template/header.css b/src/style/template/header.css index 78d1289..4c2d4aa 100644 --- a/src/style/template/header.css +++ b/src/style/template/header.css @@ -9,9 +9,6 @@ justify-content: space-between; font-family: var(--font-title); - - - height: 50px; } #img-account { @@ -31,7 +28,7 @@ #username { color: var(--main-contrast-color); - margin-left: 10px; + margin: 0 0 0 10px; } #clickable-header-right:hover #username { @@ -48,10 +45,6 @@ justify-content: space-evenly; } -#clickable-header-right:hover { - border: orange 1px solid; -} - .clickable { cursor: pointer; }