mirror of
https://github.com/stonith404/pingvin-share.git
synced 2025-02-19 01:55:48 -05:00
refactor: migrate to mantine v5
This commit is contained in:
parent
68ce8af197
commit
db7edc4cd6
14 changed files with 1073 additions and 859 deletions
|
@ -3,7 +3,6 @@
|
|||
const withPWA = require("next-pwa");
|
||||
|
||||
const nextConfig = withPWA({
|
||||
reactStrictMode: true,
|
||||
pwa: {
|
||||
dest: "public",
|
||||
disable: process.env.NODE_ENV == "development"
|
||||
|
|
1543
frontend/package-lock.json
generated
1543
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -9,13 +9,13 @@
|
|||
"format": "prettier --write \"src/**/*.ts\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@mantine/core": "^4.2.0",
|
||||
"@mantine/dropzone": "^4.2.0",
|
||||
"@mantine/form": "^4.2.0",
|
||||
"@mantine/hooks": "^4.2.0",
|
||||
"@mantine/modals": "^4.2.0",
|
||||
"@mantine/next": "^4.2.0",
|
||||
"@mantine/notifications": "^4.2.0",
|
||||
"@mantine/core": "^5.5.2",
|
||||
"@mantine/dropzone": "^5.5.2",
|
||||
"@mantine/form": "^5.5.2",
|
||||
"@mantine/hooks": "^5.5.2",
|
||||
"@mantine/modals": "^5.5.2",
|
||||
"@mantine/next": "^5.5.2",
|
||||
"@mantine/notifications": "^5.5.2",
|
||||
"axios": "^0.26.1",
|
||||
"cookies-next": "^2.0.4",
|
||||
"file-saver": "^2.0.5",
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
Title,
|
||||
} from "@mantine/core";
|
||||
import { useForm, yupResolver } from "@mantine/form";
|
||||
import { NextLink } from "@mantine/next";
|
||||
import getConfig from "next/config";
|
||||
import * as yup from "yup";
|
||||
import authService from "../../services/auth.service";
|
||||
|
@ -27,7 +28,7 @@ const AuthForm = ({ mode }: { mode: "signUp" | "signIn" }) => {
|
|||
email: "",
|
||||
password: "",
|
||||
},
|
||||
schema: yupResolver(validationSchema),
|
||||
validate: yupResolver(validationSchema),
|
||||
});
|
||||
|
||||
const signIn = (email: string, password: string) => {
|
||||
|
@ -59,7 +60,11 @@ const AuthForm = ({ mode }: { mode: "signUp" | "signIn" }) => {
|
|||
{mode == "signUp"
|
||||
? "You have an account already?"
|
||||
: "You don't have an account yet?"}{" "}
|
||||
<Anchor href={mode == "signUp" ? "signIn" : "signUp"} size="sm">
|
||||
<Anchor
|
||||
component={NextLink}
|
||||
href={mode == "signUp" ? "signIn" : "signUp"}
|
||||
size="sm"
|
||||
>
|
||||
{mode == "signUp" ? "Sign in" : "Sign up"}
|
||||
</Anchor>
|
||||
</Text>
|
||||
|
|
|
@ -6,40 +6,34 @@ import ToggleThemeButton from "./ToggleThemeButton";
|
|||
|
||||
const ActionAvatar = () => {
|
||||
return (
|
||||
<Menu
|
||||
control={
|
||||
<Menu>
|
||||
<Menu.Target>
|
||||
<ActionIcon>
|
||||
<Avatar size={28} radius="xl" />
|
||||
</ActionIcon>
|
||||
}
|
||||
>
|
||||
<Menu.Label>My account</Menu.Label>
|
||||
<Menu.Item
|
||||
component={NextLink}
|
||||
href="/account/shares"
|
||||
icon={<Link size={14} />}
|
||||
>
|
||||
Shares
|
||||
</Menu.Item>
|
||||
{/* <Menu.Item
|
||||
component={NextLink}
|
||||
href="/account/shares"
|
||||
icon={<Settings size={14} />}
|
||||
>
|
||||
Settings
|
||||
</Menu.Item> */}
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
await authService.signOut();
|
||||
}}
|
||||
icon={<DoorExit size={14} />}
|
||||
>
|
||||
Sign out
|
||||
</Menu.Item>
|
||||
<Menu.Label>Settings</Menu.Label>
|
||||
<Menu.Item icon={<Moon size={14} />}>
|
||||
<ToggleThemeButton />
|
||||
</Menu.Item>
|
||||
</Menu.Target>
|
||||
<Menu.Dropdown>
|
||||
<Menu.Label>My account</Menu.Label>
|
||||
<Menu.Item
|
||||
component={NextLink}
|
||||
href="/account/shares"
|
||||
icon={<Link size={14} />}
|
||||
>
|
||||
Shares
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
authService.signOut();
|
||||
}}
|
||||
icon={<DoorExit size={14} />}
|
||||
>
|
||||
Sign out
|
||||
</Menu.Item>
|
||||
<Menu.Label>Settings</Menu.Label>
|
||||
<Menu.Item icon={<Moon size={14} />}>
|
||||
<ToggleThemeButton />
|
||||
</Menu.Item>
|
||||
</Menu.Dropdown>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,23 +1,26 @@
|
|||
import {
|
||||
Burger,
|
||||
Container,
|
||||
createStyles,
|
||||
Group,
|
||||
Header as MantineHeader,
|
||||
Header,
|
||||
Image,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
Transition,
|
||||
} from "@mantine/core";
|
||||
import { useBooleanToggle } from "@mantine/hooks";
|
||||
import { useDisclosure } from "@mantine/hooks";
|
||||
import { NextLink } from "@mantine/next";
|
||||
import getConfig from "next/config";
|
||||
import Image from "next/image";
|
||||
import { ReactNode, useEffect, useState } from "react";
|
||||
import useUser from "../../hooks/user.hook";
|
||||
import headerStyle from "../../styles/header.style";
|
||||
import ActionAvatar from "./ActionAvatar";
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
const HEADER_HEIGHT = 60;
|
||||
|
||||
type Link = {
|
||||
link?: string;
|
||||
label?: string;
|
||||
|
@ -25,14 +28,90 @@ type Link = {
|
|||
action?: () => Promise<void>;
|
||||
};
|
||||
|
||||
const Header = () => {
|
||||
const [opened, toggleOpened] = useBooleanToggle(false);
|
||||
const [active, setActive] = useState<string>();
|
||||
const useStyles = createStyles((theme) => ({
|
||||
root: {
|
||||
position: "relative",
|
||||
zIndex: 1,
|
||||
},
|
||||
|
||||
dropdown: {
|
||||
position: "absolute",
|
||||
top: HEADER_HEIGHT,
|
||||
left: 0,
|
||||
right: 0,
|
||||
zIndex: 0,
|
||||
borderTopRightRadius: 0,
|
||||
borderTopLeftRadius: 0,
|
||||
borderTopWidth: 0,
|
||||
overflow: "hidden",
|
||||
|
||||
[theme.fn.largerThan("sm")]: {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
|
||||
header: {
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: "100%",
|
||||
},
|
||||
|
||||
links: {
|
||||
[theme.fn.smallerThan("sm")]: {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
|
||||
burger: {
|
||||
[theme.fn.largerThan("sm")]: {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
|
||||
link: {
|
||||
display: "block",
|
||||
lineHeight: 1,
|
||||
padding: "8px 12px",
|
||||
borderRadius: theme.radius.sm,
|
||||
textDecoration: "none",
|
||||
color:
|
||||
theme.colorScheme === "dark"
|
||||
? theme.colors.dark[0]
|
||||
: theme.colors.gray[7],
|
||||
fontSize: theme.fontSizes.sm,
|
||||
fontWeight: 500,
|
||||
|
||||
"&:hover": {
|
||||
backgroundColor:
|
||||
theme.colorScheme === "dark"
|
||||
? theme.colors.dark[6]
|
||||
: theme.colors.gray[0],
|
||||
},
|
||||
|
||||
[theme.fn.smallerThan("sm")]: {
|
||||
borderRadius: 0,
|
||||
padding: theme.spacing.md,
|
||||
},
|
||||
},
|
||||
|
||||
linkActive: {
|
||||
"&, &:hover": {
|
||||
backgroundColor:
|
||||
theme.colorScheme === "dark"
|
||||
? theme.fn.rgba(theme.colors[theme.primaryColor][9], 0.25)
|
||||
: theme.colors[theme.primaryColor][0],
|
||||
color:
|
||||
theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 3 : 7],
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const NavBar = () => {
|
||||
const user = useUser();
|
||||
const [opened, toggleOpened] = useDisclosure(false);
|
||||
|
||||
const { classes, cx } = headerStyle();
|
||||
|
||||
const authenticatedLinks: Link[] = [
|
||||
const [authenticatedLinks, setAuthenticatedLinks] = useState<Link[]>([
|
||||
{
|
||||
link: "/upload",
|
||||
label: "Upload",
|
||||
|
@ -40,61 +119,66 @@ const Header = () => {
|
|||
{
|
||||
component: <ActionAvatar />,
|
||||
},
|
||||
];
|
||||
]);
|
||||
|
||||
const unauthenticatedLinks: Link[] | undefined = [
|
||||
const [unauthenticatedLinks, setUnauthenticatedLinks] = useState<Link[]>([
|
||||
{
|
||||
link: "/auth/signIn",
|
||||
label: "Sign in",
|
||||
},
|
||||
];
|
||||
]);
|
||||
|
||||
if (publicRuntimeConfig.SHOW_HOME_PAGE == "true")
|
||||
unauthenticatedLinks.unshift({
|
||||
link: "/",
|
||||
label: "Home",
|
||||
});
|
||||
useEffect(() => {
|
||||
if (publicRuntimeConfig.SHOW_HOME_PAGE == "true")
|
||||
setUnauthenticatedLinks((array) => [
|
||||
{
|
||||
link: "/",
|
||||
label: "Home",
|
||||
},
|
||||
...array,
|
||||
]);
|
||||
|
||||
if (publicRuntimeConfig.ALLOW_REGISTRATION == "true")
|
||||
unauthenticatedLinks.push({
|
||||
link: "/auth/signUp",
|
||||
label: "Sign up",
|
||||
});
|
||||
if (publicRuntimeConfig.ALLOW_REGISTRATION == "true")
|
||||
setUnauthenticatedLinks((array) => [
|
||||
...array,
|
||||
{
|
||||
link: "/auth/signUp",
|
||||
label: "Sign up",
|
||||
},
|
||||
]);
|
||||
}, []);
|
||||
|
||||
const links = user ? authenticatedLinks : unauthenticatedLinks;
|
||||
|
||||
const items = links.map((link, i) => {
|
||||
if (link.component) {
|
||||
return (
|
||||
<Container key={i} pl={5} py={15}>
|
||||
{link.component}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
if (link) {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
useEffect(() => {
|
||||
if (window.location.pathname == link.link) {
|
||||
setActive(link.link);
|
||||
const { classes, cx } = useStyles();
|
||||
console.log(user);
|
||||
const items = (
|
||||
<>
|
||||
{(user ? authenticatedLinks : unauthenticatedLinks).map((link) => {
|
||||
if (link.component) {
|
||||
return (
|
||||
<>
|
||||
<Container pl={5} py={15}>
|
||||
{link.component}
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
return (
|
||||
<NextLink
|
||||
key={link.label}
|
||||
href={link.link ?? ""}
|
||||
onClick={link.action}
|
||||
className={cx(classes.link, {
|
||||
[classes.linkActive]: link.link && active === link.link,
|
||||
})}
|
||||
>
|
||||
{link.label}
|
||||
</NextLink>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<NextLink
|
||||
key={link.label}
|
||||
href={link.link ?? ""}
|
||||
onClick={() => toggleOpened.toggle()}
|
||||
className={cx(classes.link, {
|
||||
[classes.linkActive]: window.location.pathname == link.link,
|
||||
})}
|
||||
>
|
||||
{link.label}
|
||||
</NextLink>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<MantineHeader height={60} mb={20} className={classes.root}>
|
||||
<Header height={HEADER_HEIGHT} mb={40} className={classes.root}>
|
||||
<Container className={classes.header}>
|
||||
<NextLink href="/">
|
||||
<Group>
|
||||
|
@ -108,24 +192,24 @@ const Header = () => {
|
|||
</Group>
|
||||
</NextLink>
|
||||
<Group spacing={5} className={classes.links}>
|
||||
{items}
|
||||
<Group>{items} </Group>
|
||||
</Group>
|
||||
<Burger
|
||||
opened={opened}
|
||||
onClick={() => toggleOpened()}
|
||||
onClick={() => toggleOpened.toggle()}
|
||||
className={classes.burger}
|
||||
size="sm"
|
||||
/>
|
||||
|
||||
<Transition transition="pop-top-right" duration={200} mounted={opened}>
|
||||
{(styles) => (
|
||||
<Paper className={classes.dropdown} withBorder style={styles}>
|
||||
{items}
|
||||
<Stack spacing={0}> {items}</Stack>
|
||||
</Paper>
|
||||
)}
|
||||
</Transition>
|
||||
</Container>
|
||||
</MantineHeader>
|
||||
</Header>
|
||||
);
|
||||
};
|
||||
export default Header;
|
||||
|
||||
export default NavBar;
|
||||
|
|
|
@ -3,10 +3,10 @@ import {
|
|||
Button,
|
||||
Col,
|
||||
Grid,
|
||||
Group,
|
||||
NumberInput,
|
||||
PasswordInput,
|
||||
Select,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
} from "@mantine/core";
|
||||
|
@ -46,7 +46,7 @@ const CreateUploadModalBody = ({
|
|||
maxViews: undefined,
|
||||
expiration: "1-day",
|
||||
},
|
||||
schema: yupResolver(validationSchema),
|
||||
validate: yupResolver(validationSchema),
|
||||
});
|
||||
|
||||
return (
|
||||
|
@ -63,7 +63,7 @@ const CreateUploadModalBody = ({
|
|||
}
|
||||
})}
|
||||
>
|
||||
<Group direction="column" grow>
|
||||
<Stack align="stretch">
|
||||
<Grid align={form.errors.link ? "center" : "flex-end"}>
|
||||
<Col xs={9}>
|
||||
<TextInput
|
||||
|
@ -115,10 +115,10 @@ const CreateUploadModalBody = ({
|
|||
/>
|
||||
<Accordion>
|
||||
<Accordion.Item
|
||||
label="Security options"
|
||||
value="Security options"
|
||||
sx={{ borderBottom: "none" }}
|
||||
>
|
||||
<Group direction="column" grow>
|
||||
<Stack align="stretch">
|
||||
<PasswordInput
|
||||
variant="filled"
|
||||
placeholder="No password"
|
||||
|
@ -134,11 +134,11 @@ const CreateUploadModalBody = ({
|
|||
label="Maximal views"
|
||||
{...form.getInputProps("maxViews")}
|
||||
/>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Accordion.Item>
|
||||
</Accordion>
|
||||
<Button type="submit">Share</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -19,10 +19,13 @@ const DownloadAllButton = ({ shareId }: { shareId: string }) => {
|
|||
.catch(() => {});
|
||||
|
||||
const timer = setInterval(() => {
|
||||
shareService.getMetaData(shareId).then((share) => {
|
||||
setIsZipReady(share.isZipReady);
|
||||
if (share.isZipReady) clearInterval(timer);
|
||||
}).catch(() => {});
|
||||
shareService
|
||||
.getMetaData(shareId)
|
||||
.then((share) => {
|
||||
setIsZipReady(share.isZipReady);
|
||||
if (share.isZipReady) clearInterval(timer);
|
||||
})
|
||||
.catch(() => {});
|
||||
}, 5000);
|
||||
return () => {
|
||||
clearInterval(timer);
|
||||
|
@ -32,7 +35,6 @@ const DownloadAllButton = ({ shareId }: { shareId: string }) => {
|
|||
if (!isZipReady)
|
||||
return (
|
||||
<Tooltip
|
||||
wrapLines
|
||||
position="bottom"
|
||||
width={220}
|
||||
withArrow
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { ActionIcon, Loader, Skeleton, Table } from "@mantine/core";
|
||||
import { useRouter } from "next/router";
|
||||
import { CircleCheck, Download } from "tabler-icons-react";
|
||||
import shareService from "../../services/share.service";
|
||||
|
||||
|
@ -14,8 +13,6 @@ const FileList = ({
|
|||
shareId: string;
|
||||
isLoading: boolean;
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
|
||||
const skeletonRows = [...Array(5)].map((c, i) => (
|
||||
<tr key={i}>
|
||||
<td>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Button, Group, PasswordInput, Text, Title } from "@mantine/core";
|
||||
import { Button, Group, PasswordInput, Stack, Text, Title } from "@mantine/core";
|
||||
import { ModalsContextProps } from "@mantine/modals/lib/context";
|
||||
import { useState } from "react";
|
||||
|
||||
|
@ -27,7 +27,7 @@ const Body = ({ submitCallback }: { submitCallback: any }) => {
|
|||
const [passwordWrong, setPasswordWrong] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Group grow direction="column">
|
||||
<Stack align="stretch">
|
||||
<PasswordInput
|
||||
variant="filled"
|
||||
placeholder="Password"
|
||||
|
@ -50,7 +50,7 @@ const Body = ({ submitCallback }: { submitCallback: any }) => {
|
|||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Button, Group, Text, Title } from "@mantine/core";
|
||||
import { Button, Group, Stack, Text, Title } from "@mantine/core";
|
||||
import { useModals } from "@mantine/modals";
|
||||
import { ModalsContextProps } from "@mantine/modals/lib/context";
|
||||
import { useRouter } from "next/router";
|
||||
|
@ -23,7 +23,7 @@ const Body = ({ text }: { text: string }) => {
|
|||
const router = useRouter();
|
||||
return (
|
||||
<>
|
||||
<Group grow direction="column">
|
||||
<Stack align="stretch">
|
||||
<Text size="sm">{text}</Text>
|
||||
<Button
|
||||
onClick={() => {
|
||||
|
@ -33,7 +33,7 @@ const Body = ({ text }: { text: string }) => {
|
|||
>
|
||||
Go back
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -3,17 +3,17 @@ import {
|
|||
Center,
|
||||
createStyles,
|
||||
Group,
|
||||
MantineTheme,
|
||||
Text,
|
||||
useMantineTheme,
|
||||
} from "@mantine/core";
|
||||
import { Dropzone as MantineDropzone, DropzoneStatus } from "@mantine/dropzone";
|
||||
import { Dropzone as MantineDropzone } from "@mantine/dropzone";
|
||||
import getConfig from "next/config";
|
||||
import React, { Dispatch, ForwardedRef, SetStateAction, useRef } from "react";
|
||||
import { Dispatch, ForwardedRef, SetStateAction, useRef } from "react";
|
||||
import { CloudUpload, Upload } from "tabler-icons-react";
|
||||
import { byteStringToHumanSizeString } from "../../utils/math/byteStringToHumanSizeString.util";
|
||||
import toast from "../../utils/toast.util";
|
||||
|
||||
const { publicRuntimeConfig } = getConfig()
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
const useStyles = createStyles((theme) => ({
|
||||
wrapper: {
|
||||
|
@ -39,14 +39,6 @@ const useStyles = createStyles((theme) => ({
|
|||
},
|
||||
}));
|
||||
|
||||
function getActiveColor(status: DropzoneStatus, theme: MantineTheme) {
|
||||
return status.accepted
|
||||
? theme.colors[theme.primaryColor][6]
|
||||
: theme.colorScheme === "dark"
|
||||
? theme.colors.dark[2]
|
||||
: theme.black;
|
||||
}
|
||||
|
||||
const Dropzone = ({
|
||||
isUploading,
|
||||
setFiles,
|
||||
|
@ -76,26 +68,20 @@ const Dropzone = ({
|
|||
className={classes.dropzone}
|
||||
radius="md"
|
||||
>
|
||||
{(status) => (
|
||||
<div style={{ pointerEvents: "none" }}>
|
||||
<Group position="center">
|
||||
<CloudUpload size={50} color={getActiveColor(status, theme)} />
|
||||
</Group>
|
||||
<Text
|
||||
align="center"
|
||||
weight={700}
|
||||
size="lg"
|
||||
mt="xl"
|
||||
sx={{ color: getActiveColor(status, theme) }}
|
||||
>
|
||||
{status.accepted ? "Drop files here" : "Upload files"}
|
||||
</Text>
|
||||
<Text align="center" size="sm" mt="xs" color="dimmed">
|
||||
Drag and drop your files or use the upload button to start your
|
||||
share.
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
<div style={{ pointerEvents: "none" }}>
|
||||
<Group position="center">
|
||||
<CloudUpload size={50} />
|
||||
</Group>
|
||||
<Text align="center" weight={700} size="lg" mt="xl">
|
||||
Upload files
|
||||
</Text>
|
||||
<Text align="center" size="sm" mt="xs" color="dimmed">
|
||||
Drag'n'drop files here to start your share. We can accept
|
||||
only files that are less than{" "}
|
||||
{byteStringToHumanSizeString(publicRuntimeConfig.MAX_FILE_SIZE)} in
|
||||
size.
|
||||
</Text>
|
||||
</div>
|
||||
</MantineDropzone>
|
||||
<Center>
|
||||
<Button
|
||||
|
|
|
@ -2,9 +2,10 @@ import {
|
|||
ActionIcon,
|
||||
Button,
|
||||
Group,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
Title
|
||||
} from "@mantine/core";
|
||||
import { useClipboard } from "@mantine/hooks";
|
||||
import { useModals } from "@mantine/modals";
|
||||
|
@ -24,9 +25,9 @@ const showCompletedUploadModal = (
|
|||
withCloseButton: false,
|
||||
closeOnEscape: false,
|
||||
title: (
|
||||
<Group grow direction="column" spacing={0}>
|
||||
<Stack align="stretch" spacing={0}>
|
||||
<Title order={4}>Share ready</Title>
|
||||
</Group>
|
||||
</Stack>
|
||||
),
|
||||
children: <Body share={share} />,
|
||||
});
|
||||
|
@ -38,7 +39,7 @@ const Body = ({ share }: { share: Share }) => {
|
|||
const router = useRouter();
|
||||
const link = `${window.location.origin}/share/${share.id}`;
|
||||
return (
|
||||
<Group grow direction="column">
|
||||
<Stack align="stretch">
|
||||
<TextInput
|
||||
variant="filled"
|
||||
value={link}
|
||||
|
@ -70,7 +71,7 @@ const Body = ({ share }: { share: Share }) => {
|
|||
>
|
||||
Done
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ const signUp = async (email: string, password: string) => {
|
|||
|
||||
const signOut = () => {
|
||||
setCookies("access_token", null);
|
||||
setCookies("refresh_token", null);
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue