[FE][Classroom] Fixes #17 - Add button to increase expiry date by 2 months

This commit is contained in:
Araozu 2023-11-22 11:21:20 -05:00
parent 930c4ef56e
commit 8d8c5b0cca
2 changed files with 109 additions and 45 deletions

View File

@ -6,9 +6,11 @@ import { ArrowsClockwiseIcon } from "../../icons/ArrowsClockwiseIcon";
import { JsonResult } from "../../types/JsonResult"; import { JsonResult } from "../../types/JsonResult";
import { AxiosError } from "axios"; import { AxiosError } from "axios";
import { WarningIcon } from "../../icons/WarningIcon"; import { WarningIcon } from "../../icons/WarningIcon";
import { PlusIcon } from "../../icons/PlusIcon";
export function AccountExpiration(props: {userId: number}) { export function AccountExpiration(props: {userId: number}) {
const [expirationDate, setExpirationDate] = createSignal<string | null>(null); // YYYY-MM-DD const [expirationDate, setExpirationDate] = createSignal<string | null>(null); // YYYY-MM-DD
const [localExpirationDate, setLocalExpirationDate] = createSignal<string | null>(null); // YYYY-MM-DD
const {status, setStatus, error, setError} = useLoading(); const {status, setStatus, error, setError} = useLoading();
const loading = createMemo(() => status() === LoadingStatus.Loading); const loading = createMemo(() => status() === LoadingStatus.Loading);
@ -28,6 +30,7 @@ export function AccountExpiration(props: {userId: number}) {
setError(""); setError("");
setStatus(LoadingStatus.Loading); setStatus(LoadingStatus.Loading);
setExpirationDate(null); setExpirationDate(null);
setLocalExpirationDate(null);
backend.get<JsonResult<string>>(`/api/classroom/expiration_date/${props.userId}`) backend.get<JsonResult<string>>(`/api/classroom/expiration_date/${props.userId}`)
.then((response) => { .then((response) => {
@ -51,15 +54,25 @@ export function AccountExpiration(props: {userId: number}) {
}); });
}; };
const setExpiration2Months = () => {
setStatus(LoadingStatus.Loading);
const newDate = new Date();
newDate.setDate(newDate.getDate() + 60);
setLocalExpirationDate(newDate.toISOString().split("T")[0]);
setExpiration();
};
const setExpiration = () => { const setExpiration = () => {
setStatus(LoadingStatus.Loading); setStatus(LoadingStatus.Loading);
backend.put<JsonResult<null>>( backend.put<JsonResult<null>>(
`/api/classroom/expiration_date/${props.userId}`, `/api/classroom/expiration_date/${props.userId}`,
{date: expirationDate()}, {date: localExpirationDate()},
) )
.then((response) => { .then((response) => {
if (response.status === 200) { if (response.status === 200) {
loadExpiration();
setStatus(LoadingStatus.Ok); setStatus(LoadingStatus.Ok);
} }
}) })
@ -72,7 +85,7 @@ export function AccountExpiration(props: {userId: number}) {
onMount(loadExpiration); onMount(loadExpiration);
return ( return (
<OutlinedCard class="w-[24rem] h-[10.5rem] overflow-hidden"> <OutlinedCard class="w-[24rem] overflow-hidden">
<h2 class="text-xl p-3 bg-c-surface-variant text-c-on-surface-variant"> <h2 class="text-xl p-3 bg-c-surface-variant text-c-on-surface-variant">
Fecha de expiración del acceso Fecha de expiración del acceso
</h2> </h2>
@ -106,55 +119,91 @@ export function AccountExpiration(props: {userId: number}) {
</span> </span>
</p> </p>
<p class="grid grid-cols-[auto_9rem] items-center"> <hr />
<span>
Fecha de expiración:
</span>
<input <div class="grid grid-cols-2">
class="bg-c-surface text-c-on-surface border border-c-outline rounded-lg py-1 px-2 font-mono <div class="border-r border-c-outline pt-2 pr-1">
disabled:opacity-50 disabled:cursor-not-allowed" <p>Ampliar por preset:</p>
type="date"
name="classroom-expiration-update" <button
id="classroom-expiration-update" class="bg-c-primary text-c-on-primary px-3 py-2 rounded-full cursor-pointer
value={expirationDate() ?? ""} disabled:opacity-50 disabled:cursor-not-allowed relative mt-[2.47rem]"
oninput={(e) => setExpirationDate(e.target.value)} type="button"
disabled={status() === LoadingStatus.Loading} disabled={loading()}
/> onclick={setExpiration2Months}
</p> >
<span class="mr-6">
Agregar 2 meses
</span>
<span
class="absolute top-1 right-2"
style={{display: loading() ? "inline-block" : "none"}}
>
<LoadingIcon
class="animate-spin"
fill="var(--c-primary-container)"
/>
</span>
<span
class="absolute top-1 right-1"
style={{display: loading() ? "none" : "inline-block"}}
>
<PlusIcon
fill="var(--c-on-primary)"
/>
</span>
</button>
</div>
<div class="pt-2 pl-1 text-right">
<p>Ampliar manualmente:</p>
<input
class="bg-c-surface text-c-on-surface border border-c-outline rounded-lg py-1 px-2 font-mono
disabled:opacity-50 disabled:cursor-not-allowed my-1"
type="date"
name="classroom-expiration-update"
id="classroom-expiration-update"
value={localExpirationDate() ?? ""}
oninput={(e) => setLocalExpirationDate(e.target.value)}
disabled={status() === LoadingStatus.Loading}
/>
<button
class="bg-c-primary text-c-on-primary px-4 py-2 rounded-full cursor-pointer
disabled:opacity-50 disabled:cursor-not-allowed relative"
type="button"
disabled={loading()}
onclick={setExpiration}
>
<span class="mr-6">
Actualizar
</span>
<span
class="absolute top-1 right-2"
style={{display: loading() ? "inline-block" : "none"}}
>
<LoadingIcon
class="animate-spin"
fill="var(--c-primary-container)"
/>
</span>
<span
class="absolute top-1 right-2"
style={{display: loading() ? "none" : "inline-block"}}
>
<ArrowsClockwiseIcon
fill="var(--c-on-primary)"
/>
</span>
</button>
</div>
</div>
<div class="pt-2 grid grid-cols-[auto_8.5rem] items-center gap-2"> <div class="pt-2 grid grid-cols-[auto_8.5rem] items-center gap-2">
<span class="text-c-error"> <span class="text-c-error">
{error()} {error()}
</span> </span>
<button
class="bg-c-primary text-c-on-primary px-4 py-2 rounded-full cursor-pointer
disabled:opacity-50 disabled:cursor-not-allowed relative"
type="button"
disabled={loading()}
onclick={setExpiration}
>
<span class="mr-6">
Actualizar
</span>
<span
class="absolute top-1 right-2"
style={{display: loading() ? "inline-block" : "none"}}
>
<LoadingIcon
class="animate-spin"
fill="var(--c-primary-container)"
/>
</span>
<span
class="absolute top-1 right-2"
style={{display: loading() ? "none" : "inline-block"}}
>
<ArrowsClockwiseIcon
fill="var(--c-on-primary)"
/>
</span>
</button>
</div> </div>
</div> </div>

View File

@ -0,0 +1,15 @@
export function PlusIcon(props: {fill: string, size?: number, class?: string}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
class={`inline-block w-6 ${props.class}`}
width={props.size ?? 32}
height={props.size ?? 32}
fill={props.fill}
viewBox="0 0 256 256"
>
<path d="M224,128a8,8,0,0,1-8,8H136v80a8,8,0,0,1-16,0V136H40a8,8,0,0,1,0-16h80V40a8,8,0,0,1,16,0v80h80A8,8,0,0,1,224,128Z" />
</svg>
);
}