codeforlife 2.9.2 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Countdown-7-Mzftzr.cjs +2 -0
- package/dist/{Countdown-CTNMDtaU.cjs.map → Countdown-7-Mzftzr.cjs.map} +1 -1
- package/dist/{Countdown-D4s4yfhB.js → Countdown-ZA68a09m.js} +4 -4
- package/dist/{Countdown-D4s4yfhB.js.map → Countdown-ZA68a09m.js.map} +1 -1
- package/dist/{Image-D5jC9UoX.js → Image-KHEjEELP.js} +2 -2
- package/dist/{Image-D5jC9UoX.js.map → Image-KHEjEELP.js.map} +1 -1
- package/dist/{LinkButton-COnDB_KU.js → LinkButton-Do07PnhU.js} +4 -4
- package/dist/LinkButton-Do07PnhU.js.map +1 -0
- package/dist/LinkButton-cfljqSBx.cjs +2 -0
- package/dist/LinkButton-cfljqSBx.cjs.map +1 -0
- package/dist/Navigate-Cu8Ge031.cjs +2 -0
- package/dist/Navigate-Cu8Ge031.cjs.map +1 -0
- package/dist/{Navigate-Baeudg5V.js → Navigate-DC6ag0th.js} +4 -4
- package/dist/Navigate-DC6ag0th.js.map +1 -0
- package/dist/api/endpoints/index.es.js +2 -2
- package/dist/api/index.es.js +3 -3
- package/dist/{api-Cbyt3rw0.js → api-CYqNqtN9.js} +2 -2
- package/dist/{api-Cbyt3rw0.js.map → api-CYqNqtN9.js.map} +1 -1
- package/dist/auth-C_aSIrwD.cjs +2 -0
- package/dist/auth-C_aSIrwD.cjs.map +1 -0
- package/dist/{auth-C9qgLRQ4.js → auth-CvJ5Mh6y.js} +17 -17
- package/dist/auth-CvJ5Mh6y.js.map +1 -0
- package/dist/components/form/index.es.js +1 -1
- package/dist/components/index.cjs.js +1 -10
- package/dist/components/index.cjs.js.map +1 -1
- package/dist/components/index.es.js +179 -256
- package/dist/components/index.es.js.map +1 -1
- package/dist/components/page/index.cjs.js +1 -1
- package/dist/components/page/index.es.js +1 -1
- package/dist/components/router/Navigate.d.ts +1 -1
- package/dist/components/router/index.cjs.js +1 -1
- package/dist/components/router/index.es.js +2 -2
- package/dist/components/table/index.es.js +1 -1
- package/dist/features/index.cjs.js +1 -1
- package/dist/features/index.cjs.js.map +1 -1
- package/dist/features/index.es.js +7 -7
- package/dist/hooks/index.cjs.js +1 -1
- package/dist/hooks/index.es.js +1 -1
- package/dist/hooks/router.d.ts +1 -1
- package/dist/{index-2W--_sNE.js → index-B3cd2A-G.js} +2 -2
- package/dist/{index-2W--_sNE.js.map → index-B3cd2A-G.js.map} +1 -1
- package/dist/{index-CkM7p7f8.js → index-Brh3Kbv6.js} +2 -2
- package/dist/{index-CkM7p7f8.js.map → index-Brh3Kbv6.js.map} +1 -1
- package/dist/{index-DALohJdb.js → index-DlQc68Q4.js} +6 -6
- package/dist/index-DlQc68Q4.js.map +1 -0
- package/dist/index-DsVpb45W.cjs +2 -0
- package/dist/index-DsVpb45W.cjs.map +1 -0
- package/dist/{index-Dqp7dpn3.js → index-DuVBQMst.js} +5 -5
- package/dist/{index-Dqp7dpn3.js.map → index-DuVBQMst.js.map} +1 -1
- package/dist/{jsx-runtime-Dpn_P65e.js → jsx-runtime-XvoU0p7t.js} +57 -57
- package/dist/{jsx-runtime-Dpn_P65e.js.map → jsx-runtime-XvoU0p7t.js.map} +1 -1
- package/dist/{schemas-DlOtf2vf.js → schemas-CDXuSjyI.js} +2 -2
- package/dist/{schemas-DlOtf2vf.js.map → schemas-CDXuSjyI.js.map} +1 -1
- package/dist/server.cjs.js +3 -3
- package/dist/server.cjs.js.map +1 -1
- package/dist/server.d.ts +12 -1
- package/dist/server.es.js +84 -56
- package/dist/server.es.js.map +1 -1
- package/dist/theme/components/index.es.js +1 -1
- package/dist/theme/index.es.js +2 -2
- package/dist/{urls-DtHr1d3H.js → urls-BY-za1bX.js} +2 -2
- package/dist/{urls-DtHr1d3H.js.map → urls-BY-za1bX.js.map} +1 -1
- package/dist/utils/api.es.js +2 -2
- package/dist/utils/router.cjs.js +1 -1
- package/dist/utils/router.cjs.js.map +1 -1
- package/dist/utils/router.d.ts +1 -1
- package/dist/utils/router.es.js +3 -3
- package/dist/utils/router.es.js.map +1 -1
- package/dist/utils/test.es.js +1 -1
- package/dist/utils/theme.es.js +2 -2
- package/package.json +3 -3
- package/dist/Countdown-CTNMDtaU.cjs +0 -2
- package/dist/LinkButton-C9y6XyQV.cjs +0 -2
- package/dist/LinkButton-C9y6XyQV.cjs.map +0 -1
- package/dist/LinkButton-COnDB_KU.js.map +0 -1
- package/dist/Navigate-Baeudg5V.js.map +0 -1
- package/dist/Navigate-D8_ubqaT.cjs +0 -2
- package/dist/Navigate-D8_ubqaT.cjs.map +0 -1
- package/dist/auth-C9qgLRQ4.js.map +0 -1
- package/dist/auth-DjC4nR_8.cjs +0 -2
- package/dist/auth-DjC4nR_8.cjs.map +0 -1
- package/dist/index-CiWln8tI.cjs +0 -2
- package/dist/index-CiWln8tI.cjs.map +0 -1
- package/dist/index-DALohJdb.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const n=require("./jsx-runtime-CeSfJrVB.cjs"),c=require("react"),m=require("@mui/material");require("./auth-C_aSIrwD.cjs");const q=require("./general-BPbbmkeX.cjs");require("react-router");require("yup");require("@mui/icons-material");require("./palette-BnIdHKDE.cjs");const x=({seconds:e,start:u=!0,onEnd:i,...o})=>{e=Math.floor(e);const r=q.useCountdown(e)[0],[s,a]=c.useState(!u);r===0&&!s&&(a(!0),i()),e=Math.floor(r%60);const t=Math.floor(r/60);return n.jsxRuntimeExports.jsx(n.jsxRuntimeExports.Fragment,{children:r>0&&n.jsxRuntimeExports.jsxs(m.Typography,{...o,children:[t>0&&`${t} ${t>1?"mins":"min"} `,e>0&&`${e} ${e>1?"secs":"sec"}`]})})};exports.Countdown=x;
|
|
2
|
+
//# sourceMappingURL=Countdown-7-Mzftzr.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Countdown-
|
|
1
|
+
{"version":3,"file":"Countdown-7-Mzftzr.cjs","sources":["../src/components/Countdown.tsx"],"sourcesContent":["import { type FC, useState } from \"react\"\nimport { Typography, type TypographyProps } from \"@mui/material\"\n\nimport { useCountdown } from \"../hooks\"\n\nexport interface CountdownProps extends Omit<TypographyProps, \"children\"> {\n seconds: number\n start?: boolean\n onEnd: () => void\n}\n\nconst Countdown: FC<CountdownProps> = ({\n seconds,\n start = true,\n onEnd,\n ...typographyProps\n}) => {\n seconds = Math.floor(seconds)\n const _seconds = useCountdown(seconds)[0]\n const [end, setEnd] = useState(!start)\n\n if (_seconds === 0 && !end) {\n setEnd(true)\n onEnd()\n }\n\n seconds = Math.floor(_seconds % 60)\n const minutes = Math.floor(_seconds / 60)\n\n return (\n <>\n {_seconds > 0 && (\n <Typography {...typographyProps}>\n {minutes > 0 && `${minutes} ${minutes > 1 ? \"mins\" : \"min\"} `}\n {seconds > 0 && `${seconds} ${seconds > 1 ? \"secs\" : \"sec\"}`}\n </Typography>\n )}\n </>\n )\n}\n\nexport default Countdown\n"],"names":["Countdown","seconds","start","onEnd","typographyProps","_seconds","useCountdown","end","setEnd","useState","minutes","jsxs","Typography"],"mappings":"0RAWA,MAAMA,EAAgC,CAAC,CACrC,QAAAC,EACA,MAAAC,EAAQ,GACR,MAAAC,EACA,GAAGC,CACL,IAAM,CACJH,EAAU,KAAK,MAAMA,CAAO,EAC5B,MAAMI,EAAWC,EAAAA,aAAaL,CAAO,EAAE,CAAC,EAClC,CAACM,EAAKC,CAAM,EAAIC,EAAAA,SAAS,CAACP,CAAK,EAEjCG,IAAa,GAAK,CAACE,IACrBC,EAAO,EAAI,EACXL,EAAA,GAGFF,EAAU,KAAK,MAAMI,EAAW,EAAE,EAClC,MAAMK,EAAU,KAAK,MAAML,EAAW,EAAE,EAExC,6DAEK,SAAAA,EAAW,GACVM,EAAAA,kBAAAA,KAACC,EAAAA,WAAA,CAAY,GAAGR,EACb,SAAA,CAAAM,EAAU,GAAK,GAAGA,CAAO,IAAIA,EAAU,EAAI,OAAS,KAAK,IACzDT,EAAU,GAAK,GAAGA,CAAO,IAAIA,EAAU,EAAI,OAAS,KAAK,EAAA,CAAA,CAC5D,CAAA,CAEJ,CAEJ"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { j as m } from "./jsx-runtime-
|
|
1
|
+
import { j as m } from "./jsx-runtime-XvoU0p7t.js";
|
|
2
2
|
import { useState as s } from "react";
|
|
3
3
|
import { Typography as u } from "@mui/material";
|
|
4
|
-
import "./auth-
|
|
4
|
+
import "./auth-CvJ5Mh6y.js";
|
|
5
5
|
import { a as f } from "./general-CtTJPCJn.js";
|
|
6
|
-
import "react-router
|
|
6
|
+
import "react-router";
|
|
7
7
|
import "yup";
|
|
8
8
|
import "@mui/icons-material";
|
|
9
9
|
import "./palette-CYwuLBW7.js";
|
|
@@ -25,4 +25,4 @@ const w = ({
|
|
|
25
25
|
export {
|
|
26
26
|
w as C
|
|
27
27
|
};
|
|
28
|
-
//# sourceMappingURL=Countdown-
|
|
28
|
+
//# sourceMappingURL=Countdown-ZA68a09m.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Countdown-
|
|
1
|
+
{"version":3,"file":"Countdown-ZA68a09m.js","sources":["../src/components/Countdown.tsx"],"sourcesContent":["import { type FC, useState } from \"react\"\nimport { Typography, type TypographyProps } from \"@mui/material\"\n\nimport { useCountdown } from \"../hooks\"\n\nexport interface CountdownProps extends Omit<TypographyProps, \"children\"> {\n seconds: number\n start?: boolean\n onEnd: () => void\n}\n\nconst Countdown: FC<CountdownProps> = ({\n seconds,\n start = true,\n onEnd,\n ...typographyProps\n}) => {\n seconds = Math.floor(seconds)\n const _seconds = useCountdown(seconds)[0]\n const [end, setEnd] = useState(!start)\n\n if (_seconds === 0 && !end) {\n setEnd(true)\n onEnd()\n }\n\n seconds = Math.floor(_seconds % 60)\n const minutes = Math.floor(_seconds / 60)\n\n return (\n <>\n {_seconds > 0 && (\n <Typography {...typographyProps}>\n {minutes > 0 && `${minutes} ${minutes > 1 ? \"mins\" : \"min\"} `}\n {seconds > 0 && `${seconds} ${seconds > 1 ? \"secs\" : \"sec\"}`}\n </Typography>\n )}\n </>\n )\n}\n\nexport default Countdown\n"],"names":["Countdown","seconds","start","onEnd","typographyProps","_seconds","useCountdown","end","setEnd","useState","minutes","jsxs","Typography"],"mappings":";;;;;;;;;AAWA,MAAMA,IAAgC,CAAC;AAAA,EACrC,SAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,OAAAC;AAAA,EACA,GAAGC;AACL,MAAM;AACJ,EAAAH,IAAU,KAAK,MAAMA,CAAO;AAC5B,QAAMI,IAAWC,EAAaL,CAAO,EAAE,CAAC,GAClC,CAACM,GAAKC,CAAM,IAAIC,EAAS,CAACP,CAAK;AAErC,EAAIG,MAAa,KAAK,CAACE,MACrBC,EAAO,EAAI,GACXL,EAAA,IAGFF,IAAU,KAAK,MAAMI,IAAW,EAAE;AAClC,QAAMK,IAAU,KAAK,MAAML,IAAW,EAAE;AAExC,6CAEK,UAAAA,IAAW,KACVM,gBAAAA,EAAAA,KAACC,GAAA,EAAY,GAAGR,GACb,UAAA;AAAA,IAAAM,IAAU,KAAK,GAAGA,CAAO,IAAIA,IAAU,IAAI,SAAS,KAAK;AAAA,IACzDT,IAAU,KAAK,GAAGA,CAAO,IAAIA,IAAU,IAAI,SAAS,KAAK;AAAA,EAAA,EAAA,CAC5D,EAAA,CAEJ;AAEJ;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { j as n } from "./jsx-runtime-
|
|
1
|
+
import { j as n } from "./jsx-runtime-XvoU0p7t.js";
|
|
2
2
|
import { Box as p } from "@mui/material";
|
|
3
3
|
import "react";
|
|
4
4
|
import { openInNewTab as s } from "./utils/general.es.js";
|
|
@@ -18,4 +18,4 @@ const f = ({ href: i, hrefInNewTab: r = !1, ...e }) => {
|
|
|
18
18
|
export {
|
|
19
19
|
f as I
|
|
20
20
|
};
|
|
21
|
-
//# sourceMappingURL=Image-
|
|
21
|
+
//# sourceMappingURL=Image-KHEjEELP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Image-
|
|
1
|
+
{"version":3,"file":"Image-KHEjEELP.js","sources":["../src/components/Image.tsx"],"sourcesContent":["import { Box, type BoxProps } from \"@mui/material\"\nimport { type FC } from \"react\"\n\nimport { openInNewTab } from \"../utils/general\"\n\nexport interface ImageProps extends Omit<BoxProps, \"component\"> {\n alt: string\n src: string\n href?: string\n hrefInNewTab?: boolean\n}\n\nconst Image: FC<ImageProps> = ({ href, hrefInNewTab = false, ...props }) => {\n let {\n onClick,\n style = {},\n ...otherProps // eslint-disable-line prefer-const\n } = props\n\n if (style.width === undefined) {\n style.width = \"100%\"\n }\n\n // Override onClick if href provided.\n if (href !== undefined) {\n style = { ...style, cursor: \"pointer\" }\n if (hrefInNewTab) {\n onClick = () => {\n openInNewTab(href)\n }\n } else {\n onClick = () => {\n window.location.replace(href)\n }\n }\n }\n\n return <Box component=\"img\" onClick={onClick} style={style} {...otherProps} />\n}\n\nexport default Image\n"],"names":["Image","href","hrefInNewTab","props","onClick","style","otherProps","openInNewTab","Box"],"mappings":";;;;AAYA,MAAMA,IAAwB,CAAC,EAAE,MAAAC,GAAM,cAAAC,IAAe,IAAO,GAAGC,QAAY;AAC1E,MAAI;AAAA,IACF,SAAAC;AAAA,IACA,OAAAC,IAAQ,CAAA;AAAA,IACR,GAAGC;AAAA;AAAA,EAAA,IACDH;AAEJ,SAAIE,EAAM,UAAU,WAClBA,EAAM,QAAQ,SAIZJ,MAAS,WACXI,IAAQ,EAAE,GAAGA,GAAO,QAAQ,UAAA,GACxBH,IACFE,IAAU,MAAM;AACd,IAAAG,EAAaN,CAAI;AAAA,EACnB,IAEAG,IAAU,MAAM;AACd,WAAO,SAAS,QAAQH,CAAI;AAAA,EAC9B,0BAIIO,GAAA,EAAI,WAAU,OAAM,SAAAJ,GAAkB,OAAAC,GAAe,GAAGC,GAAY;AAC9E;"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { j as t } from "./jsx-runtime-
|
|
1
|
+
import { j as t } from "./jsx-runtime-XvoU0p7t.js";
|
|
2
2
|
import { Button as r } from "@mui/material";
|
|
3
3
|
import "react";
|
|
4
|
-
import { Link as m } from "react-router
|
|
4
|
+
import { Link as m } from "react-router";
|
|
5
5
|
import "@mui/icons-material";
|
|
6
6
|
import "./palette-CYwuLBW7.js";
|
|
7
|
-
import "./auth-
|
|
7
|
+
import "./auth-CvJ5Mh6y.js";
|
|
8
8
|
const f = (o) => /* @__PURE__ */ t.jsx(r, { ...o, component: m });
|
|
9
9
|
export {
|
|
10
10
|
f as L
|
|
11
11
|
};
|
|
12
|
-
//# sourceMappingURL=LinkButton-
|
|
12
|
+
//# sourceMappingURL=LinkButton-Do07PnhU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkButton-Do07PnhU.js","sources":["../src/components/router/LinkButton.tsx"],"sourcesContent":["import { Button, type ButtonProps } from \"@mui/material\"\nimport { type JSX } from \"react\"\nimport { Link } from \"react-router\"\n\nimport { type LinkProps } from \"../../utils/router\"\n\nexport type LinkButtonProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Omit<ButtonProps, \"component\"> & LinkProps<Override, State>\n\n// https://mui.com/material-ui/integrations/routing/#button\nconst LinkButton: {\n (props: LinkButtonProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: LinkButtonProps<\"to\", State>,\n ): JSX.Element\n} = (props: LinkButtonProps<\"delta\"> | LinkButtonProps<\"to\">) => {\n return <Button {...{ ...props, component: Link }} />\n}\n\nexport default LinkButton\n"],"names":["LinkButton","props","jsx","Button","Link"],"mappings":";;;;;;;AAYA,MAAMA,IAKF,CAACC,MACIC,gBAAAA,EAAAA,IAACC,KAAa,GAAGF,GAAO,WAAWG,GAAQ;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const r=require("./jsx-runtime-CeSfJrVB.cjs"),t=require("@mui/material");require("react");const n=require("react-router");require("@mui/icons-material");require("./palette-BnIdHKDE.cjs");require("./auth-C_aSIrwD.cjs");const u=e=>r.jsxRuntimeExports.jsx(t.Button,{...e,component:n.Link});exports.LinkButton=u;
|
|
2
|
+
//# sourceMappingURL=LinkButton-cfljqSBx.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkButton-cfljqSBx.cjs","sources":["../src/components/router/LinkButton.tsx"],"sourcesContent":["import { Button, type ButtonProps } from \"@mui/material\"\nimport { type JSX } from \"react\"\nimport { Link } from \"react-router\"\n\nimport { type LinkProps } from \"../../utils/router\"\n\nexport type LinkButtonProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Omit<ButtonProps, \"component\"> & LinkProps<Override, State>\n\n// https://mui.com/material-ui/integrations/routing/#button\nconst LinkButton: {\n (props: LinkButtonProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: LinkButtonProps<\"to\", State>,\n ): JSX.Element\n} = (props: LinkButtonProps<\"delta\"> | LinkButtonProps<\"to\">) => {\n return <Button {...{ ...props, component: Link }} />\n}\n\nexport default LinkButton\n"],"names":["LinkButton","props","jsx","Button","Link"],"mappings":"uOAYA,MAAMA,EAKDC,GACIC,EAAAA,kBAAAA,IAACC,EAAAA,QAAa,GAAGF,EAAO,UAAWG,EAAAA,KAAQ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const n=require("./jsx-runtime-CeSfJrVB.cjs"),e=require("@mui/material"),u=require("react"),i=require("react-router");require("@mui/icons-material");require("./palette-BnIdHKDE.cjs");const c=require("./auth-C_aSIrwD.cjs"),x=t=>n.jsxRuntimeExports.jsx(e.Link,{component:i.Link,...t}),m=t=>n.jsxRuntimeExports.jsx(e.IconButton,{...t,component:i.Link}),L=t=>n.jsxRuntimeExports.jsx(e.ListItem,{...t,component:i.Link}),a=t=>n.jsxRuntimeExports.jsx(e.Tab,{...t,component:i.Link}),k=({delta:t,to:s,...o})=>{const r=c.useNavigate();return u.useEffect(()=>{typeof t=="number"?r(t):r(s,o)},[r,t,s,o]),n.jsxRuntimeExports.jsx(n.jsxRuntimeExports.Fragment,{})};exports.Link=x;exports.LinkIconButton=m;exports.LinkListItem=L;exports.LinkTab=a;exports.Navigate=k;
|
|
2
|
+
//# sourceMappingURL=Navigate-Cu8Ge031.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Navigate-Cu8Ge031.cjs","sources":["../src/components/router/Link.tsx","../src/components/router/LinkIconButton.tsx","../src/components/router/LinkListItem.tsx","../src/components/router/LinkTab.tsx","../src/components/router/Navigate.tsx"],"sourcesContent":["import { Link as MuiLink, type LinkProps as MuiLinkProps } from \"@mui/material\"\nimport { type JSX } from \"react\"\nimport { Link as RouterLink } from \"react-router\"\n\nimport { type LinkProps as RouterLinkProps } from \"../../utils/router\"\n\nexport type LinkProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Omit<MuiLinkProps, \"component\"> & RouterLinkProps<Override, State>\n\n// https://mui.com/material-ui/integrations/routing/#link\nconst Link: {\n (props: LinkProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: LinkProps<\"to\", State>,\n ): JSX.Element\n} = (props: LinkProps<\"delta\"> | LinkProps<\"to\">) => {\n // @ts-expect-error props are assignable\n return <MuiLink component={RouterLink} {...props} />\n}\n\nexport default Link\n","import { IconButton, type IconButtonProps } from \"@mui/material\"\nimport { type JSX } from \"react\"\nimport { Link } from \"react-router\"\n\nimport { type LinkProps } from \"../../utils/router\"\n\nexport type LinkIconButtonProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Omit<IconButtonProps, \"component\"> & LinkProps<Override, State>\n\n// https://mui.com/material-ui/integrations/routing/#button\nconst LinkIconButton: {\n (props: LinkIconButtonProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: LinkIconButtonProps<\"to\", State>,\n ): JSX.Element\n} = (props: LinkIconButtonProps<\"delta\"> | LinkIconButtonProps<\"to\">) => {\n return <IconButton {...{ ...props, component: Link }} />\n}\n\nexport default LinkIconButton\n","import { ListItem, type ListItemProps } from \"@mui/material\"\nimport { type JSX } from \"react\"\nimport { Link } from \"react-router\"\n\nimport { type LinkProps } from \"../../utils/router\"\n\nexport type LinkListItemProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Omit<ListItemProps, \"component\"> & LinkProps<Override, State>\n\n// https://mui.com/material-ui/integrations/routing/#list\nconst LinkListItem: {\n (props: LinkListItemProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: LinkListItemProps<\"to\", State>,\n ): JSX.Element\n} = (props: LinkListItemProps<\"delta\"> | LinkListItemProps<\"to\">) => {\n return <ListItem {...{ ...props, component: Link }} />\n}\n\nexport default LinkListItem\n","import { Tab, type TabProps } from \"@mui/material\"\nimport { type JSX } from \"react\"\nimport { Link } from \"react-router\"\n\nimport { type LinkProps } from \"../../utils/router\"\n\nexport type LinkTabProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Omit<TabProps, \"component\"> & LinkProps<Override, State>\n\n// https://mui.com/material-ui/integrations/routing/#tabs\nconst LinkTab: {\n (props: LinkTabProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: LinkTabProps<\"to\", State>,\n ): JSX.Element\n} = (props: LinkTabProps<\"delta\"> | LinkTabProps<\"to\">) => {\n return <Tab {...{ ...props, component: Link }} />\n}\n\nexport default LinkTab\n","import { type JSX, useEffect } from \"react\"\nimport { type To } from \"react-router\"\n\nimport { type NavigateOptions, useNavigate } from \"../../hooks\"\n\nexport type NavigateProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Override extends \"delta\"\n ? { delta: number; to?: undefined }\n : { delta?: undefined; to: To } & NavigateOptions<State>\n\nconst Navigate: {\n (props: NavigateProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: NavigateProps<\"to\", State>,\n ): JSX.Element\n} = ({\n delta,\n to,\n ...options\n}: NavigateProps<\"delta\"> | NavigateProps<\"to\">) => {\n const navigate = useNavigate()\n\n useEffect(() => {\n if (typeof delta === \"number\") navigate(delta)\n else navigate(to, options)\n }, [navigate, delta, to, options])\n\n return <></>\n}\n\nexport default Navigate\n"],"names":["Link","props","jsx","MuiLink","RouterLink","LinkIconButton","IconButton","LinkListItem","ListItem","LinkTab","Tab","Navigate","delta","to","options","navigate","useNavigate","useEffect","Fragment"],"mappings":"2OAYMA,EAKDC,GAEIC,EAAAA,kBAAAA,IAACC,EAAAA,KAAA,CAAQ,UAAWC,EAAAA,KAAa,GAAGH,EAAO,ECP9CI,EAKDJ,GACIC,EAAAA,kBAAAA,IAACI,EAAAA,YAAiB,GAAGL,EAAO,UAAWD,EAAAA,KAAQ,ECNlDO,EAKDN,GACIC,EAAAA,kBAAAA,IAACM,EAAAA,UAAe,GAAGP,EAAO,UAAWD,EAAAA,KAAQ,ECNhDS,EAKDR,GACIC,EAAAA,kBAAAA,IAACQ,EAAAA,KAAU,GAAGT,EAAO,UAAWD,EAAAA,KAAQ,ECN3CW,EAKF,CAAC,CACH,MAAAC,EACA,GAAAC,EACA,GAAGC,CACL,IAAoD,CAClD,MAAMC,EAAWC,EAAAA,YAAA,EAEjBC,OAAAA,EAAAA,UAAU,IAAM,CACV,OAAOL,GAAU,SAAUG,EAASH,CAAK,EACxCG,EAASF,EAAIC,CAAO,CAC3B,EAAG,CAACC,EAAUH,EAAOC,EAAIC,CAAO,CAAC,EAE1BZ,EAAAA,kBAAAA,IAAAgB,EAAAA,kBAAAA,SAAA,EAAE,CACX"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { j as n } from "./jsx-runtime-
|
|
1
|
+
import { j as n } from "./jsx-runtime-XvoU0p7t.js";
|
|
2
2
|
import { Link as i, IconButton as m, ListItem as a, Tab as c } from "@mui/material";
|
|
3
3
|
import { useEffect as p } from "react";
|
|
4
|
-
import { Link as o } from "react-router
|
|
4
|
+
import { Link as o } from "react-router";
|
|
5
5
|
import "@mui/icons-material";
|
|
6
6
|
import "./palette-CYwuLBW7.js";
|
|
7
|
-
import { e as u } from "./auth-
|
|
7
|
+
import { e as u } from "./auth-CvJ5Mh6y.js";
|
|
8
8
|
const I = (t) => /* @__PURE__ */ n.jsx(i, { component: o, ...t }), v = (t) => /* @__PURE__ */ n.jsx(m, { ...t, component: o }), N = (t) => /* @__PURE__ */ n.jsx(a, { ...t, component: o }), B = (t) => /* @__PURE__ */ n.jsx(c, { ...t, component: o }), E = ({
|
|
9
9
|
delta: t,
|
|
10
10
|
to: s,
|
|
@@ -22,4 +22,4 @@ export {
|
|
|
22
22
|
N as b,
|
|
23
23
|
B as c
|
|
24
24
|
};
|
|
25
|
-
//# sourceMappingURL=Navigate-
|
|
25
|
+
//# sourceMappingURL=Navigate-DC6ag0th.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Navigate-DC6ag0th.js","sources":["../src/components/router/Link.tsx","../src/components/router/LinkIconButton.tsx","../src/components/router/LinkListItem.tsx","../src/components/router/LinkTab.tsx","../src/components/router/Navigate.tsx"],"sourcesContent":["import { Link as MuiLink, type LinkProps as MuiLinkProps } from \"@mui/material\"\nimport { type JSX } from \"react\"\nimport { Link as RouterLink } from \"react-router\"\n\nimport { type LinkProps as RouterLinkProps } from \"../../utils/router\"\n\nexport type LinkProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Omit<MuiLinkProps, \"component\"> & RouterLinkProps<Override, State>\n\n// https://mui.com/material-ui/integrations/routing/#link\nconst Link: {\n (props: LinkProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: LinkProps<\"to\", State>,\n ): JSX.Element\n} = (props: LinkProps<\"delta\"> | LinkProps<\"to\">) => {\n // @ts-expect-error props are assignable\n return <MuiLink component={RouterLink} {...props} />\n}\n\nexport default Link\n","import { IconButton, type IconButtonProps } from \"@mui/material\"\nimport { type JSX } from \"react\"\nimport { Link } from \"react-router\"\n\nimport { type LinkProps } from \"../../utils/router\"\n\nexport type LinkIconButtonProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Omit<IconButtonProps, \"component\"> & LinkProps<Override, State>\n\n// https://mui.com/material-ui/integrations/routing/#button\nconst LinkIconButton: {\n (props: LinkIconButtonProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: LinkIconButtonProps<\"to\", State>,\n ): JSX.Element\n} = (props: LinkIconButtonProps<\"delta\"> | LinkIconButtonProps<\"to\">) => {\n return <IconButton {...{ ...props, component: Link }} />\n}\n\nexport default LinkIconButton\n","import { ListItem, type ListItemProps } from \"@mui/material\"\nimport { type JSX } from \"react\"\nimport { Link } from \"react-router\"\n\nimport { type LinkProps } from \"../../utils/router\"\n\nexport type LinkListItemProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Omit<ListItemProps, \"component\"> & LinkProps<Override, State>\n\n// https://mui.com/material-ui/integrations/routing/#list\nconst LinkListItem: {\n (props: LinkListItemProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: LinkListItemProps<\"to\", State>,\n ): JSX.Element\n} = (props: LinkListItemProps<\"delta\"> | LinkListItemProps<\"to\">) => {\n return <ListItem {...{ ...props, component: Link }} />\n}\n\nexport default LinkListItem\n","import { Tab, type TabProps } from \"@mui/material\"\nimport { type JSX } from \"react\"\nimport { Link } from \"react-router\"\n\nimport { type LinkProps } from \"../../utils/router\"\n\nexport type LinkTabProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Omit<TabProps, \"component\"> & LinkProps<Override, State>\n\n// https://mui.com/material-ui/integrations/routing/#tabs\nconst LinkTab: {\n (props: LinkTabProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: LinkTabProps<\"to\", State>,\n ): JSX.Element\n} = (props: LinkTabProps<\"delta\"> | LinkTabProps<\"to\">) => {\n return <Tab {...{ ...props, component: Link }} />\n}\n\nexport default LinkTab\n","import { type JSX, useEffect } from \"react\"\nimport { type To } from \"react-router\"\n\nimport { type NavigateOptions, useNavigate } from \"../../hooks\"\n\nexport type NavigateProps<\n Override extends \"delta\" | \"to\",\n State extends Record<string, any> = Record<string, any>,\n> = Override extends \"delta\"\n ? { delta: number; to?: undefined }\n : { delta?: undefined; to: To } & NavigateOptions<State>\n\nconst Navigate: {\n (props: NavigateProps<\"delta\">): JSX.Element\n <State extends Record<string, any> = Record<string, any>>(\n props: NavigateProps<\"to\", State>,\n ): JSX.Element\n} = ({\n delta,\n to,\n ...options\n}: NavigateProps<\"delta\"> | NavigateProps<\"to\">) => {\n const navigate = useNavigate()\n\n useEffect(() => {\n if (typeof delta === \"number\") navigate(delta)\n else navigate(to, options)\n }, [navigate, delta, to, options])\n\n return <></>\n}\n\nexport default Navigate\n"],"names":["Link","props","jsx","MuiLink","RouterLink","LinkIconButton","IconButton","LinkListItem","ListItem","LinkTab","Tab","Navigate","delta","to","options","navigate","useNavigate","useEffect","Fragment"],"mappings":";;;;;;;AAYA,MAAMA,IAKF,CAACC,MAEIC,gBAAAA,EAAAA,IAACC,GAAA,EAAQ,WAAWC,GAAa,GAAGH,GAAO,GCP9CI,IAKF,CAACJ,MACIC,gBAAAA,EAAAA,IAACI,KAAiB,GAAGL,GAAO,WAAWD,GAAQ,GCNlDO,IAKF,CAACN,MACIC,gBAAAA,EAAAA,IAACM,KAAe,GAAGP,GAAO,WAAWD,GAAQ,GCNhDS,IAKF,CAACR,MACIC,gBAAAA,EAAAA,IAACQ,KAAU,GAAGT,GAAO,WAAWD,GAAQ,GCN3CW,IAKF,CAAC;AAAA,EACH,OAAAC;AAAA,EACA,IAAAC;AAAA,EACA,GAAGC;AACL,MAAoD;AAClD,QAAMC,IAAWC,EAAA;AAEjB,SAAAC,EAAU,MAAM;AACd,IAAI,OAAOL,KAAU,WAAUG,EAASH,CAAK,IACxCG,EAASF,GAAIC,CAAO;AAAA,EAC3B,GAAG,CAACC,GAAUH,GAAOC,GAAIC,CAAO,CAAC,GAE1BZ,gBAAAA,EAAAA,IAAAgB,EAAAA,UAAA,EAAE;AACX;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t, b as s } from "../../api-
|
|
2
|
-
import { u as o } from "../../urls-
|
|
1
|
+
import { t, b as s } from "../../api-CYqNqtN9.js";
|
|
2
|
+
import { u as o } from "../../urls-BY-za1bX.js";
|
|
3
3
|
import { a as q, b as y } from "../../session-D312kYKk.js";
|
|
4
4
|
const a = "AuthFactor";
|
|
5
5
|
function c(r) {
|
package/dist/api/index.es.js
CHANGED
|
@@ -5,9 +5,9 @@ import { useCallback as N, useDebugValue as x, useMemo as k, useState as re, use
|
|
|
5
5
|
import { SERVICE_API_URL as ve } from "../settings/index.es.js";
|
|
6
6
|
import { b as Ee } from "../session-D312kYKk.js";
|
|
7
7
|
import { getCsrfCookie as J } from "../utils/auth.es.js";
|
|
8
|
-
import { i as Qe } from "../api-
|
|
9
|
-
import { s as Be } from "../schemas-
|
|
10
|
-
import { u as Ze } from "../urls-
|
|
8
|
+
import { i as Qe } from "../api-CYqNqtN9.js";
|
|
9
|
+
import { s as Be } from "../schemas-CDXuSjyI.js";
|
|
10
|
+
import { u as Ze } from "../urls-BY-za1bX.js";
|
|
11
11
|
function F(e) {
|
|
12
12
|
return e.replace(e[0], e[0].toUpperCase());
|
|
13
13
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { j as u } from "./jsx-runtime-
|
|
1
|
+
import { j as u } from "./jsx-runtime-XvoU0p7t.js";
|
|
2
2
|
import { Stack as h, Typography as m, CircularProgress as p } from "@mui/material";
|
|
3
3
|
import "react";
|
|
4
4
|
import { getNestedProperty as g } from "./utils/general.es.js";
|
|
@@ -89,4 +89,4 @@ export {
|
|
|
89
89
|
C as m,
|
|
90
90
|
L as t
|
|
91
91
|
};
|
|
92
|
-
//# sourceMappingURL=api-
|
|
92
|
+
//# sourceMappingURL=api-CYqNqtN9.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-Cbyt3rw0.js","sources":["../src/components/SyncError.tsx","../src/utils/api.tsx"],"sourcesContent":["import { Stack, Typography } from \"@mui/material\"\nimport { type FC } from \"react\"\nimport { SyncProblem as SyncProblemIcon } from \"@mui/icons-material\"\n\nexport interface SyncErrorProps {}\n\nconst SyncError: FC<SyncErrorProps> = () => (\n <Stack alignItems=\"center\" alignContent=\"center\">\n <SyncProblemIcon color=\"error\" />\n <Typography color=\"error.main\">Failed to sync data</Typography>\n </Stack>\n)\n\nexport default SyncError\n","import type {\n FetchBaseQueryError,\n TypedUseMutationResult,\n TypedUseQueryHookResult,\n TypedUseQueryStateResult,\n} from \"@reduxjs/toolkit/query/react\"\nimport { CircularProgress } from \"@mui/material\"\nimport { type ReactNode } from \"react\"\n\nimport { type Optional, type Required, getNestedProperty } from \"./general\"\nimport { type SchemaMap } from \"./schema\"\nimport SyncError from \"../components/SyncError\"\n\n// -----------------------------------------------------------------------------\n// Model Types\n// -----------------------------------------------------------------------------\n\n// The fields of a model.\nexport type Fields = Record<string, unknown>\n\nexport interface Tag<Type extends string> {\n type: Type\n id: string\n}\n\nexport type ModelId = string | number\n\n/**\n * A data model.\n * Id: The type of Id.\n * Data: The data fields.\n */\nexport type Model<Id extends ModelId, MFields extends Fields = Fields> = {\n id: Id\n} & Omit<MFields, \"id\">\n\nexport type Schemas<M extends Model<any>> = {\n [K in keyof M]-?: SchemaMap<M[K]>\n}\n\nexport type Result<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n> = Pick<M, \"id\" | MFields>\n\nexport type Arg<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\">,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields> = never,\n> = Required<M, RequiredFields> & Optional<M, OptionalFields>\n\n// -----------------------------------------------------------------------------\n// CRUD Types\n// https://www.django-rest-framework.org/api-guide/viewsets/#viewset-actions\n// -----------------------------------------------------------------------------\n\n// Create\n\nexport type CreateResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n> = Result<M, MFields>\n\nexport type CreateArg<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\">,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields> = never,\n> = Arg<M, RequiredFields, OptionalFields>\n\nexport type BulkCreateResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n ExtraFields extends Fields = Fields,\n> = Array<Result<M, MFields> & ExtraFields>\n\nexport type BulkCreateArg<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\">,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields> = never,\n ExtraFields extends Fields = Fields,\n> = Array<Arg<M, RequiredFields, OptionalFields> & ExtraFields>\n\n// Read\n\nexport type RetrieveResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n> = Result<M, MFields>\n\nexport type RetrieveArg<M extends Model<any>> = M[\"id\"]\n\nexport interface ListResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n ExtraFields extends Fields = Fields,\n> {\n count: number\n offset: number\n limit: number\n max_limit: number\n data: Array<Result<M, MFields> & ExtraFields>\n}\n\nexport type ListArg<Filters extends Fields = Fields> = {\n limit: number\n offset: number\n} & Partial<Omit<Filters, \"limit\" | \"offset\">>\n\n// Update\n\nexport type UpdateResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n> = Result<M, MFields>\n\ntype UpdateWithBody<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\">,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields>,\n> = Pick<M, \"id\"> & Arg<M, RequiredFields, OptionalFields>\n\n// NOTE: Sometimes update does not require a body. For example, if calling the\n// \"refresh\" action on an invitation object updates the expiry date to be 24\n// hours from now. In this case, you only need to pass the ID of the object.\nexport type UpdateArg<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\"> = never,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields> = never,\n> = [RequiredFields] extends [never]\n ? [OptionalFields] extends [never]\n ? M[\"id\"]\n : UpdateWithBody<M, RequiredFields, OptionalFields>\n : UpdateWithBody<M, RequiredFields, OptionalFields>\n\nexport type BulkUpdateResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n ExtraFields extends Fields = Fields,\n> = Array<Result<M, MFields> & ExtraFields>\n\nexport type BulkUpdateArg<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\">,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields> = never,\n ExtraFields extends Fields = Fields,\n> = Record<M[\"id\"], Arg<M, RequiredFields, OptionalFields> & ExtraFields>\n\n// Delete\n\nexport type DestroyResult = null\n\nexport type DestroyArg<M extends Model<any>> = M[\"id\"]\n\nexport type BulkDestroyResult = null\n\nexport type BulkDestroyArg<M extends Model<any>> = Array<M[\"id\"]>\n\n// -----------------------------------------------------------------------------\n// Functions\n// -----------------------------------------------------------------------------\n\nexport function buildUrl(\n url: string,\n params: {\n search?: Fields\n url?: Fields\n },\n): string {\n if (params.url) {\n Object.entries(params.url).forEach(([key, value]) => {\n url = url.replace(`<${key}>`, String(value))\n })\n }\n\n if (params.search) {\n const searchParams: string[][] = []\n for (const key in params.search) {\n const values = params.search[key]\n if (values === undefined) continue\n\n if (Array.isArray(values)) {\n for (const value of values) searchParams.push([key, String(value)])\n } else {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n searchParams.push([key, String(values)])\n }\n }\n\n if (searchParams.length !== 0) {\n url += `?${new URLSearchParams(searchParams).toString()}`\n }\n }\n\n return url\n}\n\nexport function isModelId(value: unknown): boolean {\n return typeof value === \"number\" || typeof value === \"string\"\n}\n\nexport function listTag<Type extends string>(type: Type): Tag<Type> {\n return { type, id: \"LIST\" }\n}\n\nexport type TagDataOptions = Partial<{\n includeListTag: boolean\n argKeysAreIds: boolean\n id: string\n}>\n\nexport function tagData<Type extends string, M extends Model<any>>(\n type: Type,\n options?: TagDataOptions,\n): (\n result:\n | Result<M, any>\n | Array<Result<M, any>>\n | ListResult<M, any>\n | null\n | undefined,\n error: FetchBaseQueryError | undefined,\n arg:\n | Arg<M, any>\n | Array<Arg<M, any>>\n | Record<M[\"id\"], Arg<M, any>>\n | ListArg<any>\n | Array<M[\"id\"]>\n | string\n | number\n | undefined,\n) => Array<Tag<Type>> {\n const {\n includeListTag = false,\n argKeysAreIds = false,\n id = \"id\",\n } = options || {}\n\n function tags(\n ids: ModelId[],\n list: boolean = includeListTag,\n ): Array<Tag<Type>> {\n const tags = ids.map(id => ({ type, id: String(id) }))\n if (list) tags.push(listTag(type))\n return tags\n }\n\n function getModelId(result: Result<M, any>) {\n return getNestedProperty(result, id) as ModelId\n }\n\n return (result, error, arg) => {\n if (!error) {\n if (arg) {\n // The argument is an ID.\n if (isModelId(arg)) return tags([arg as ModelId])\n\n // The argument is an array of IDs.\n if (Array.isArray(arg)) {\n if (arg.length && isModelId(arg[0])) {\n return tags(arg as Array<M[\"id\"]>)\n }\n }\n // The argument is an object that contains the id field.\n else if (typeof arg === \"object\" && argKeysAreIds) {\n return tags(Object.keys(arg as Record<M[\"id\"], any>))\n }\n }\n\n if (result) {\n // The result is an array of models that contain the id field.\n if (Array.isArray(result)) {\n return tags(result.map(getModelId))\n }\n\n // The result is a model that contains the id field.\n if (getModelId(result as Result<M, any>) !== undefined) {\n return tags([getModelId(result as Result<M, any>)])\n }\n\n // The result is a list that contains an array of models that contain\n // the id field.\n return tags((result as ListResult<M, any>).data.map(getModelId), true)\n }\n }\n\n return tags([])\n }\n}\n\nexport function modelUrls(list: string, detail: string) {\n if (list === detail) throw Error(\"List and detail are the same.\")\n\n return { list, detail }\n}\n\nexport type HandleQueryStateOptions = Partial<{\n loading: ReactNode\n error: ReactNode\n}>\n\nexport function handleResultState<QueryArg, ResultType>(\n result:\n | TypedUseQueryHookResult<ResultType, QueryArg, any>\n | TypedUseQueryStateResult<ResultType, QueryArg, any>\n | TypedUseMutationResult<ResultType, QueryArg, any>,\n children: (data: NonNullable<ResultType>) => ReactNode,\n options?: HandleQueryStateOptions,\n): ReactNode {\n const { data, isLoading, isSuccess } = result\n const error = result.error as string | undefined\n\n const {\n loading: loadingNode = <CircularProgress />,\n error: errorNode = <SyncError />,\n } = options || {}\n\n // An error occurred.\n if (error) {\n console.error(error)\n return errorNode\n }\n\n // Busy calling the API.\n if (isLoading) return loadingNode\n\n // Called the API and got data.\n if (data) return children(data)\n\n // Called the API and did not get data.\n if (isSuccess) throw Error(\"Expected to get data from API but got nothing.\")\n\n // Have yet to call the API.\n return loadingNode\n}\n\nexport function isSafeHttpMethod(method: string) {\n // https://datatracker.ietf.org/doc/html/rfc9110.html#section-9.2.1\n return [\"GET\", \"HEAD\", \"OPTIONS\", \"TRACE\"].includes(method.toUpperCase())\n}\n"],"names":["SyncError","jsxs","Stack","jsx","SyncProblemIcon","Typography","buildUrl","url","params","key","value","searchParams","values","isModelId","listTag","type","tagData","options","includeListTag","argKeysAreIds","id","tags","ids","list","getModelId","result","getNestedProperty","error","arg","modelUrls","detail","handleResultState","children","data","isLoading","isSuccess","loadingNode","CircularProgress","errorNode","isSafeHttpMethod","method"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api-CYqNqtN9.js","sources":["../src/components/SyncError.tsx","../src/utils/api.tsx"],"sourcesContent":["import { Stack, Typography } from \"@mui/material\"\nimport { type FC } from \"react\"\nimport { SyncProblem as SyncProblemIcon } from \"@mui/icons-material\"\n\nexport interface SyncErrorProps {}\n\nconst SyncError: FC<SyncErrorProps> = () => (\n <Stack alignItems=\"center\" alignContent=\"center\">\n <SyncProblemIcon color=\"error\" />\n <Typography color=\"error.main\">Failed to sync data</Typography>\n </Stack>\n)\n\nexport default SyncError\n","import type {\n FetchBaseQueryError,\n TypedUseMutationResult,\n TypedUseQueryHookResult,\n TypedUseQueryStateResult,\n} from \"@reduxjs/toolkit/query/react\"\nimport { CircularProgress } from \"@mui/material\"\nimport { type ReactNode } from \"react\"\n\nimport { type Optional, type Required, getNestedProperty } from \"./general\"\nimport { type SchemaMap } from \"./schema\"\nimport SyncError from \"../components/SyncError\"\n\n// -----------------------------------------------------------------------------\n// Model Types\n// -----------------------------------------------------------------------------\n\n// The fields of a model.\nexport type Fields = Record<string, unknown>\n\nexport interface Tag<Type extends string> {\n type: Type\n id: string\n}\n\nexport type ModelId = string | number\n\n/**\n * A data model.\n * Id: The type of Id.\n * Data: The data fields.\n */\nexport type Model<Id extends ModelId, MFields extends Fields = Fields> = {\n id: Id\n} & Omit<MFields, \"id\">\n\nexport type Schemas<M extends Model<any>> = {\n [K in keyof M]-?: SchemaMap<M[K]>\n}\n\nexport type Result<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n> = Pick<M, \"id\" | MFields>\n\nexport type Arg<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\">,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields> = never,\n> = Required<M, RequiredFields> & Optional<M, OptionalFields>\n\n// -----------------------------------------------------------------------------\n// CRUD Types\n// https://www.django-rest-framework.org/api-guide/viewsets/#viewset-actions\n// -----------------------------------------------------------------------------\n\n// Create\n\nexport type CreateResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n> = Result<M, MFields>\n\nexport type CreateArg<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\">,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields> = never,\n> = Arg<M, RequiredFields, OptionalFields>\n\nexport type BulkCreateResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n ExtraFields extends Fields = Fields,\n> = Array<Result<M, MFields> & ExtraFields>\n\nexport type BulkCreateArg<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\">,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields> = never,\n ExtraFields extends Fields = Fields,\n> = Array<Arg<M, RequiredFields, OptionalFields> & ExtraFields>\n\n// Read\n\nexport type RetrieveResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n> = Result<M, MFields>\n\nexport type RetrieveArg<M extends Model<any>> = M[\"id\"]\n\nexport interface ListResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n ExtraFields extends Fields = Fields,\n> {\n count: number\n offset: number\n limit: number\n max_limit: number\n data: Array<Result<M, MFields> & ExtraFields>\n}\n\nexport type ListArg<Filters extends Fields = Fields> = {\n limit: number\n offset: number\n} & Partial<Omit<Filters, \"limit\" | \"offset\">>\n\n// Update\n\nexport type UpdateResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n> = Result<M, MFields>\n\ntype UpdateWithBody<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\">,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields>,\n> = Pick<M, \"id\"> & Arg<M, RequiredFields, OptionalFields>\n\n// NOTE: Sometimes update does not require a body. For example, if calling the\n// \"refresh\" action on an invitation object updates the expiry date to be 24\n// hours from now. In this case, you only need to pass the ID of the object.\nexport type UpdateArg<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\"> = never,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields> = never,\n> = [RequiredFields] extends [never]\n ? [OptionalFields] extends [never]\n ? M[\"id\"]\n : UpdateWithBody<M, RequiredFields, OptionalFields>\n : UpdateWithBody<M, RequiredFields, OptionalFields>\n\nexport type BulkUpdateResult<\n M extends Model<any>,\n MFields extends keyof Omit<M, \"id\"> = never,\n ExtraFields extends Fields = Fields,\n> = Array<Result<M, MFields> & ExtraFields>\n\nexport type BulkUpdateArg<\n M extends Model<any>,\n RequiredFields extends keyof Omit<M, \"id\">,\n OptionalFields extends keyof Omit<M, \"id\" | RequiredFields> = never,\n ExtraFields extends Fields = Fields,\n> = Record<M[\"id\"], Arg<M, RequiredFields, OptionalFields> & ExtraFields>\n\n// Delete\n\nexport type DestroyResult = null\n\nexport type DestroyArg<M extends Model<any>> = M[\"id\"]\n\nexport type BulkDestroyResult = null\n\nexport type BulkDestroyArg<M extends Model<any>> = Array<M[\"id\"]>\n\n// -----------------------------------------------------------------------------\n// Functions\n// -----------------------------------------------------------------------------\n\nexport function buildUrl(\n url: string,\n params: {\n search?: Fields\n url?: Fields\n },\n): string {\n if (params.url) {\n Object.entries(params.url).forEach(([key, value]) => {\n url = url.replace(`<${key}>`, String(value))\n })\n }\n\n if (params.search) {\n const searchParams: string[][] = []\n for (const key in params.search) {\n const values = params.search[key]\n if (values === undefined) continue\n\n if (Array.isArray(values)) {\n for (const value of values) searchParams.push([key, String(value)])\n } else {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n searchParams.push([key, String(values)])\n }\n }\n\n if (searchParams.length !== 0) {\n url += `?${new URLSearchParams(searchParams).toString()}`\n }\n }\n\n return url\n}\n\nexport function isModelId(value: unknown): boolean {\n return typeof value === \"number\" || typeof value === \"string\"\n}\n\nexport function listTag<Type extends string>(type: Type): Tag<Type> {\n return { type, id: \"LIST\" }\n}\n\nexport type TagDataOptions = Partial<{\n includeListTag: boolean\n argKeysAreIds: boolean\n id: string\n}>\n\nexport function tagData<Type extends string, M extends Model<any>>(\n type: Type,\n options?: TagDataOptions,\n): (\n result:\n | Result<M, any>\n | Array<Result<M, any>>\n | ListResult<M, any>\n | null\n | undefined,\n error: FetchBaseQueryError | undefined,\n arg:\n | Arg<M, any>\n | Array<Arg<M, any>>\n | Record<M[\"id\"], Arg<M, any>>\n | ListArg<any>\n | Array<M[\"id\"]>\n | string\n | number\n | undefined,\n) => Array<Tag<Type>> {\n const {\n includeListTag = false,\n argKeysAreIds = false,\n id = \"id\",\n } = options || {}\n\n function tags(\n ids: ModelId[],\n list: boolean = includeListTag,\n ): Array<Tag<Type>> {\n const tags = ids.map(id => ({ type, id: String(id) }))\n if (list) tags.push(listTag(type))\n return tags\n }\n\n function getModelId(result: Result<M, any>) {\n return getNestedProperty(result, id) as ModelId\n }\n\n return (result, error, arg) => {\n if (!error) {\n if (arg) {\n // The argument is an ID.\n if (isModelId(arg)) return tags([arg as ModelId])\n\n // The argument is an array of IDs.\n if (Array.isArray(arg)) {\n if (arg.length && isModelId(arg[0])) {\n return tags(arg as Array<M[\"id\"]>)\n }\n }\n // The argument is an object that contains the id field.\n else if (typeof arg === \"object\" && argKeysAreIds) {\n return tags(Object.keys(arg as Record<M[\"id\"], any>))\n }\n }\n\n if (result) {\n // The result is an array of models that contain the id field.\n if (Array.isArray(result)) {\n return tags(result.map(getModelId))\n }\n\n // The result is a model that contains the id field.\n if (getModelId(result as Result<M, any>) !== undefined) {\n return tags([getModelId(result as Result<M, any>)])\n }\n\n // The result is a list that contains an array of models that contain\n // the id field.\n return tags((result as ListResult<M, any>).data.map(getModelId), true)\n }\n }\n\n return tags([])\n }\n}\n\nexport function modelUrls(list: string, detail: string) {\n if (list === detail) throw Error(\"List and detail are the same.\")\n\n return { list, detail }\n}\n\nexport type HandleQueryStateOptions = Partial<{\n loading: ReactNode\n error: ReactNode\n}>\n\nexport function handleResultState<QueryArg, ResultType>(\n result:\n | TypedUseQueryHookResult<ResultType, QueryArg, any>\n | TypedUseQueryStateResult<ResultType, QueryArg, any>\n | TypedUseMutationResult<ResultType, QueryArg, any>,\n children: (data: NonNullable<ResultType>) => ReactNode,\n options?: HandleQueryStateOptions,\n): ReactNode {\n const { data, isLoading, isSuccess } = result\n const error = result.error as string | undefined\n\n const {\n loading: loadingNode = <CircularProgress />,\n error: errorNode = <SyncError />,\n } = options || {}\n\n // An error occurred.\n if (error) {\n console.error(error)\n return errorNode\n }\n\n // Busy calling the API.\n if (isLoading) return loadingNode\n\n // Called the API and got data.\n if (data) return children(data)\n\n // Called the API and did not get data.\n if (isSuccess) throw Error(\"Expected to get data from API but got nothing.\")\n\n // Have yet to call the API.\n return loadingNode\n}\n\nexport function isSafeHttpMethod(method: string) {\n // https://datatracker.ietf.org/doc/html/rfc9110.html#section-9.2.1\n return [\"GET\", \"HEAD\", \"OPTIONS\", \"TRACE\"].includes(method.toUpperCase())\n}\n"],"names":["SyncError","jsxs","Stack","jsx","SyncProblemIcon","Typography","buildUrl","url","params","key","value","searchParams","values","isModelId","listTag","type","tagData","options","includeListTag","argKeysAreIds","id","tags","ids","list","getModelId","result","getNestedProperty","error","arg","modelUrls","detail","handleResultState","children","data","isLoading","isSuccess","loadingNode","CircularProgress","errorNode","isSafeHttpMethod","method"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const y=require("./jsx-runtime-CeSfJrVB.cjs"),C=require("yup"),l=require("react"),w=require("js-cookie"),S=require("react-router"),z=require("react-redux"),V=require("./settings/index.cjs.js"),B=require("./session-CE2U7oL1.cjs"),E=require("./utils/auth.cjs.js");require("@mui/material");const G=require("./utils/general.cjs.js");require("@mui/icons-material");require("./schemas-BZbJpkD5.cjs");require("./urls-MaVXL_C2.cjs");const k=require("./utils/schema.cjs.js");require("./palette-BnIdHKDE.cjs");function H(e){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const t in e)if(t!=="default"){const s=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,s.get?s:{enumerable:!0,get:()=>e[t]})}}return n.default=e,Object.freeze(n)}const T=H(C);function v(){const e=S.useNavigate(),n=x();return(t,s=void 0)=>{if(typeof t=="number")e(t);else{const{next:o=!0,...i}=s||{};e(o&&"next"in n?n.next:t,i)}}}function q(){return S.useLocation()}function x(e,n){const t=Object.fromEntries(S.useSearchParams()[0].entries());return e?k.tryValidateSync(t,C.object(e),n):t}function J(e,n){const t=S.useParams();return e?k.tryValidateSync(t,C.object(e),n):t}function Q({shape:e,children:n,onValidationError:t,onValidationSuccess:s=()=>{},validateOptions:o}){const i=J(e,o),a=v();return l.useEffect(()=>{i?s(i):t(a)},[]),i?n(i):y.jsxRuntimeExports.jsx(y.jsxRuntimeExports.Fragment,{})}function m(e=V.SESSION_METADATA_COOKIE_NAME){return z.useSelector(B.selectIsLoggedIn)?JSON.parse(w.get(e)):void 0}m.predefine=(e=V.SESSION_METADATA_COOKIE_NAME)=>()=>m(e);function W(e,n={}){const{userType:t,next:s=!0}=n,{pathname:o}=q(),i=v(),a=m(),c=t&&(!a||a.user_type!==t);return l.useEffect(()=>{c&&i({pathname:"/login"+{teacher:"/teacher",student:"/student",indy:"/independent"}[t],search:s?S.createSearchParams({next:o}).toString():void 0})},[i,c,t,s,o]),c?y.jsxRuntimeExports.jsx(y.jsxRuntimeExports.Fragment,{}):typeof e=="function"?e(a):e}function F(e,n=32,t="state"){const s=E.makeOAuth2StorageKey(e,t),o=sessionStorage.getItem(s),[i,a]=l.useState();l.useEffect(()=>{let u;o&&o.length===n?u=o:(u=G.generateSecureRandomString(n),sessionStorage.setItem(s,u)),a(u)},[s,o,n]);const c=l.useCallback(()=>{sessionStorage.removeItem(s),a(void 0)},[s]);return[i,c]}function D(e,n=128,t="codeChallenge"){const s=E.makeOAuth2StorageKey(e,t),o=sessionStorage.getItem(s),[i,a]=l.useState();l.useEffect(()=>{let u;if(o){const r=JSON.parse(o);typeof r=="object"&&r&&"verifier"in r&&typeof r.verifier=="string"&&r.verifier.length===n&&"challenge"in r&&typeof r.challenge=="string"&&"method"in r&&r.method==="S256"&&(u={verifier:r.verifier,challenge:r.challenge,method:r.method})}u?a(u):E.generateOAuth2CodeChallenge(n).then(r=>{sessionStorage.setItem(s,JSON.stringify(r)),a(r)}).catch(r=>{r&&console.error(r)})},[s,o,n]);const c=l.useCallback(()=>{sessionStorage.removeItem(s),a(void 0)},[s]);return[i,c]}function X({provider:e,authUri:n,clientId:t,redirectUri:s,scope:o,responseType:i="code",accessType:a="offline",prompt:c,useSessionMetadata:u,useLoginMutation:r,onCreateSession:P,onRetrieveSession:j}){const[h,I]=F(e),[{verifier:p,challenge:b,method:M}={},R]=D(e),[N,{originalArgs:f={},isLoading:L,isError:K}]=r(),O=u(),_=v(),d=x({code:T.string(),state:T.string()})||{},g=q().state||{};if(l.useEffect(()=>{d.code&&d.state&&_(".",{replace:!0,next:!1,state:{code:d.code,state:d.state}})},[d.code,d.state,_]),l.useEffect(()=>{O?j(O):h&&p&&g.code&&g.state===h&&(f.code!==g.code||f.code_verifier!==p||f.redirect_uri!==s||!K)&&!L&&N({code:g.code,code_verifier:p,redirect_uri:s}).unwrap().then(P).catch(()=>{_(".",{replace:!0,state:{notifications:[{props:{error:!0,children:"Failed to login. Please try again."}}]}})}).finally(()=>{I(),R()})},[_,s,h,g.state,I,p,g.code,R,N,L,K,f.code,f.code_verifier,f.redirect_uri,O,P,j]),h&&b&&M){const A={client_id:t,redirect_uri:s,scope:o,response_type:i,access_type:a,state:h,code_challenge:b,code_challenge_method:M};return c&&(A.prompt=c),[n+"?"+new URLSearchParams(A).toString(),A]}return[]}const Y=e=>X("useSessionMetadata"in e?e:{...e,useSessionMetadata:m});exports.useLocation=q;exports.useNavigate=v;exports.useOAuth2=Y;exports.useOAuth2CodeChallenge=D;exports.useOAuth2State=F;exports.useParams=J;exports.useParamsRequired=Q;exports.useSearchParams=x;exports.useSession=W;exports.useSessionMetadata=m;
|
|
2
|
+
//# sourceMappingURL=auth-C_aSIrwD.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-C_aSIrwD.cjs","sources":["../src/hooks/router.tsx","../src/hooks/auth.tsx"],"sourcesContent":["import {\n type Location,\n type Params,\n type To,\n type NavigateOptions as _NavigateOptions,\n useLocation as _useLocation,\n useNavigate as _useNavigate,\n useParams as _useParams,\n useSearchParams as _useSearchParams,\n} from \"react-router\"\nimport { type ObjectShape, object as objectSchema } from \"yup\"\nimport { type ReactNode, useEffect } from \"react\"\n\nimport {\n type ObjectSchemaFromShape,\n type TryValidateSyncOnErrorRT,\n type TryValidateSyncOptions,\n type TryValidateSyncRT,\n tryValidateSync,\n} from \"../utils/schema\"\nimport { type PageState } from \"../components/page\"\nimport { type ReadOnly } from \"../utils/router\"\n\nexport type NavigateOptions<\n State extends Record<string, any> = Record<string, any>,\n> = Omit<_NavigateOptions, \"state\"> & {\n state?: State & Partial<PageState>\n next?: boolean\n}\n\nexport type Navigate = {\n <State extends Record<string, any> = Record<string, any>>(\n to: To,\n options?: NavigateOptions<State>,\n ): void\n (delta: number): void\n}\n\nexport function useNavigate(): Navigate {\n const navigate = _useNavigate()\n const searchParams = useSearchParams()\n\n return (\n toOrDelta: To | number,\n options: (NavigateOptions & { next?: boolean }) | undefined = undefined,\n ) => {\n if (typeof toOrDelta === \"number\") void navigate(toOrDelta)\n else {\n const { next = true, ..._options } = options || {}\n\n void navigate(\n next && \"next\" in searchParams ? searchParams.next : toOrDelta,\n _options,\n )\n }\n }\n}\n\nexport function useLocation<State = {}>() {\n return _useLocation() as Location<null | Partial<PageState & State>>\n}\n\n// -----------------------------------------------------------------------------\n// Use Search Params\n// -----------------------------------------------------------------------------\n\nexport function useSearchParams(): { [k: string]: string }\n\nexport function useSearchParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n): TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n\nexport function useSearchParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape?: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n) {\n const searchParams = Object.fromEntries(_useSearchParams()[0].entries())\n if (!shape) return searchParams\n\n return tryValidateSync(searchParams, objectSchema(shape), validateOptions)\n}\n\n// -----------------------------------------------------------------------------\n// Use Params\n// -----------------------------------------------------------------------------\n\nexport function useParams(): ReadOnly<Params<string>>\n\nexport function useParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n): TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n\nexport function useParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape?: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n) {\n const params = _useParams()\n if (!shape) return params\n\n return tryValidateSync(params, objectSchema(shape), validateOptions)\n}\n\nexport function useParamsRequired<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>({\n shape,\n children,\n onValidationError,\n onValidationSuccess = () => {},\n validateOptions,\n}: {\n shape: Shape\n children: (\n data: NonNullable<\n TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n >,\n ) => ReactNode\n onValidationError: (navigate: Navigate) => void\n onValidationSuccess?: (\n params: NonNullable<\n TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n >,\n ) => void\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >\n}) {\n const params = useParams(shape, validateOptions)\n const navigate = useNavigate()\n\n useEffect(\n () => {\n if (params) onValidationSuccess(params)\n else onValidationError(navigate)\n },\n [], // eslint-disable-line react-hooks/exhaustive-deps\n )\n\n return params ? children(params) : <></>\n}\n","import * as yup from \"yup\"\nimport { type ReactNode, useCallback, useEffect, useState } from \"react\"\nimport Cookies from \"js-cookie\"\nimport type { TypedUseMutation } from \"@reduxjs/toolkit/query/react\"\nimport { createSearchParams } from \"react-router\"\n// eslint-disable-next-line @typescript-eslint/no-restricted-imports\nimport { useSelector } from \"react-redux\"\n\nimport { type AuthFactor, type User } from \"../api\"\nimport {\n type OAuth2CodeChallenge,\n type OAuth2CodeChallengeLengths,\n type OAuth2ReceiveCodeUrlSearchParams,\n type OAuth2RequestCodeUrlSearchParams,\n generateOAuth2CodeChallenge,\n makeOAuth2StorageKey,\n} from \"../utils/auth\"\nimport { useLocation, useNavigate, useSearchParams } from \"./router\"\nimport { type ExchangeOAuth2CodeArg } from \"../api/endpoints/session\"\nimport { SESSION_METADATA_COOKIE_NAME } from \"../settings\"\nimport { generateSecureRandomString } from \"../utils/general\"\nimport { selectIsLoggedIn } from \"../slices/session\"\n\n// -----------------------------------------------------------------------------\n// Session\n// -----------------------------------------------------------------------------\n\nexport interface SessionMetadata {\n user_id: User[\"id\"]\n user_type: \"teacher\" | \"student\" | \"indy\"\n auth_factors: Array<AuthFactor[\"type\"]>\n otp_bypass_token_exists: boolean\n}\n\nexport function useSessionMetadata<T = SessionMetadata>(\n cookieName = SESSION_METADATA_COOKIE_NAME,\n): T | undefined {\n return useSelector(selectIsLoggedIn)\n ? (JSON.parse(Cookies.get(cookieName)!) as T)\n : undefined\n}\n\n/**\n * A utility function to predefine a useSessionMetadata hook.\n * @param cookieName The name of the session metadata cookie.\n * @returns An object containing the session metadata.\n */\nuseSessionMetadata.predefine = <SessionMetadata,>(\n cookieName = SESSION_METADATA_COOKIE_NAME,\n) => {\n return () => useSessionMetadata<SessionMetadata>(cookieName)\n}\n\nexport type UseSessionChildrenFunction<Required extends boolean> = (\n metadata: Required extends true\n ? SessionMetadata\n : SessionMetadata | undefined,\n) => ReactNode\n\nexport type UseSessionChildren<\n UserType extends SessionMetadata[\"user_type\"] | undefined,\n> =\n | ReactNode\n | (UserType extends undefined\n ? UseSessionChildrenFunction<false>\n : UseSessionChildrenFunction<true>)\n\nexport type UseSessionOptions<\n UserType extends SessionMetadata[\"user_type\"] | undefined,\n> = Partial<{\n userType: UserType\n next: boolean\n}>\n\nexport function useSession<\n UserType extends SessionMetadata[\"user_type\"] | undefined = undefined,\n>(\n children: UseSessionChildren<UserType>,\n options: UseSessionOptions<UserType> = {},\n) {\n const { userType, next = true } = options\n\n const { pathname } = useLocation()\n const navigate = useNavigate()\n const sessionMetadata = useSessionMetadata()\n\n const loginRequired =\n userType && (!sessionMetadata || sessionMetadata.user_type !== userType)\n\n useEffect(() => {\n if (loginRequired) {\n navigate({\n pathname:\n \"/login\" +\n {\n teacher: \"/teacher\",\n student: \"/student\",\n indy: \"/independent\",\n }[userType],\n search: next\n ? createSearchParams({ next: pathname }).toString()\n : undefined,\n })\n }\n }, [navigate, loginRequired, userType, next, pathname])\n\n if (loginRequired) return <></>\n\n if (typeof children === \"function\") {\n return sessionMetadata\n ? (children as UseSessionChildrenFunction<true>)(sessionMetadata)\n : (children as UseSessionChildrenFunction<false>)(sessionMetadata)\n }\n\n return children\n}\n\n// -----------------------------------------------------------------------------\n// OAuth2\n// -----------------------------------------------------------------------------\n\nexport function useOAuth2State(\n provider: string,\n length: number = 32,\n storageKey: string = \"state\",\n): [string | undefined, () => void] {\n const oAuth2StorageKey = makeOAuth2StorageKey(provider, storageKey)\n const storageValue = sessionStorage.getItem(oAuth2StorageKey)\n\n const [_state, _setState] = useState<string>()\n\n useEffect(() => {\n let state: string\n if (storageValue && storageValue.length === length) {\n state = storageValue\n } else {\n state = generateSecureRandomString(length)\n sessionStorage.setItem(oAuth2StorageKey, state)\n }\n\n _setState(state)\n }, [oAuth2StorageKey, storageValue, length])\n\n const resetState = useCallback(() => {\n sessionStorage.removeItem(oAuth2StorageKey)\n _setState(undefined)\n }, [oAuth2StorageKey])\n\n return [_state, resetState]\n}\n\nexport function useOAuth2CodeChallenge(\n provider: string,\n length: OAuth2CodeChallengeLengths = 128,\n storageKey: string = \"codeChallenge\",\n): [OAuth2CodeChallenge | undefined, () => void] {\n const oAuth2StorageKey = makeOAuth2StorageKey(provider, storageKey)\n const storageValue = sessionStorage.getItem(oAuth2StorageKey)\n\n const [_codeChallenge, _setCodeChallenge] = useState<OAuth2CodeChallenge>()\n\n useEffect(() => {\n let codeChallenge: OAuth2CodeChallenge | undefined\n if (storageValue) {\n const storageJsonValue: unknown = JSON.parse(storageValue)\n if (\n typeof storageJsonValue === \"object\" &&\n storageJsonValue &&\n \"verifier\" in storageJsonValue &&\n typeof storageJsonValue.verifier == \"string\" &&\n storageJsonValue.verifier.length === length &&\n \"challenge\" in storageJsonValue &&\n typeof storageJsonValue.challenge === \"string\" &&\n \"method\" in storageJsonValue &&\n storageJsonValue.method === \"S256\"\n ) {\n codeChallenge = {\n verifier: storageJsonValue.verifier,\n challenge: storageJsonValue.challenge,\n method: storageJsonValue.method,\n }\n }\n }\n\n if (codeChallenge) _setCodeChallenge(codeChallenge)\n else {\n generateOAuth2CodeChallenge(length)\n .then(codeChallenge => {\n sessionStorage.setItem(\n oAuth2StorageKey,\n JSON.stringify(codeChallenge),\n )\n\n _setCodeChallenge(codeChallenge)\n })\n .catch(error => {\n if (error) console.error(error)\n })\n }\n }, [oAuth2StorageKey, storageValue, length])\n\n const resetCodeChallenge = useCallback(() => {\n sessionStorage.removeItem(oAuth2StorageKey)\n _setCodeChallenge(undefined)\n }, [oAuth2StorageKey])\n\n return [_codeChallenge, resetCodeChallenge]\n}\n\ninterface BaseUseOAuth2KwArgs<SessionMetadata> {\n provider: string\n authUri: string\n clientId: string\n redirectUri: string\n scope: string\n responseType?: \"code\"\n accessType?: \"offline\"\n prompt?: string\n useLoginMutation: TypedUseMutation<\n SessionMetadata,\n ExchangeOAuth2CodeArg,\n any\n >\n onCreateSession: (result: SessionMetadata) => void\n onRetrieveSession: (metadata: SessionMetadata) => void\n}\n\ninterface UseOAuth2KwArgs<SessionMetadata>\n extends BaseUseOAuth2KwArgs<SessionMetadata> {\n useSessionMetadata: () => SessionMetadata | undefined\n}\n\nexport type OAuth2 = [string, OAuth2RequestCodeUrlSearchParams] | []\n\n// https://datatracker.ietf.org/doc/html/rfc7636\nfunction useOAuth2Internal<SessionMetadata>({\n provider,\n authUri,\n clientId,\n redirectUri,\n scope,\n responseType = \"code\",\n accessType = \"offline\",\n prompt,\n useSessionMetadata,\n useLoginMutation,\n onCreateSession,\n onRetrieveSession,\n}: UseOAuth2KwArgs<SessionMetadata>): OAuth2 {\n const [state, resetState] = useOAuth2State(provider)\n const [\n {\n verifier: codeVerifier,\n challenge: codeChallenge,\n method: codeChallengeMethod,\n } = {},\n resetCodeChallenge,\n ] = useOAuth2CodeChallenge(provider)\n const [\n login,\n {\n originalArgs: loginArgs = {} as ExchangeOAuth2CodeArg,\n isLoading: loginIsLoading,\n isError: loginIsError,\n },\n ] = useLoginMutation()\n const sessionMetadata = useSessionMetadata()\n const navigate = useNavigate()\n const searchParams =\n useSearchParams({ code: yup.string(), state: yup.string() }) || {}\n const location = useLocation<OAuth2ReceiveCodeUrlSearchParams>()\n\n const locationState = location.state || {}\n\n useEffect(() => {\n // If the the auth provider has redirected back to our site with the\n // expected search params, we redirect to the current page to remove them.\n if (searchParams.code && searchParams.state) {\n navigate<OAuth2ReceiveCodeUrlSearchParams>(\".\", {\n // Removes the URL containing the search params from the history stack.\n replace: true,\n // Ensure we don't break the auth flow by navigating to another page.\n next: false,\n // Store the search params in the page's state instead.\n state: { code: searchParams.code, state: searchParams.state },\n })\n }\n }, [searchParams.code, searchParams.state, navigate])\n\n useEffect(() => {\n // If we're already logged in, no need to log in again.\n if (sessionMetadata) onRetrieveSession(sessionMetadata)\n else if (\n // If the state and code verifier have been generated...\n state &&\n codeVerifier &&\n // ...and the page's state contains a code...\n locationState.code &&\n // ...and the page's state contains the stored state...\n locationState.state === state &&\n // ...and the login endpoint was not called with the current values or has\n // not returned an error...\n (loginArgs.code !== locationState.code ||\n loginArgs.code_verifier !== codeVerifier ||\n loginArgs.redirect_uri !== redirectUri ||\n !loginIsError) &&\n // ...and the login endpoint is not currently being called...\n !loginIsLoading\n ) {\n // ...call the login endpoint.\n login({\n code: locationState.code,\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n })\n .unwrap()\n .then(onCreateSession)\n .catch(() => {\n navigate(\".\", {\n replace: true,\n state: {\n notifications: [\n {\n props: {\n error: true,\n children: \"Failed to login. Please try again.\",\n },\n },\n ],\n },\n })\n })\n .finally(() => {\n resetState()\n resetCodeChallenge()\n })\n }\n }, [\n navigate,\n redirectUri,\n // State\n state,\n locationState.state,\n resetState,\n // Code\n codeVerifier,\n locationState.code,\n resetCodeChallenge,\n // Login\n login,\n loginIsLoading,\n loginIsError,\n loginArgs.code,\n loginArgs.code_verifier,\n loginArgs.redirect_uri,\n // Session\n sessionMetadata,\n onCreateSession,\n onRetrieveSession,\n ])\n\n if (state && codeChallenge && codeChallengeMethod) {\n const urlSearchParams: OAuth2RequestCodeUrlSearchParams = {\n client_id: clientId,\n redirect_uri: redirectUri,\n scope,\n response_type: responseType,\n access_type: accessType,\n state,\n code_challenge: codeChallenge,\n code_challenge_method: codeChallengeMethod,\n }\n\n if (prompt) urlSearchParams[\"prompt\"] = prompt\n\n return [\n authUri + \"?\" + new URLSearchParams(urlSearchParams).toString(),\n urlSearchParams,\n ]\n }\n\n return []\n}\n\nexport const useOAuth2: {\n <SessionMetadata>(kwargs: UseOAuth2KwArgs<SessionMetadata>): OAuth2\n (kwargs: BaseUseOAuth2KwArgs<SessionMetadata>): OAuth2\n} = <_SessionMetadata,>(\n kwargs:\n | UseOAuth2KwArgs<_SessionMetadata>\n | BaseUseOAuth2KwArgs<SessionMetadata>,\n): OAuth2 => {\n return useOAuth2Internal(\n // @ts-expect-error value is assignable\n \"useSessionMetadata\" in kwargs ? kwargs : { ...kwargs, useSessionMetadata },\n )\n}\n"],"names":["useNavigate","navigate","_useNavigate","searchParams","useSearchParams","toOrDelta","options","next","_options","useLocation","_useLocation","shape","validateOptions","_useSearchParams","tryValidateSync","objectSchema","useParams","params","_useParams","useParamsRequired","children","onValidationError","onValidationSuccess","useEffect","jsx","Fragment","useSessionMetadata","cookieName","SESSION_METADATA_COOKIE_NAME","useSelector","selectIsLoggedIn","Cookies","useSession","userType","pathname","sessionMetadata","loginRequired","createSearchParams","useOAuth2State","provider","length","storageKey","oAuth2StorageKey","makeOAuth2StorageKey","storageValue","_state","_setState","useState","state","generateSecureRandomString","resetState","useCallback","useOAuth2CodeChallenge","_codeChallenge","_setCodeChallenge","codeChallenge","storageJsonValue","generateOAuth2CodeChallenge","error","resetCodeChallenge","useOAuth2Internal","authUri","clientId","redirectUri","scope","responseType","accessType","prompt","useLoginMutation","onCreateSession","onRetrieveSession","codeVerifier","codeChallengeMethod","login","loginArgs","loginIsLoading","loginIsError","yup","locationState","urlSearchParams","useOAuth2","kwargs"],"mappings":"2xBAsCO,SAASA,GAAwB,CACtC,MAAMC,EAAWC,EAAAA,YAAA,EACXC,EAAeC,EAAA,EAErB,MAAO,CACLC,EACAC,EAA8D,SAC3D,CACH,GAAI,OAAOD,GAAc,SAAeJ,EAASI,CAAS,MACrD,CACH,KAAM,CAAE,KAAAE,EAAO,GAAM,GAAGC,CAAA,EAAaF,GAAW,CAAA,EAE3CL,EACHM,GAAQ,SAAUJ,EAAeA,EAAa,KAAOE,EACrDG,CAAA,CAEJ,CACF,CACF,CAEO,SAASC,GAA0B,CACxC,OAAOC,cAAA,CACT,CAmBO,SAASN,EAIdO,EACAC,EAIA,CACA,MAAMT,EAAe,OAAO,YAAYU,EAAAA,gBAAA,EAAmB,CAAC,EAAE,SAAS,EACvE,OAAKF,EAEEG,EAAAA,gBAAgBX,EAAcY,EAAAA,OAAaJ,CAAK,EAAGC,CAAe,EAFtDT,CAGrB,CAmBO,SAASa,EAIdL,EACAC,EAIA,CACA,MAAMK,EAASC,EAAAA,UAAA,EACf,OAAKP,EAEEG,EAAAA,gBAAgBG,EAAQF,EAAAA,OAAaJ,CAAK,EAAGC,CAAe,EAFhDK,CAGrB,CAEO,SAASE,EAGd,CACA,MAAAR,EACA,SAAAS,EACA,kBAAAC,EACA,oBAAAC,EAAsB,IAAM,CAAC,EAC7B,gBAAAV,CACF,EAiBG,CACD,MAAMK,EAASD,EAAUL,EAAOC,CAAe,EACzCX,EAAWD,EAAA,EAEjBuB,OAAAA,EAAAA,UACE,IAAM,CACAN,IAA4BA,CAAM,IACfhB,CAAQ,CACjC,EACA,CAAA,CAAC,EAGIgB,EAASG,EAASH,CAAM,EAAIO,EAAAA,kBAAAA,IAAAC,EAAAA,kBAAAA,SAAA,EAAE,CACvC,CCrIO,SAASC,EACdC,EAAaC,+BACE,CACf,OAAOC,EAAAA,YAAYC,kBAAgB,EAC9B,KAAK,MAAMC,EAAQ,IAAIJ,CAAU,CAAE,EACpC,MACN,CAOAD,EAAmB,UAAY,CAC7BC,EAAaC,iCAEN,IAAMF,EAAoCC,CAAU,EAwBtD,SAASK,EAGdZ,EACAd,EAAuC,GACvC,CACA,KAAM,CAAE,SAAA2B,EAAU,KAAA1B,EAAO,EAAA,EAASD,EAE5B,CAAE,SAAA4B,CAAA,EAAazB,EAAA,EACfR,EAAWD,EAAA,EACXmC,EAAkBT,EAAA,EAElBU,EACJH,IAAa,CAACE,GAAmBA,EAAgB,YAAcF,GAmBjE,OAjBAV,EAAAA,UAAU,IAAM,CACVa,GACFnC,EAAS,CACP,SACE,SACA,CACE,QAAS,WACT,QAAS,WACT,KAAM,cAAA,EACNgC,CAAQ,EACZ,OAAQ1B,EACJ8B,qBAAmB,CAAE,KAAMH,CAAA,CAAU,EAAE,WACvC,MAAA,CACL,CAEL,EAAG,CAACjC,EAAUmC,EAAeH,EAAU1B,EAAM2B,CAAQ,CAAC,EAElDE,EAAsBZ,wBAAAC,EAAAA,kBAAAA,SAAA,CAAA,CAAE,EAExB,OAAOL,GAAa,WAEjBA,EAA8Ce,CAAe,EAI7Df,CACT,CAMO,SAASkB,EACdC,EACAC,EAAiB,GACjBC,EAAqB,QACa,CAClC,MAAMC,EAAmBC,EAAAA,qBAAqBJ,EAAUE,CAAU,EAC5DG,EAAe,eAAe,QAAQF,CAAgB,EAEtD,CAACG,EAAQC,CAAS,EAAIC,WAAA,EAE5BxB,EAAAA,UAAU,IAAM,CACd,IAAIyB,EACAJ,GAAgBA,EAAa,SAAWJ,EAC1CQ,EAAQJ,GAERI,EAAQC,EAAAA,2BAA2BT,CAAM,EACzC,eAAe,QAAQE,EAAkBM,CAAK,GAGhDF,EAAUE,CAAK,CACjB,EAAG,CAACN,EAAkBE,EAAcJ,CAAM,CAAC,EAE3C,MAAMU,EAAaC,EAAAA,YAAY,IAAM,CACnC,eAAe,WAAWT,CAAgB,EAC1CI,EAAU,MAAS,CACrB,EAAG,CAACJ,CAAgB,CAAC,EAErB,MAAO,CAACG,EAAQK,CAAU,CAC5B,CAEO,SAASE,EACdb,EACAC,EAAqC,IACrCC,EAAqB,gBAC0B,CAC/C,MAAMC,EAAmBC,EAAAA,qBAAqBJ,EAAUE,CAAU,EAC5DG,EAAe,eAAe,QAAQF,CAAgB,EAEtD,CAACW,EAAgBC,CAAiB,EAAIP,WAAA,EAE5CxB,EAAAA,UAAU,IAAM,CACd,IAAIgC,EACJ,GAAIX,EAAc,CAChB,MAAMY,EAA4B,KAAK,MAAMZ,CAAY,EAEvD,OAAOY,GAAqB,UAC5BA,GACA,aAAcA,GACd,OAAOA,EAAiB,UAAY,UACpCA,EAAiB,SAAS,SAAWhB,GACrC,cAAegB,GACf,OAAOA,EAAiB,WAAc,UACtC,WAAYA,GACZA,EAAiB,SAAW,SAE5BD,EAAgB,CACd,SAAUC,EAAiB,SAC3B,UAAWA,EAAiB,UAC5B,OAAQA,EAAiB,MAAA,EAG/B,CAEID,IAAiCA,CAAa,EAEhDE,EAAAA,4BAA4BjB,CAAM,EAC/B,KAAKe,GAAiB,CACrB,eAAe,QACbb,EACA,KAAK,UAAUa,CAAa,CAAA,EAG9BD,EAAkBC,CAAa,CACjC,CAAC,EACA,MAAMG,GAAS,CACVA,GAAO,QAAQ,MAAMA,CAAK,CAChC,CAAC,CAEP,EAAG,CAAChB,EAAkBE,EAAcJ,CAAM,CAAC,EAE3C,MAAMmB,EAAqBR,EAAAA,YAAY,IAAM,CAC3C,eAAe,WAAWT,CAAgB,EAC1CY,EAAkB,MAAS,CAC7B,EAAG,CAACZ,CAAgB,CAAC,EAErB,MAAO,CAACW,EAAgBM,CAAkB,CAC5C,CA4BA,SAASC,EAAmC,CAC1C,SAAArB,EACA,QAAAsB,EACA,SAAAC,EACA,YAAAC,EACA,MAAAC,EACA,aAAAC,EAAe,OACf,WAAAC,EAAa,UACb,OAAAC,EACA,mBAAAzC,EACA,iBAAA0C,EACA,gBAAAC,EACA,kBAAAC,CACF,EAA6C,CAC3C,KAAM,CAACtB,EAAOE,CAAU,EAAIZ,EAAeC,CAAQ,EAC7C,CACJ,CACE,SAAUgC,EACV,UAAWhB,EACX,OAAQiB,CAAA,EACN,CAAA,EACJb,CAAA,EACEP,EAAuBb,CAAQ,EAC7B,CACJkC,EACA,CACE,aAAcC,EAAY,CAAA,EAC1B,UAAWC,EACX,QAASC,CAAA,CACX,EACER,EAAA,EACEjC,EAAkBT,EAAAA,EAClBzB,EAAWD,EAAA,EACXG,EACJC,EAAgB,CAAE,KAAMyE,EAAI,SAAU,MAAOA,EAAI,OAAA,CAAO,CAAG,GAAK,CAAA,EAG5DC,EAFWrE,EAAA,EAEc,OAAS,CAAA,EAyFxC,GAvFAc,EAAAA,UAAU,IAAM,CAGVpB,EAAa,MAAQA,EAAa,OACpCF,EAA2C,IAAK,CAE9C,QAAS,GAET,KAAM,GAEN,MAAO,CAAE,KAAME,EAAa,KAAM,MAAOA,EAAa,KAAA,CAAM,CAC7D,CAEL,EAAG,CAACA,EAAa,KAAMA,EAAa,MAAOF,CAAQ,CAAC,EAEpDsB,EAAAA,UAAU,IAAM,CAEVY,IAAmCA,CAAe,EAGpDa,GACAuB,GAEAO,EAAc,MAEdA,EAAc,QAAU9B,IAGvB0B,EAAU,OAASI,EAAc,MAChCJ,EAAU,gBAAkBH,GAC5BG,EAAU,eAAiBX,GAC3B,CAACa,IAEH,CAACD,GAGDF,EAAM,CACJ,KAAMK,EAAc,KACpB,cAAeP,EACf,aAAcR,CAAA,CACf,EACE,OAAA,EACA,KAAKM,CAAe,EACpB,MAAM,IAAM,CACXpE,EAAS,IAAK,CACZ,QAAS,GACT,MAAO,CACL,cAAe,CACb,CACE,MAAO,CACL,MAAO,GACP,SAAU,oCAAA,CACZ,CACF,CACF,CACF,CACD,CACH,CAAC,EACA,QAAQ,IAAM,CACbiD,EAAA,EACAS,EAAA,CACF,CAAC,CAEP,EAAG,CACD1D,EACA8D,EAEAf,EACA8B,EAAc,MACd5B,EAEAqB,EACAO,EAAc,KACdnB,EAEAc,EACAE,EACAC,EACAF,EAAU,KACVA,EAAU,cACVA,EAAU,aAEVvC,EACAkC,EACAC,CAAA,CACD,EAEGtB,GAASO,GAAiBiB,EAAqB,CACjD,MAAMO,EAAoD,CACxD,UAAWjB,EACX,aAAcC,EACd,MAAAC,EACA,cAAeC,EACf,YAAaC,EACb,MAAAlB,EACA,eAAgBO,EAChB,sBAAuBiB,CAAA,EAGzB,OAAIL,IAAQY,EAAgB,OAAYZ,GAEjC,CACLN,EAAU,IAAM,IAAI,gBAAgBkB,CAAe,EAAE,SAAA,EACrDA,CAAA,CAEJ,CAEA,MAAO,CAAA,CACT,CAEO,MAAMC,EAIXC,GAIOrB,EAEL,uBAAwBqB,EAASA,EAAS,CAAE,GAAGA,EAAQ,mBAAAvD,CAAA,CAAmB"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { j as S } from "./jsx-runtime-
|
|
1
|
+
import { j as S } from "./jsx-runtime-XvoU0p7t.js";
|
|
2
2
|
import * as j from "yup";
|
|
3
3
|
import { object as L } from "yup";
|
|
4
4
|
import { useEffect as g, useState as V, useCallback as J } from "react";
|
|
5
5
|
import q from "js-cookie";
|
|
6
|
-
import { useNavigate as k, useLocation as w, useSearchParams as z, useParams as B, createSearchParams as G } from "react-router
|
|
6
|
+
import { useNavigate as k, useLocation as w, useSearchParams as z, useParams as B, createSearchParams as G } from "react-router";
|
|
7
7
|
import { useSelector as H } from "react-redux";
|
|
8
8
|
import { SESSION_METADATA_COOKIE_NAME as K } from "./settings/index.es.js";
|
|
9
9
|
import { b as Q } from "./session-oI-Ht2C8.js";
|
|
@@ -11,8 +11,8 @@ import { makeOAuth2StorageKey as R, generateOAuth2CodeChallenge as W } from "./u
|
|
|
11
11
|
import "@mui/material";
|
|
12
12
|
import { generateSecureRandomString as X } from "./utils/general.es.js";
|
|
13
13
|
import "@mui/icons-material";
|
|
14
|
-
import "./schemas-
|
|
15
|
-
import "./urls-
|
|
14
|
+
import "./schemas-CDXuSjyI.js";
|
|
15
|
+
import "./urls-BY-za1bX.js";
|
|
16
16
|
import { tryValidateSync as $ } from "./utils/schema.es.js";
|
|
17
17
|
import "./palette-CYwuLBW7.js";
|
|
18
18
|
function C() {
|
|
@@ -56,12 +56,12 @@ function Se({
|
|
|
56
56
|
// eslint-disable-line react-hooks/exhaustive-deps
|
|
57
57
|
), i ? s(i) : /* @__PURE__ */ S.jsx(S.Fragment, {});
|
|
58
58
|
}
|
|
59
|
-
function
|
|
59
|
+
function v(e = K) {
|
|
60
60
|
return H(Q) ? JSON.parse(q.get(e)) : void 0;
|
|
61
61
|
}
|
|
62
|
-
|
|
63
|
-
function
|
|
64
|
-
const { userType: o, next: t = !0 } = s, { pathname: a } = F(), i = C(), n =
|
|
62
|
+
v.predefine = (e = K) => () => v(e);
|
|
63
|
+
function ve(e, s = {}) {
|
|
64
|
+
const { userType: o, next: t = !0 } = s, { pathname: a } = F(), i = C(), n = v(), c = o && (!n || n.user_type !== o);
|
|
65
65
|
return g(() => {
|
|
66
66
|
c && i({
|
|
67
67
|
pathname: "/login" + {
|
|
@@ -138,7 +138,7 @@ function U({
|
|
|
138
138
|
isLoading: N,
|
|
139
139
|
isError: b
|
|
140
140
|
}
|
|
141
|
-
] = r(),
|
|
141
|
+
] = r(), _ = u(), p = C(), f = T({ code: j.string(), state: j.string() }) || {}, l = F().state || {};
|
|
142
142
|
if (g(() => {
|
|
143
143
|
f.code && f.state && p(".", {
|
|
144
144
|
// Removes the URL containing the search params from the history stack.
|
|
@@ -149,7 +149,7 @@ function U({
|
|
|
149
149
|
state: { code: f.code, state: f.state }
|
|
150
150
|
});
|
|
151
151
|
}, [f.code, f.state, p]), g(() => {
|
|
152
|
-
|
|
152
|
+
_ ? P(_) : (
|
|
153
153
|
// If the state and code verifier have been generated...
|
|
154
154
|
d && h && // ...and the page's state contains a code...
|
|
155
155
|
l.code && // ...and the page's state contains the stored state...
|
|
@@ -197,7 +197,7 @@ function U({
|
|
|
197
197
|
m.code_verifier,
|
|
198
198
|
m.redirect_uri,
|
|
199
199
|
// Session
|
|
200
|
-
|
|
200
|
+
_,
|
|
201
201
|
A,
|
|
202
202
|
P
|
|
203
203
|
]), d && x && O) {
|
|
@@ -218,20 +218,20 @@ function U({
|
|
|
218
218
|
}
|
|
219
219
|
return [];
|
|
220
220
|
}
|
|
221
|
-
const
|
|
221
|
+
const _e = (e) => U(
|
|
222
222
|
// @ts-expect-error value is assignable
|
|
223
|
-
"useSessionMetadata" in e ? e : { ...e, useSessionMetadata:
|
|
223
|
+
"useSessionMetadata" in e ? e : { ...e, useSessionMetadata: v }
|
|
224
224
|
);
|
|
225
225
|
export {
|
|
226
|
-
|
|
226
|
+
ve as a,
|
|
227
227
|
Z as b,
|
|
228
228
|
D as c,
|
|
229
|
-
|
|
229
|
+
_e as d,
|
|
230
230
|
C as e,
|
|
231
231
|
F as f,
|
|
232
232
|
T as g,
|
|
233
233
|
Y as h,
|
|
234
234
|
Se as i,
|
|
235
|
-
|
|
235
|
+
v as u
|
|
236
236
|
};
|
|
237
|
-
//# sourceMappingURL=auth-
|
|
237
|
+
//# sourceMappingURL=auth-CvJ5Mh6y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-CvJ5Mh6y.js","sources":["../src/hooks/router.tsx","../src/hooks/auth.tsx"],"sourcesContent":["import {\n type Location,\n type Params,\n type To,\n type NavigateOptions as _NavigateOptions,\n useLocation as _useLocation,\n useNavigate as _useNavigate,\n useParams as _useParams,\n useSearchParams as _useSearchParams,\n} from \"react-router\"\nimport { type ObjectShape, object as objectSchema } from \"yup\"\nimport { type ReactNode, useEffect } from \"react\"\n\nimport {\n type ObjectSchemaFromShape,\n type TryValidateSyncOnErrorRT,\n type TryValidateSyncOptions,\n type TryValidateSyncRT,\n tryValidateSync,\n} from \"../utils/schema\"\nimport { type PageState } from \"../components/page\"\nimport { type ReadOnly } from \"../utils/router\"\n\nexport type NavigateOptions<\n State extends Record<string, any> = Record<string, any>,\n> = Omit<_NavigateOptions, \"state\"> & {\n state?: State & Partial<PageState>\n next?: boolean\n}\n\nexport type Navigate = {\n <State extends Record<string, any> = Record<string, any>>(\n to: To,\n options?: NavigateOptions<State>,\n ): void\n (delta: number): void\n}\n\nexport function useNavigate(): Navigate {\n const navigate = _useNavigate()\n const searchParams = useSearchParams()\n\n return (\n toOrDelta: To | number,\n options: (NavigateOptions & { next?: boolean }) | undefined = undefined,\n ) => {\n if (typeof toOrDelta === \"number\") void navigate(toOrDelta)\n else {\n const { next = true, ..._options } = options || {}\n\n void navigate(\n next && \"next\" in searchParams ? searchParams.next : toOrDelta,\n _options,\n )\n }\n }\n}\n\nexport function useLocation<State = {}>() {\n return _useLocation() as Location<null | Partial<PageState & State>>\n}\n\n// -----------------------------------------------------------------------------\n// Use Search Params\n// -----------------------------------------------------------------------------\n\nexport function useSearchParams(): { [k: string]: string }\n\nexport function useSearchParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n): TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n\nexport function useSearchParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape?: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n) {\n const searchParams = Object.fromEntries(_useSearchParams()[0].entries())\n if (!shape) return searchParams\n\n return tryValidateSync(searchParams, objectSchema(shape), validateOptions)\n}\n\n// -----------------------------------------------------------------------------\n// Use Params\n// -----------------------------------------------------------------------------\n\nexport function useParams(): ReadOnly<Params<string>>\n\nexport function useParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n): TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n\nexport function useParams<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>(\n shape?: Shape,\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >,\n) {\n const params = _useParams()\n if (!shape) return params\n\n return tryValidateSync(params, objectSchema(shape), validateOptions)\n}\n\nexport function useParamsRequired<\n OnErrorRT extends TryValidateSyncOnErrorRT<ObjectSchemaFromShape<Shape>>,\n Shape extends ObjectShape = {},\n>({\n shape,\n children,\n onValidationError,\n onValidationSuccess = () => {},\n validateOptions,\n}: {\n shape: Shape\n children: (\n data: NonNullable<\n TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n >,\n ) => ReactNode\n onValidationError: (navigate: Navigate) => void\n onValidationSuccess?: (\n params: NonNullable<\n TryValidateSyncRT<ObjectSchemaFromShape<Shape>, OnErrorRT>\n >,\n ) => void\n validateOptions?: TryValidateSyncOptions<\n ObjectSchemaFromShape<Shape>,\n OnErrorRT\n >\n}) {\n const params = useParams(shape, validateOptions)\n const navigate = useNavigate()\n\n useEffect(\n () => {\n if (params) onValidationSuccess(params)\n else onValidationError(navigate)\n },\n [], // eslint-disable-line react-hooks/exhaustive-deps\n )\n\n return params ? children(params) : <></>\n}\n","import * as yup from \"yup\"\nimport { type ReactNode, useCallback, useEffect, useState } from \"react\"\nimport Cookies from \"js-cookie\"\nimport type { TypedUseMutation } from \"@reduxjs/toolkit/query/react\"\nimport { createSearchParams } from \"react-router\"\n// eslint-disable-next-line @typescript-eslint/no-restricted-imports\nimport { useSelector } from \"react-redux\"\n\nimport { type AuthFactor, type User } from \"../api\"\nimport {\n type OAuth2CodeChallenge,\n type OAuth2CodeChallengeLengths,\n type OAuth2ReceiveCodeUrlSearchParams,\n type OAuth2RequestCodeUrlSearchParams,\n generateOAuth2CodeChallenge,\n makeOAuth2StorageKey,\n} from \"../utils/auth\"\nimport { useLocation, useNavigate, useSearchParams } from \"./router\"\nimport { type ExchangeOAuth2CodeArg } from \"../api/endpoints/session\"\nimport { SESSION_METADATA_COOKIE_NAME } from \"../settings\"\nimport { generateSecureRandomString } from \"../utils/general\"\nimport { selectIsLoggedIn } from \"../slices/session\"\n\n// -----------------------------------------------------------------------------\n// Session\n// -----------------------------------------------------------------------------\n\nexport interface SessionMetadata {\n user_id: User[\"id\"]\n user_type: \"teacher\" | \"student\" | \"indy\"\n auth_factors: Array<AuthFactor[\"type\"]>\n otp_bypass_token_exists: boolean\n}\n\nexport function useSessionMetadata<T = SessionMetadata>(\n cookieName = SESSION_METADATA_COOKIE_NAME,\n): T | undefined {\n return useSelector(selectIsLoggedIn)\n ? (JSON.parse(Cookies.get(cookieName)!) as T)\n : undefined\n}\n\n/**\n * A utility function to predefine a useSessionMetadata hook.\n * @param cookieName The name of the session metadata cookie.\n * @returns An object containing the session metadata.\n */\nuseSessionMetadata.predefine = <SessionMetadata,>(\n cookieName = SESSION_METADATA_COOKIE_NAME,\n) => {\n return () => useSessionMetadata<SessionMetadata>(cookieName)\n}\n\nexport type UseSessionChildrenFunction<Required extends boolean> = (\n metadata: Required extends true\n ? SessionMetadata\n : SessionMetadata | undefined,\n) => ReactNode\n\nexport type UseSessionChildren<\n UserType extends SessionMetadata[\"user_type\"] | undefined,\n> =\n | ReactNode\n | (UserType extends undefined\n ? UseSessionChildrenFunction<false>\n : UseSessionChildrenFunction<true>)\n\nexport type UseSessionOptions<\n UserType extends SessionMetadata[\"user_type\"] | undefined,\n> = Partial<{\n userType: UserType\n next: boolean\n}>\n\nexport function useSession<\n UserType extends SessionMetadata[\"user_type\"] | undefined = undefined,\n>(\n children: UseSessionChildren<UserType>,\n options: UseSessionOptions<UserType> = {},\n) {\n const { userType, next = true } = options\n\n const { pathname } = useLocation()\n const navigate = useNavigate()\n const sessionMetadata = useSessionMetadata()\n\n const loginRequired =\n userType && (!sessionMetadata || sessionMetadata.user_type !== userType)\n\n useEffect(() => {\n if (loginRequired) {\n navigate({\n pathname:\n \"/login\" +\n {\n teacher: \"/teacher\",\n student: \"/student\",\n indy: \"/independent\",\n }[userType],\n search: next\n ? createSearchParams({ next: pathname }).toString()\n : undefined,\n })\n }\n }, [navigate, loginRequired, userType, next, pathname])\n\n if (loginRequired) return <></>\n\n if (typeof children === \"function\") {\n return sessionMetadata\n ? (children as UseSessionChildrenFunction<true>)(sessionMetadata)\n : (children as UseSessionChildrenFunction<false>)(sessionMetadata)\n }\n\n return children\n}\n\n// -----------------------------------------------------------------------------\n// OAuth2\n// -----------------------------------------------------------------------------\n\nexport function useOAuth2State(\n provider: string,\n length: number = 32,\n storageKey: string = \"state\",\n): [string | undefined, () => void] {\n const oAuth2StorageKey = makeOAuth2StorageKey(provider, storageKey)\n const storageValue = sessionStorage.getItem(oAuth2StorageKey)\n\n const [_state, _setState] = useState<string>()\n\n useEffect(() => {\n let state: string\n if (storageValue && storageValue.length === length) {\n state = storageValue\n } else {\n state = generateSecureRandomString(length)\n sessionStorage.setItem(oAuth2StorageKey, state)\n }\n\n _setState(state)\n }, [oAuth2StorageKey, storageValue, length])\n\n const resetState = useCallback(() => {\n sessionStorage.removeItem(oAuth2StorageKey)\n _setState(undefined)\n }, [oAuth2StorageKey])\n\n return [_state, resetState]\n}\n\nexport function useOAuth2CodeChallenge(\n provider: string,\n length: OAuth2CodeChallengeLengths = 128,\n storageKey: string = \"codeChallenge\",\n): [OAuth2CodeChallenge | undefined, () => void] {\n const oAuth2StorageKey = makeOAuth2StorageKey(provider, storageKey)\n const storageValue = sessionStorage.getItem(oAuth2StorageKey)\n\n const [_codeChallenge, _setCodeChallenge] = useState<OAuth2CodeChallenge>()\n\n useEffect(() => {\n let codeChallenge: OAuth2CodeChallenge | undefined\n if (storageValue) {\n const storageJsonValue: unknown = JSON.parse(storageValue)\n if (\n typeof storageJsonValue === \"object\" &&\n storageJsonValue &&\n \"verifier\" in storageJsonValue &&\n typeof storageJsonValue.verifier == \"string\" &&\n storageJsonValue.verifier.length === length &&\n \"challenge\" in storageJsonValue &&\n typeof storageJsonValue.challenge === \"string\" &&\n \"method\" in storageJsonValue &&\n storageJsonValue.method === \"S256\"\n ) {\n codeChallenge = {\n verifier: storageJsonValue.verifier,\n challenge: storageJsonValue.challenge,\n method: storageJsonValue.method,\n }\n }\n }\n\n if (codeChallenge) _setCodeChallenge(codeChallenge)\n else {\n generateOAuth2CodeChallenge(length)\n .then(codeChallenge => {\n sessionStorage.setItem(\n oAuth2StorageKey,\n JSON.stringify(codeChallenge),\n )\n\n _setCodeChallenge(codeChallenge)\n })\n .catch(error => {\n if (error) console.error(error)\n })\n }\n }, [oAuth2StorageKey, storageValue, length])\n\n const resetCodeChallenge = useCallback(() => {\n sessionStorage.removeItem(oAuth2StorageKey)\n _setCodeChallenge(undefined)\n }, [oAuth2StorageKey])\n\n return [_codeChallenge, resetCodeChallenge]\n}\n\ninterface BaseUseOAuth2KwArgs<SessionMetadata> {\n provider: string\n authUri: string\n clientId: string\n redirectUri: string\n scope: string\n responseType?: \"code\"\n accessType?: \"offline\"\n prompt?: string\n useLoginMutation: TypedUseMutation<\n SessionMetadata,\n ExchangeOAuth2CodeArg,\n any\n >\n onCreateSession: (result: SessionMetadata) => void\n onRetrieveSession: (metadata: SessionMetadata) => void\n}\n\ninterface UseOAuth2KwArgs<SessionMetadata>\n extends BaseUseOAuth2KwArgs<SessionMetadata> {\n useSessionMetadata: () => SessionMetadata | undefined\n}\n\nexport type OAuth2 = [string, OAuth2RequestCodeUrlSearchParams] | []\n\n// https://datatracker.ietf.org/doc/html/rfc7636\nfunction useOAuth2Internal<SessionMetadata>({\n provider,\n authUri,\n clientId,\n redirectUri,\n scope,\n responseType = \"code\",\n accessType = \"offline\",\n prompt,\n useSessionMetadata,\n useLoginMutation,\n onCreateSession,\n onRetrieveSession,\n}: UseOAuth2KwArgs<SessionMetadata>): OAuth2 {\n const [state, resetState] = useOAuth2State(provider)\n const [\n {\n verifier: codeVerifier,\n challenge: codeChallenge,\n method: codeChallengeMethod,\n } = {},\n resetCodeChallenge,\n ] = useOAuth2CodeChallenge(provider)\n const [\n login,\n {\n originalArgs: loginArgs = {} as ExchangeOAuth2CodeArg,\n isLoading: loginIsLoading,\n isError: loginIsError,\n },\n ] = useLoginMutation()\n const sessionMetadata = useSessionMetadata()\n const navigate = useNavigate()\n const searchParams =\n useSearchParams({ code: yup.string(), state: yup.string() }) || {}\n const location = useLocation<OAuth2ReceiveCodeUrlSearchParams>()\n\n const locationState = location.state || {}\n\n useEffect(() => {\n // If the the auth provider has redirected back to our site with the\n // expected search params, we redirect to the current page to remove them.\n if (searchParams.code && searchParams.state) {\n navigate<OAuth2ReceiveCodeUrlSearchParams>(\".\", {\n // Removes the URL containing the search params from the history stack.\n replace: true,\n // Ensure we don't break the auth flow by navigating to another page.\n next: false,\n // Store the search params in the page's state instead.\n state: { code: searchParams.code, state: searchParams.state },\n })\n }\n }, [searchParams.code, searchParams.state, navigate])\n\n useEffect(() => {\n // If we're already logged in, no need to log in again.\n if (sessionMetadata) onRetrieveSession(sessionMetadata)\n else if (\n // If the state and code verifier have been generated...\n state &&\n codeVerifier &&\n // ...and the page's state contains a code...\n locationState.code &&\n // ...and the page's state contains the stored state...\n locationState.state === state &&\n // ...and the login endpoint was not called with the current values or has\n // not returned an error...\n (loginArgs.code !== locationState.code ||\n loginArgs.code_verifier !== codeVerifier ||\n loginArgs.redirect_uri !== redirectUri ||\n !loginIsError) &&\n // ...and the login endpoint is not currently being called...\n !loginIsLoading\n ) {\n // ...call the login endpoint.\n login({\n code: locationState.code,\n code_verifier: codeVerifier,\n redirect_uri: redirectUri,\n })\n .unwrap()\n .then(onCreateSession)\n .catch(() => {\n navigate(\".\", {\n replace: true,\n state: {\n notifications: [\n {\n props: {\n error: true,\n children: \"Failed to login. Please try again.\",\n },\n },\n ],\n },\n })\n })\n .finally(() => {\n resetState()\n resetCodeChallenge()\n })\n }\n }, [\n navigate,\n redirectUri,\n // State\n state,\n locationState.state,\n resetState,\n // Code\n codeVerifier,\n locationState.code,\n resetCodeChallenge,\n // Login\n login,\n loginIsLoading,\n loginIsError,\n loginArgs.code,\n loginArgs.code_verifier,\n loginArgs.redirect_uri,\n // Session\n sessionMetadata,\n onCreateSession,\n onRetrieveSession,\n ])\n\n if (state && codeChallenge && codeChallengeMethod) {\n const urlSearchParams: OAuth2RequestCodeUrlSearchParams = {\n client_id: clientId,\n redirect_uri: redirectUri,\n scope,\n response_type: responseType,\n access_type: accessType,\n state,\n code_challenge: codeChallenge,\n code_challenge_method: codeChallengeMethod,\n }\n\n if (prompt) urlSearchParams[\"prompt\"] = prompt\n\n return [\n authUri + \"?\" + new URLSearchParams(urlSearchParams).toString(),\n urlSearchParams,\n ]\n }\n\n return []\n}\n\nexport const useOAuth2: {\n <SessionMetadata>(kwargs: UseOAuth2KwArgs<SessionMetadata>): OAuth2\n (kwargs: BaseUseOAuth2KwArgs<SessionMetadata>): OAuth2\n} = <_SessionMetadata,>(\n kwargs:\n | UseOAuth2KwArgs<_SessionMetadata>\n | BaseUseOAuth2KwArgs<SessionMetadata>,\n): OAuth2 => {\n return useOAuth2Internal(\n // @ts-expect-error value is assignable\n \"useSessionMetadata\" in kwargs ? kwargs : { ...kwargs, useSessionMetadata },\n )\n}\n"],"names":["useNavigate","navigate","_useNavigate","searchParams","useSearchParams","toOrDelta","options","next","_options","useLocation","_useLocation","shape","validateOptions","_useSearchParams","tryValidateSync","objectSchema","useParams","params","_useParams","useParamsRequired","children","onValidationError","onValidationSuccess","useEffect","jsx","Fragment","useSessionMetadata","cookieName","SESSION_METADATA_COOKIE_NAME","useSelector","selectIsLoggedIn","Cookies","useSession","userType","pathname","sessionMetadata","loginRequired","createSearchParams","useOAuth2State","provider","length","storageKey","oAuth2StorageKey","makeOAuth2StorageKey","storageValue","_state","_setState","useState","state","generateSecureRandomString","resetState","useCallback","useOAuth2CodeChallenge","_codeChallenge","_setCodeChallenge","codeChallenge","storageJsonValue","generateOAuth2CodeChallenge","error","resetCodeChallenge","useOAuth2Internal","authUri","clientId","redirectUri","scope","responseType","accessType","prompt","useLoginMutation","onCreateSession","onRetrieveSession","codeVerifier","codeChallengeMethod","login","loginArgs","loginIsLoading","loginIsError","yup","locationState","urlSearchParams","useOAuth2","kwargs"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as i, a as s, C as l, b as t, D as F, E as d, F as o, c as m, O as r, P as p, R as u, S as c, T as A, U as C } from "../../index-
|
|
1
|
+
import { A as i, a as s, C as l, b as t, D as F, E as d, F as o, c as m, O as r, P as p, R as u, S as c, T as A, U as C } from "../../index-DuVBQMst.js";
|
|
2
2
|
export {
|
|
3
3
|
i as ApiAutocompleteField,
|
|
4
4
|
s as AutocompleteField,
|
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
2
|
-
* @remix-run/router v1.23.0
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) Remix Software Inc.
|
|
5
|
-
*
|
|
6
|
-
* This source code is licensed under the MIT license found in the
|
|
7
|
-
* LICENSE.md file in the root directory of this source tree.
|
|
8
|
-
*
|
|
9
|
-
* @license MIT
|
|
10
|
-
*/var w;(function(e){e.Pop="POP",e.Push="PUSH",e.Replace="REPLACE"})(w||(w={}));var T;(function(e){e.data="data",e.deferred="deferred",e.redirect="redirect",e.error="error"})(T||(T={}));const S=["post","put","patch","delete"];new Set(S);const V=["get",...S];new Set(V);function H({basename:e,children:n,location:t="/",future:s}){typeof t=="string"&&(t=h.parsePath(t));let o=w.Pop,i={pathname:t.pathname||"/",search:t.search||"",hash:t.hash||"",state:t.state!=null?t.state:null,key:t.key||"default"},u=J();return z.createElement(h.Router,{basename:e,children:n,location:i,navigationType:o,navigator:u,future:s,static:!0})}function J(){return{createHref:X,encodeLocation:I,push(e){throw new Error(`You cannot use navigator.push() on the server because it is a stateless environment. This error was probably triggered when you did a \`navigate(${JSON.stringify(e)})\` somewhere in your app.`)},replace(e){throw new Error(`You cannot use navigator.replace() on the server because it is a stateless environment. This error was probably triggered when you did a \`navigate(${JSON.stringify(e)}, { replace: true })\` somewhere in your app.`)},go(e){throw new Error(`You cannot use navigator.go() on the server because it is a stateless environment. This error was probably triggered when you did a \`navigate(${e})\` somewhere in your app.`)},back(){throw new Error("You cannot use navigator.back() on the server because it is a stateless environment.")},forward(){throw new Error("You cannot use navigator.forward() on the server because it is a stateless environment.")}}}function X(e){return typeof e=="string"?e:h.createPath(e)}function I(e){let n=typeof e=="string"?e:h.createPath(e);n=n.replace(/ $/,"%20");let t=K.test(n)?new URL(n):new URL(n,"http://localhost");return{pathname:t.pathname,search:t.search,hash:t.hash}}const K=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,q=({path:e,routes:n,header:t=r.jsxRuntimeExports.jsx(r.jsxRuntimeExports.Fragment,{}),footer:s=r.jsxRuntimeExports.jsx(r.jsxRuntimeExports.Fragment,{}),headerExcludePaths:o=[],footerExcludePaths:i=[]})=>r.jsxRuntimeExports.jsxs(r.jsxRuntimeExports.Fragment,{children:[!o.includes(e)&&t,r.jsxRuntimeExports.jsx(h.Routes,{children:n}),!i.includes(e)&&s]}),Q=e=>{const{pathname:n}=Y.useLocation();return r.jsxRuntimeExports.jsx(q,{path:n,...e})},W=({path:e,theme:n,store:t,maxIdleSeconds:s=3600,maxTotalSeconds:o=3600,...i})=>r.jsxRuntimeExports.jsxs(a.ThemeProvider,{theme:n,children:[r.jsxRuntimeExports.jsx(a.CssBaseline,{}),r.jsxRuntimeExports.jsx($.Provider,{store:t,children:typeof window>"u"?r.jsxRuntimeExports.jsx(H,{location:e,children:r.jsxRuntimeExports.jsx(q,{path:e,...i})}):r.jsxRuntimeExports.jsx(h.BrowserRouter,{children:r.jsxRuntimeExports.jsx(Q,{...i})})})]}),Z=({open:e=!1,onClick:n,...t})=>{const[s,o]=j.useState(e);return j.useEffect(()=>{o(e)},[e]),r.jsxRuntimeExports.jsx(a.Tooltip,{open:s,onMouseOver:()=>{s||o(!0)},onMouseLeave:()=>{o(!1)},onClick:D.wrap({after:()=>{o(!s)}},n),...t})},ee=({content:e,children:n=r.jsxRuntimeExports.jsx(O.ContentCopy,{}),...t})=>r.jsxRuntimeExports.jsx(a.IconButton,{"data-testid":"copy-icon-button",onClick:()=>{navigator.clipboard.writeText(e)},...t,children:n}),te=({children:e="Download",endIcon:n=r.jsxRuntimeExports.jsx(O.Download,{}),file:t,...s})=>{let o,i;if("mimeType"in t){const{text:u,mimeType:x,name:c,charset:p="utf-8"}=t;let{extension:m}=t;m||(m="."+{plain:"txt",csv:"csv"}[x]),i={download:c+m,href:`data:text/${x};charset=${p},${encodeURIComponent(u)}`}}else o=URL.createObjectURL(t),i={href:o};return j.useEffect(()=>()=>{o&&URL.revokeObjectURL(o)},[o]),r.jsxRuntimeExports.jsx(a.Button,{endIcon:n,...s,...i,children:e})},ne=({containerProps:e,toolbarProps:n,elevation:t=4,children:s,...o})=>{const i=a.useScrollTrigger({disableHysteresis:!0,threshold:0});return j.cloneElement(r.jsxRuntimeExports.jsx(a.AppBar,{elevation:t,...o,children:r.jsxRuntimeExports.jsx(a.Container,{...e,children:r.jsxRuntimeExports.jsx(a.Toolbar,{...n,children:s})})}),{position:i?"fixed":"sticky"})},re=({children:e,inputProps:n,...t})=>r.jsxRuntimeExports.jsxs(a.Button,{component:"label",...t,children:[e,r.jsxRuntimeExports.jsx("input",{type:"file",hidden:!0,...n})]}),se=({styleType:e,listProps:n={},pl:t=4,children:s})=>{const{sx:o,...i}=n,u={display:"list-item"};return r.jsxRuntimeExports.jsx(a.List,{sx:{listStyleType:e,pl:t,".MuiListItem-root":u,".MuiListItemText-root":u,...o},...i,children:s})},oe=({rows:e,containerProps:n={},globalItemProps:t})=>{const s=Number(n.columns??12),o=x=>Math.floor(s/x),i=(x,c,p)=>Math.floor(c/o(p))*e.length+x,u=(x,c)=>{const p=e[0].length%o(c);return p!==0&&x===e[0].length-1?(s-p*c)/2:0};return r.jsxRuntimeExports.jsx(a.Unstable_Grid2,{container:!0,...n,children:e.map((x,c)=>x.map(({element:p,itemProps:m={}},l)=>r.jsxRuntimeExports.jsx(a.Unstable_Grid2,{order:{xs:i(c,l,t.xs),sm:i(c,l,t.sm),md:i(c,l,t.md),lg:i(c,l,t.lg),xl:i(c,l,t.xl)},xsOffset:u(l,t.xs),smOffset:u(l,t.sm),mdOffset:u(l,t.md),lgOffset:u(l,t.lg),xlOffset:u(l,t.xl),...t,...m,children:p},`${c}-${l}`)))})},ie=({elementId:e,options:n,...t})=>r.jsxRuntimeExports.jsx(a.Link,{...t,onClick:()=>{document.getElementById(e)?.scrollIntoView(n)}}),ae=({children:e,useLazyListQuery:n,preferCacheValue:t,filters:s,page:o=0,rowsPerPage:i=50,rowsPerPageOptions:u=[50,100,150],stackProps:x,onRowsPerPageChange:c,onPageChange:p,...m})=>{const[l,y]=n(),[{limit:g,page:b,offset:E},L]=P.usePagination({page:o,limit:i});j.useEffect(()=>{l({limit:g,offset:E,...s},t)},[l,g,E,...Object.values(s||{}),t]);const{count:k,max_limit:v}=y.data||{};return v&&(u=u.filter(d=>d<=v)),r.jsxRuntimeExports.jsxs(a.Stack,{...x,children:[B.handleResultState(y,({data:d})=>e(d,{limit:g,page:b,offset:E,count:k,maxLimit:v})),r.jsxRuntimeExports.jsx(a.TablePagination,{component:"div",count:k??0,rowsPerPage:g,onRowsPerPageChange:d=>{L({limit:parseInt(d.target.value),page:0}),c&&c(d)},page:b,onPageChange:(d,R)=>{L(({limit:_})=>({limit:_,page:R})),p&&p(d,R)},rowsPerPageOptions:u.sort((d,R)=>d-R),...m})]})},ue=({src:e,style:n={},...t})=>r.jsxRuntimeExports.jsx(a.Box,{component:"iframe",width:"100%",src:e,title:"YouTube video player",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen",style:{border:"0px",aspectRatio:"16 / 9",...n},...t});exports.forms=C.index;exports.pages=M.index;exports.Link=f.Link;exports.LinkIconButton=f.LinkIconButton;exports.LinkListItem=f.LinkListItem;exports.LinkTab=f.LinkTab;exports.Navigate=f.Navigate;exports.LinkButton=U.LinkButton;exports.tables=N.index;exports.Countdown=A.Countdown;exports.Image=F.Image;exports.SyncError=B.SyncError;exports.App=W;exports.ClickableTooltip=Z;exports.CopyIconButton=ee;exports.DownloadFileButton=te;exports.ElevatedAppBar=ne;exports.InputFileButton=re;exports.ItemizedList=se;exports.OrderedGrid=oe;exports.ScrollIntoViewLink=ie;exports.TablePagination=ae;exports.YouTubeVideo=ue;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const w=require("../index-BUMdUVBH.cjs"),C=require("../index-DsVpb45W.cjs"),R=require("../Navigate-Cu8Ge031.cjs"),S=require("../LinkButton-cfljqSBx.cjs"),_=require("../index-CA-ugBSa.cjs"),n=require("../jsx-runtime-CeSfJrVB.cjs"),L=require("react-router"),u=require("@mui/material"),j=require("react"),M=require("react-redux"),F=require("../Countdown-7-Mzftzr.cjs"),U=require("../auth-C_aSIrwD.cjs"),A=require("../utils/general.cjs.js"),T=require("@mui/icons-material"),$=require("../Image-mgT45r_B.cjs"),b=require("../api-CnMfjRk3.cjs"),D=require("../api-DIgp_6Vr.cjs"),q=({path:e,routes:s,header:t=n.jsxRuntimeExports.jsx(n.jsxRuntimeExports.Fragment,{}),footer:r=n.jsxRuntimeExports.jsx(n.jsxRuntimeExports.Fragment,{}),headerExcludePaths:o=[],footerExcludePaths:i=[]})=>n.jsxRuntimeExports.jsxs(n.jsxRuntimeExports.Fragment,{children:[!o.includes(e)&&t,n.jsxRuntimeExports.jsx(L.Routes,{children:s}),!i.includes(e)&&r]}),G=e=>{const{pathname:s}=U.useLocation();return n.jsxRuntimeExports.jsx(q,{path:s,...e})},N=({path:e,theme:s,store:t,maxIdleSeconds:r=3600,maxTotalSeconds:o=3600,...i})=>n.jsxRuntimeExports.jsxs(u.ThemeProvider,{theme:s,children:[n.jsxRuntimeExports.jsx(u.CssBaseline,{}),n.jsxRuntimeExports.jsx(M.Provider,{store:t,children:e!==void 0?n.jsxRuntimeExports.jsx(L.StaticRouter,{location:e,children:n.jsxRuntimeExports.jsx(q,{path:e,...i})}):n.jsxRuntimeExports.jsx(L.BrowserRouter,{children:n.jsxRuntimeExports.jsx(G,{...i})})})]}),V=({open:e=!1,onClick:s,...t})=>{const[r,o]=j.useState(e);return j.useEffect(()=>{o(e)},[e]),n.jsxRuntimeExports.jsx(u.Tooltip,{open:r,onMouseOver:()=>{r||o(!0)},onMouseLeave:()=>{o(!1)},onClick:A.wrap({after:()=>{o(!r)}},s),...t})},Y=({content:e,children:s=n.jsxRuntimeExports.jsx(T.ContentCopy,{}),...t})=>n.jsxRuntimeExports.jsx(u.IconButton,{"data-testid":"copy-icon-button",onClick:()=>{navigator.clipboard.writeText(e)},...t,children:s}),P=({children:e="Download",endIcon:s=n.jsxRuntimeExports.jsx(T.Download,{}),file:t,...r})=>{let o,i;if("mimeType"in t){const{text:a,mimeType:l,name:c,charset:m="utf-8"}=t;let{extension:d}=t;d||(d="."+{plain:"txt",csv:"csv"}[l]),i={download:c+d,href:`data:text/${l};charset=${m},${encodeURIComponent(a)}`}}else o=URL.createObjectURL(t),i={href:o};return j.useEffect(()=>()=>{o&&URL.revokeObjectURL(o)},[o]),n.jsxRuntimeExports.jsx(u.Button,{endIcon:s,...r,...i,children:e})},z=({containerProps:e,toolbarProps:s,elevation:t=4,children:r,...o})=>{const i=u.useScrollTrigger({disableHysteresis:!0,threshold:0});return j.cloneElement(n.jsxRuntimeExports.jsx(u.AppBar,{elevation:t,...o,children:n.jsxRuntimeExports.jsx(u.Container,{...e,children:n.jsxRuntimeExports.jsx(u.Toolbar,{...s,children:r})})}),{position:i?"fixed":"sticky"})},H=({children:e,inputProps:s,...t})=>n.jsxRuntimeExports.jsxs(u.Button,{component:"label",...t,children:[e,n.jsxRuntimeExports.jsx("input",{type:"file",hidden:!0,...s})]}),I=({styleType:e,listProps:s={},pl:t=4,children:r})=>{const{sx:o,...i}=s,a={display:"list-item"};return n.jsxRuntimeExports.jsx(u.List,{sx:{listStyleType:e,pl:t,".MuiListItem-root":a,".MuiListItemText-root":a,...o},...i,children:r})},J=({rows:e,containerProps:s={},globalItemProps:t})=>{const r=Number(s.columns??12),o=l=>Math.floor(r/l),i=(l,c,m)=>Math.floor(c/o(m))*e.length+l,a=(l,c)=>{const m=e[0].length%o(c);return m!==0&&l===e[0].length-1?(r-m*c)/2:0};return n.jsxRuntimeExports.jsx(u.Unstable_Grid2,{container:!0,...s,children:e.map((l,c)=>l.map(({element:m,itemProps:d={}},x)=>n.jsxRuntimeExports.jsx(u.Unstable_Grid2,{order:{xs:i(c,x,t.xs),sm:i(c,x,t.sm),md:i(c,x,t.md),lg:i(c,x,t.lg),xl:i(c,x,t.xl)},xsOffset:a(x,t.xs),smOffset:a(x,t.sm),mdOffset:a(x,t.md),lgOffset:a(x,t.lg),xlOffset:a(x,t.xl),...t,...d,children:m},`${c}-${x}`)))})},K=({elementId:e,options:s,...t})=>n.jsxRuntimeExports.jsx(u.Link,{...t,onClick:()=>{document.getElementById(e)?.scrollIntoView(s)}}),Q=({children:e,useLazyListQuery:s,preferCacheValue:t,filters:r,page:o=0,rowsPerPage:i=50,rowsPerPageOptions:a=[50,100,150],stackProps:l,onRowsPerPageChange:c,onPageChange:m,...d})=>{const[x,k]=s(),[{limit:E,page:v,offset:g},y]=D.usePagination({page:o,limit:i});j.useEffect(()=>{x({limit:E,offset:g,...r},t)},[x,E,g,...Object.values(r||{}),t]);const{count:B,max_limit:h}=k.data||{};return h&&(a=a.filter(p=>p<=h)),n.jsxRuntimeExports.jsxs(u.Stack,{...l,children:[b.handleResultState(k,({data:p})=>e(p,{limit:E,page:v,offset:g,count:B,maxLimit:h})),n.jsxRuntimeExports.jsx(u.TablePagination,{component:"div",count:B??0,rowsPerPage:E,onRowsPerPageChange:p=>{y({limit:parseInt(p.target.value),page:0}),c&&c(p)},page:v,onPageChange:(p,f)=>{y(({limit:O})=>({limit:O,page:f})),m&&m(p,f)},rowsPerPageOptions:a.sort((p,f)=>p-f),...d})]})},W=({src:e,style:s={},...t})=>n.jsxRuntimeExports.jsx(u.Box,{component:"iframe",width:"100%",src:e,title:"YouTube video player",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen",style:{border:"0px",aspectRatio:"16 / 9",...s},...t});exports.forms=w.index;exports.pages=C.index;exports.Link=R.Link;exports.LinkIconButton=R.LinkIconButton;exports.LinkListItem=R.LinkListItem;exports.LinkTab=R.LinkTab;exports.Navigate=R.Navigate;exports.LinkButton=S.LinkButton;exports.tables=_.index;exports.Countdown=F.Countdown;exports.Image=$.Image;exports.SyncError=b.SyncError;exports.App=N;exports.ClickableTooltip=V;exports.CopyIconButton=Y;exports.DownloadFileButton=P;exports.ElevatedAppBar=z;exports.InputFileButton=H;exports.ItemizedList=I;exports.OrderedGrid=J;exports.ScrollIntoViewLink=K;exports.TablePagination=Q;exports.YouTubeVideo=W;
|
|
11
2
|
//# sourceMappingURL=index.cjs.js.map
|