feat: add verification bannner
This commit is contained in:
parent
1118ba2a71
commit
8235f516e9
|
@ -2,7 +2,7 @@ import { Button } from "~/components/ui/button";
|
||||||
import logoPng from "~/images/lume-logo.png?url";
|
import logoPng from "~/images/lume-logo.png?url";
|
||||||
import lumeColorLogoPng from "~/images/lume-color-logo.png?url";
|
import lumeColorLogoPng from "~/images/lume-color-logo.png?url";
|
||||||
import discordLogoPng from "~/images/discord-logo.png?url";
|
import discordLogoPng from "~/images/discord-logo.png?url";
|
||||||
import { Form, Link, useLocation } from "@remix-run/react";
|
import { Link, useLocation } from "@remix-run/react";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
|
@ -46,18 +46,22 @@ import {
|
||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
} from "./ui/tooltip";
|
} from "./ui/tooltip";
|
||||||
import filesize from "./lib/filesize";
|
import filesize from "./lib/filesize";
|
||||||
import { z } from "zod";
|
|
||||||
import { getFormProps, useForm, useInputControl } from "@conform-to/react";
|
|
||||||
import { getZodConstraint, parseWithZod } from "@conform-to/zod";
|
|
||||||
import { ErrorList } from "./forms";
|
import { ErrorList } from "./forms";
|
||||||
|
|
||||||
export const GeneralLayout = ({ children }: React.PropsWithChildren) => {
|
export const GeneralLayout = ({ children }: React.PropsWithChildren) => {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const { data: identity } = useGetIdentity<Identity>();
|
const { data: identity } = useGetIdentity<Identity>();
|
||||||
const { mutate: logout } = useLogout();
|
const { mutate: logout } = useLogout();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PinningProvider>
|
<PinningProvider>
|
||||||
<div className="h-full flex flex-row">
|
{!identity?.verified ? (
|
||||||
|
<div className="bg-primary-1 text-primary-1-foreground p-4">
|
||||||
|
We have sent you a verification email. Please click on the link in the
|
||||||
|
email to start using the platform.
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
<div className={"h-full flex flex-row"}>
|
||||||
<header className="p-10 pr-0 flex flex-col w-[240px] h-full scroll-m-0 overflow-hidden">
|
<header className="p-10 pr-0 flex flex-col w-[240px] h-full scroll-m-0 overflow-hidden">
|
||||||
<img src={logoPng} alt="Lume logo" className="h-10 w-32" />
|
<img src={logoPng} alt="Lume logo" className="h-10 w-32" />
|
||||||
|
|
||||||
|
@ -201,77 +205,73 @@ const UploadFileForm = () => {
|
||||||
<DialogHeader className="mb-6">
|
<DialogHeader className="mb-6">
|
||||||
<DialogTitle>Upload Files</DialogTitle>
|
<DialogTitle>Upload Files</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
{!hasStarted ? (
|
{!hasStarted ? (
|
||||||
<div
|
<div
|
||||||
{...getRootProps()}
|
{...getRootProps()}
|
||||||
className="border border-border rounded text-primary-2 bg-primary-dark h-48 flex flex-col items-center justify-center">
|
className="border border-border rounded text-primary-2 bg-primary-dark h-48 flex flex-col items-center justify-center">
|
||||||
<input
|
<input
|
||||||
hidden
|
hidden
|
||||||
aria-hidden
|
aria-hidden
|
||||||
key={new Date().toISOString()}
|
key={new Date().toISOString()}
|
||||||
multiple
|
multiple
|
||||||
name="uppyFiles[]"
|
name="uppyFiles[]"
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
/>
|
/>
|
||||||
<CloudUploadIcon className="w-24 h-24 stroke stroke-primary-dark" />
|
<CloudUploadIcon className="w-24 h-24 stroke stroke-primary-dark" />
|
||||||
<p>Drag & Drop Files or Browse</p>
|
<p>Drag & Drop Files or Browse</p>
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<div className="w-full space-y-3 max-h-48 overflow-y-auto">
|
|
||||||
{getFiles().map((file) => (
|
|
||||||
<UploadFileItem
|
|
||||||
key={file.id}
|
|
||||||
file={file}
|
|
||||||
onRemove={(id) => {
|
|
||||||
removeFile(id);
|
|
||||||
}}
|
|
||||||
failedState={getFailedState(file.id)}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<ErrorList
|
<div className="w-full space-y-3 max-h-48 overflow-y-auto">
|
||||||
errors={[
|
{getFiles().map((file) => (
|
||||||
...(hasErrored ? ["An error occurred"] : []),
|
<UploadFileItem
|
||||||
]}
|
key={file.id}
|
||||||
/>
|
file={file}
|
||||||
|
onRemove={(id) => {
|
||||||
|
removeFile(id);
|
||||||
|
}}
|
||||||
|
failedState={getFailedState(file.id)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
{hasStarted && !hasErrored ? (
|
<ErrorList errors={[...(hasErrored ? ["An error occurred"] : [])]} />
|
||||||
<div className="flex flex-col items-center gap-y-2 w-full text-primary-1">
|
|
||||||
<CloudCheckIcon className="w-32 h-32" />
|
|
||||||
{isCompleted
|
|
||||||
? "Upload completed"
|
|
||||||
: `${getFiles().length} files being uploaded`}
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{isUploading ? (
|
{hasStarted && !hasErrored ? (
|
||||||
<DialogClose asChild onClick={cancelAll}>
|
<div className="flex flex-col items-center gap-y-2 w-full text-primary-1">
|
||||||
<Button type="button" size={"lg"} className="mt-6">
|
<CloudCheckIcon className="w-32 h-32" />
|
||||||
Cancel
|
{isCompleted
|
||||||
</Button>
|
? "Upload completed"
|
||||||
</DialogClose>
|
: `${getFiles().length} files being uploaded`}
|
||||||
) : null}
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
{isCompleted ? (
|
{isUploading ? (
|
||||||
<DialogClose asChild>
|
<DialogClose asChild onClick={cancelAll}>
|
||||||
<Button type="button" size={"lg"} className="mt-6">
|
<Button type="button" size={"lg"} className="mt-6">
|
||||||
Close
|
Cancel
|
||||||
</Button>
|
|
||||||
</DialogClose>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
{!hasStarted && !isCompleted && !isUploading ? (
|
|
||||||
<Button
|
|
||||||
type="submit"
|
|
||||||
size={"lg"}
|
|
||||||
onClick={isValid ? upload : () => {}}
|
|
||||||
className="mt-6"
|
|
||||||
disabled={!isValid}>
|
|
||||||
Upload
|
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
</DialogClose>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{isCompleted ? (
|
||||||
|
<DialogClose asChild>
|
||||||
|
<Button type="button" size={"lg"} className="mt-6">
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
</DialogClose>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{!hasStarted && !isCompleted && !isUploading ? (
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
size={"lg"}
|
||||||
|
onClick={isValid ? upload : () => {}}
|
||||||
|
className="mt-6"
|
||||||
|
disabled={!isValid}>
|
||||||
|
Upload
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -285,7 +285,7 @@ const UploadFileItem = ({
|
||||||
failedState?: FailedUppyFile<Record<string, any>, Record<string, any>>;
|
failedState?: FailedUppyFile<Record<string, any>, Record<string, any>>;
|
||||||
onRemove: (id: string) => void;
|
onRemove: (id: string) => void;
|
||||||
}) => {
|
}) => {
|
||||||
console.log({file: file.progress})
|
console.log({ file: file.progress });
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-full py-4 px-2 bg-primary-dark">
|
<div className="flex flex-col w-full py-4 px-2 bg-primary-dark">
|
||||||
<div
|
<div
|
||||||
|
@ -350,7 +350,9 @@ const UploadFileItem = ({
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{file.progress?.preprocess ? <p className="text-sm text-primary-2 ml-2">Processing...</p> : null}
|
{file.progress?.preprocess ? (
|
||||||
|
<p className="text-sm text-primary-2 ml-2">Processing...</p>
|
||||||
|
) : null}
|
||||||
{file.progress?.uploadStarted && !file.progress.uploadComplete ? (
|
{file.progress?.uploadStarted && !file.progress.uploadComplete ? (
|
||||||
<Progress max={100} value={file.progress.percentage} className="mt-2" />
|
<Progress max={100} value={file.progress.percentage} className="mt-2" />
|
||||||
) : null}
|
) : null}
|
||||||
|
|
|
@ -31,6 +31,7 @@ export type Identity = {
|
||||||
firstName: string;
|
firstName: string;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
verified: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdatePasswordFormRequest extends UpdatePasswordFormTypes {
|
export interface UpdatePasswordFormRequest extends UpdatePasswordFormTypes {
|
||||||
|
@ -197,6 +198,7 @@ export const createPortalAuthProvider = (sdk: Sdk): AuthProvider => {
|
||||||
firstName: acct.first_name,
|
firstName: acct.first_name,
|
||||||
lastName: acct.last_name,
|
lastName: acct.last_name,
|
||||||
email: acct.email,
|
email: acct.email,
|
||||||
|
verified: acct.verified,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
||||||
<Meta />
|
<Meta />
|
||||||
<Links />
|
<Links />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body className="max-h-screen">
|
||||||
{children}
|
{children}
|
||||||
<ScrollRestoration />
|
<ScrollRestoration />
|
||||||
<Scripts />
|
<Scripts />
|
||||||
|
|
Loading…
Reference in New Issue