From d7f5ec8c4781e787ad29dd29bb1709ef43caf644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=BA=C5=A1=20Hlav=C3=A1=C4=8Dik?= Date: Thu, 16 Nov 2023 00:57:03 +0100 Subject: [PATCH] File uploader - uprava upozorneni (#221) * Add can resubmit logic * Improve allerts of user when resubmit or after deadline * fix after review --- src/components/Problems/Problem.tsx | 3 + src/components/Problems/Problems.tsx | 15 +++- .../Problems/UploadProblemForm.module.scss | 7 +- .../UploadProblemForm.module.scss.d.ts | 1 + src/components/Problems/UploadProblemForm.tsx | 80 +++++++++++++------ src/types/api/competition.ts | 1 + 6 files changed, 82 insertions(+), 25 deletions(-) diff --git a/src/components/Problems/Problem.tsx b/src/components/Problems/Problem.tsx index 6041b6e9..602e449f 100644 --- a/src/components/Problems/Problem.tsx +++ b/src/components/Problems/Problem.tsx @@ -21,6 +21,7 @@ export const Problem: FC<{ registered: boolean canRegister: boolean canSubmit: boolean + isAfterDeadline: boolean invalidateSeriesQuery: () => Promise displayRegisterDialog: () => void }> = ({ @@ -29,6 +30,7 @@ export const Problem: FC<{ setDisplaySideContent, canRegister, canSubmit, + isAfterDeadline, invalidateSeriesQuery, displayRegisterDialog, }) => { @@ -73,6 +75,7 @@ export const Problem: FC<{ problemId={problem.id} setDisplayProblemUploadForm={setDisplayProblemUploadForm} problemSubmitted={!!problem.submitted} + isAfterDeadline={isAfterDeadline} invalidateSeriesQuery={invalidateSeriesQuery} setDisplayActions={setDisplayActions} /> diff --git a/src/components/Problems/Problems.tsx b/src/components/Problems/Problems.tsx index 158e0954..b1a4ac57 100644 --- a/src/components/Problems/Problems.tsx +++ b/src/components/Problems/Problems.tsx @@ -2,6 +2,7 @@ import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' import axios from 'axios' import {useRouter} from 'next/router' import {FC, useState} from 'react' +import {useInterval} from 'usehooks-ts' import {Button, Link} from '@/components/Clickable/Clickable' import {SeriesWithProblems} from '@/types/api/competition' @@ -53,6 +54,17 @@ export const Problems: FC = () => { const problems = series?.problems ?? [] const semesterId = series?.semester ?? -1 const canSubmit = series?.can_submit ?? false + const canResubmit = series?.can_resubmit ?? canSubmit + const [isAfterDeadline, setIsAfterDeadline] = useState(new Date(series?.deadline ?? '') < new Date()) + + useInterval( + () => { + const isAfterDeadlineNew = new Date(series?.deadline ?? '') < new Date() + isAfterDeadlineNew !== isAfterDeadline && setIsAfterDeadline(isAfterDeadlineNew) + }, + // Delay to null to stop it after deadline + isAfterDeadline ? null : 500, + ) const [overrideCanRegister, setOverrideCanRegister] = useState() const [overrideIsRegistered, setOverrideIsRegistered] = useState() @@ -118,7 +130,8 @@ export const Problems: FC = () => { setDisplaySideContent={setDisplaySideContent} registered={isRegistered} canRegister={canRegister} - canSubmit={canSubmit} + canSubmit={problem.submitted ? canResubmit : canSubmit} + isAfterDeadline={isAfterDeadline} invalidateSeriesQuery={invalidateSeriesQuery} displayRegisterDialog={() => setDisplayRegisterDialog(true)} /> diff --git a/src/components/Problems/UploadProblemForm.module.scss b/src/components/Problems/UploadProblemForm.module.scss index 3891ec84..daaa723d 100644 --- a/src/components/Problems/UploadProblemForm.module.scss +++ b/src/components/Problems/UploadProblemForm.module.scss @@ -10,6 +10,10 @@ position: relative; } +.inputWrapper { + position: relative; +} + .files { margin-top: 8px; display: grid; @@ -39,5 +43,6 @@ .closeButton { position: absolute; - right: 0; + right: 2px; + top: 2px; } diff --git a/src/components/Problems/UploadProblemForm.module.scss.d.ts b/src/components/Problems/UploadProblemForm.module.scss.d.ts index 16c963c3..1f67a88d 100644 --- a/src/components/Problems/UploadProblemForm.module.scss.d.ts +++ b/src/components/Problems/UploadProblemForm.module.scss.d.ts @@ -4,6 +4,7 @@ export type Styles = { closeButton: string container: string files: string + inputWrapper: string problemSubmitted: string } diff --git a/src/components/Problems/UploadProblemForm.tsx b/src/components/Problems/UploadProblemForm.tsx index 817f9929..f9f982c0 100644 --- a/src/components/Problems/UploadProblemForm.tsx +++ b/src/components/Problems/UploadProblemForm.tsx @@ -7,22 +7,23 @@ import {CloseButton} from '@/components/CloseButton/CloseButton' import {niceBytes} from '@/utils/niceBytes' import {Button} from '../Clickable/Clickable' +import {Dialog} from '../Dialog/Dialog' import {FileDropZone} from '../FileDropZone/FileDropZone' import styles from './UploadProblemForm.module.scss' export const UploadProblemForm: FC<{ problemId: number setDisplayProblemUploadForm: Dispatch> - problemSubmitted?: boolean + problemSubmitted: boolean + isAfterDeadline: boolean setDisplayActions: Dispatch> invalidateSeriesQuery: () => Promise }> = ({ problemId, setDisplayActions, setDisplayProblemUploadForm, - // problemNumber, problemSubmitted, - // setDisplaySideContent, + isAfterDeadline, invalidateSeriesQuery, }) => { const {mutate: uploadSolution} = useMutation({ @@ -42,7 +43,7 @@ export const UploadProblemForm: FC<{ }) const [files, setFiles] = useState(undefined) - const {acceptedFiles, fileRejections, getRootProps, getInputProps} = useDropzone({ + const {fileRejections, getRootProps, getInputProps} = useDropzone({ multiple: false, accept: { 'application/pdf': ['.pdf'], @@ -68,34 +69,67 @@ export const UploadProblemForm: FC<{ setDisplayActions(true) } + const [displayAlertDialog, setDisplayAlertDialog] = useState(problemSubmitted) + const closeAlertDialog = () => setDisplayAlertDialog(false) + const cancel = () => { + closeAlertDialog() + setDisplayProblemUploadForm(false) + setDisplayActions(true) + } + + const alertMessage = isAfterDeadline + ? 'Toto riešenie nahrávaš PO TERMÍNE. Nahraním nového riešenia prepíšeš svoje predošlé odovzdanie a pri hodnotení budeme zohľadnovať len toto nové riešenie.' + : 'Nahraním nového riešenia prepíšeš svoje predošlé odovzdanie a pri hodnotení budeme zohľadnovať len toto nové riešenie.' + return (
- + {isAfterDeadline &&
Toto riešenie už nahrávaš po termíne.
} {problemSubmitted && (
Pozor, nahraním nového riešenia prepíšeš svoje predošlé odovzdanie.
)} - {!files && ( - - )} - {files?.name && ( -
-
- Súbor: + + + + + } + /> +
+ {!files && ( + <> + + + + )} + {files?.name && ( +
+
+ Súbor: - - {files.name} ({niceBytes(files.size)}) - -
-
- - -
+ + {files.name} ({niceBytes(files.size)}) + +
+
+ + +
- {/* {fileRejections.length > 0 && Nahraný súbor musí byť vo formáte pdf.} */} -
- )} + {fileRejections.length > 0 && Nahraný súbor musí byť vo formáte pdf.} +
+ )} +
) } diff --git a/src/types/api/competition.ts b/src/types/api/competition.ts index 45875149..8403bb0e 100644 --- a/src/types/api/competition.ts +++ b/src/types/api/competition.ts @@ -148,6 +148,7 @@ export interface SeriesWithProblems { is_registered: boolean problems: Problem[] can_submit: boolean + can_resubmit: boolean order: number deadline: string complete: boolean