Add install calendar dialog
This commit is contained in:
@ -33,4 +33,11 @@ export class AccommodationsCalendarURLApi {
|
||||
})
|
||||
).data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get accommodation calendar URL route
|
||||
*/
|
||||
static CalendarURL(c: AccommodationCalendarURL): string {
|
||||
return `${APIClient.backendURL()}/acccommodations_calendar/${c.token}`;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
import {
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogActions,
|
||||
Button,
|
||||
Typography,
|
||||
FormControl,
|
||||
IconButton,
|
||||
InputAdornment,
|
||||
InputLabel,
|
||||
OutlinedInput,
|
||||
} from "@mui/material";
|
||||
import {
|
||||
AccommodationCalendarURL,
|
||||
AccommodationsCalendarURLApi,
|
||||
} from "../../api/accommodations/AccommodationsCalendarURLApi";
|
||||
import { VisibilityOff, Visibility } from "@mui/icons-material";
|
||||
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
||||
import { CopyToClipboard } from "../../widgets/CopyToClipboard";
|
||||
import QRCode from "react-qr-code";
|
||||
|
||||
export function InstallCalendarDialog(p: {
|
||||
cal?: AccommodationCalendarURL;
|
||||
onClose: () => void;
|
||||
}): React.ReactElement {
|
||||
if (!p.cal) return <></>;
|
||||
|
||||
return (
|
||||
<Dialog open={true} onClose={p.onClose}>
|
||||
<DialogTitle>Installation du calendrier</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
<Typography>
|
||||
Afin d'installer le calendrier <i>{p.cal.name}</i> sur votre
|
||||
appareil, veuillez utiliser l'URL suivante :
|
||||
</Typography>
|
||||
<br />
|
||||
<FormControl fullWidth variant="outlined">
|
||||
<InputLabel>URL</InputLabel>
|
||||
<OutlinedInput
|
||||
value={AccommodationsCalendarURLApi.CalendarURL(p.cal!)}
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<CopyToClipboard
|
||||
content={AccommodationsCalendarURLApi.CalendarURL(p.cal!)}
|
||||
>
|
||||
<IconButton>
|
||||
<ContentCopyIcon />
|
||||
</IconButton>
|
||||
</CopyToClipboard>
|
||||
</InputAdornment>
|
||||
}
|
||||
label="Password"
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
margin: "20px auto",
|
||||
padding: "20px",
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
>
|
||||
<QRCode
|
||||
value={AccommodationsCalendarURLApi.CalendarURL(p.cal!)}
|
||||
/>
|
||||
</div>
|
||||
</FormControl>
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={p.onClose}>Fermer</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
import React, { PropsWithChildren } from "react";
|
||||
import { AccommodationCalendarURL } from "../../../api/accommodations/AccommodationsCalendarURLApi";
|
||||
import { InstallCalendarDialog } from "../../../dialogs/accommodations/InstallCalendarDialog";
|
||||
|
||||
type DialogContext = (cal: AccommodationCalendarURL) => Promise<void>;
|
||||
|
||||
const DialogContextK = React.createContext<DialogContext | null>(null);
|
||||
|
||||
export function InstallCalendarDialogProvider(
|
||||
p: PropsWithChildren
|
||||
): React.ReactElement {
|
||||
const [cal, setCal] = React.useState<AccommodationCalendarURL | undefined>();
|
||||
|
||||
const cb = React.useRef<null | (() => void)>(null);
|
||||
|
||||
const handleClose = () => {
|
||||
setCal(undefined);
|
||||
|
||||
if (cb.current !== null) cb.current();
|
||||
cb.current = null;
|
||||
};
|
||||
|
||||
const hook: DialogContext = (c) => {
|
||||
setCal(c);
|
||||
|
||||
return new Promise((res) => {
|
||||
cb.current = res;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DialogContextK.Provider value={hook}>
|
||||
{p.children}
|
||||
</DialogContextK.Provider>
|
||||
|
||||
{cal && <InstallCalendarDialog cal={cal} onClose={handleClose} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function useInstallCalendarDialog(): DialogContext {
|
||||
return React.useContext(DialogContextK)!;
|
||||
}
|
@ -24,6 +24,8 @@ import { TimeWidget } from "../../../widgets/TimeWidget";
|
||||
import { useAccommodations } from "../../../widgets/accommodations/BaseAccommodationsRoute";
|
||||
import { useCreateAccommodationCalendarURL } from "../../../hooks/context_providers/accommodations/CreateAccommodationCalendarURLDialogProvider";
|
||||
import { AccommodationsCalendarURLApi } from "../../../api/accommodations/AccommodationsCalendarURLApi";
|
||||
import { useInstallCalendarDialog } from "../../../hooks/context_providers/accommodations/InstallCalendarDialogProvider";
|
||||
import { InstallCalendarDialog } from "../../../dialogs/accommodations/InstallCalendarDialog";
|
||||
|
||||
export function AccommodationsSettingsRoute(): React.ReactElement {
|
||||
return (
|
||||
@ -224,6 +226,7 @@ function AccommodationsCalURLsCard(): React.ReactElement {
|
||||
const family = useFamily();
|
||||
|
||||
const createCalendarURLDialog = useCreateAccommodationCalendarURL();
|
||||
const calendarURLDialog = useInstallCalendarDialog();
|
||||
|
||||
const createCalendarURL = async () => {
|
||||
try {
|
||||
@ -241,8 +244,8 @@ function AccommodationsCalURLsCard(): React.ReactElement {
|
||||
setSuccess("Le calendrier a été créé avec succès !");
|
||||
|
||||
// TODO : reload URLS list
|
||||
// TODO : show QrCode dialog
|
||||
console.log(cal);
|
||||
|
||||
calendarURLDialog(cal);
|
||||
} catch (e) {
|
||||
console.error("Failed to create new accommodation calendar URL!", e);
|
||||
setError(`Échec de la création du calendrier! ${e}`);
|
||||
|
30
geneit_app/src/widgets/CopyToClipboard.tsx
Normal file
30
geneit_app/src/widgets/CopyToClipboard.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
import { ButtonBase } from "@mui/material";
|
||||
import { PropsWithChildren } from "react";
|
||||
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
|
||||
|
||||
export function CopyToClipboard(
|
||||
p: PropsWithChildren<{ content: string }>
|
||||
): React.ReactElement {
|
||||
const snackbar = useSnackbar();
|
||||
|
||||
const copy = () => {
|
||||
navigator.clipboard.writeText(p.content);
|
||||
snackbar(`${p.content} copied to clipboard.`);
|
||||
};
|
||||
|
||||
return (
|
||||
<ButtonBase
|
||||
onClick={copy}
|
||||
style={{
|
||||
display: "inline-block",
|
||||
alignItems: "unset",
|
||||
textAlign: "unset",
|
||||
position: "relative",
|
||||
padding: "0px",
|
||||
}}
|
||||
disableRipple
|
||||
>
|
||||
{p.children}
|
||||
</ButtonBase>
|
||||
);
|
||||
}
|
@ -8,6 +8,7 @@ import { CreateAccommodationCalendarURLDialogProvider } from "../../hooks/contex
|
||||
import { UpdateAccommodationDialogProvider } from "../../hooks/context_providers/accommodations/UpdateAccommodationDialogProvider";
|
||||
import { AsyncWidget } from "../AsyncWidget";
|
||||
import { useFamily } from "../BaseFamilyRoute";
|
||||
import { InstallCalendarDialogProvider } from "../../hooks/context_providers/accommodations/InstallCalendarDialogProvider";
|
||||
|
||||
interface AccommodationsContext {
|
||||
accommodations: AccommodationsList;
|
||||
@ -63,7 +64,9 @@ export function BaseAccommodationsRoute(): React.ReactElement {
|
||||
>
|
||||
<UpdateAccommodationDialogProvider>
|
||||
<CreateAccommodationCalendarURLDialogProvider>
|
||||
<Outlet />
|
||||
<InstallCalendarDialogProvider>
|
||||
<Outlet />
|
||||
</InstallCalendarDialogProvider>
|
||||
</CreateAccommodationCalendarURLDialogProvider>
|
||||
</UpdateAccommodationDialogProvider>
|
||||
</AccommodationsContextK.Provider>
|
||||
|
Reference in New Issue
Block a user