forked from Archives/Athou_commafeed
update to mantine 7
This commit is contained in:
@@ -50,11 +50,11 @@ export function ErrorPage(props: { error: Error }) {
|
||||
<Title className={classes.title}>
|
||||
<Trans>Something bad just happened...</Trans>
|
||||
</Title>
|
||||
<Text size="lg" align="center" className={classes.description}>
|
||||
<Text size="lg" ta="center" className={classes.description}>
|
||||
{props.error.message}
|
||||
</Text>
|
||||
<Group position="center">
|
||||
<Button size="md" onClick={() => window.location.reload()} leftIcon={<TbRefresh size={18} />}>
|
||||
<Group justify="center">
|
||||
<Button size="md" onClick={() => window.location.reload()} leftSection={<TbRefresh size={18} />}>
|
||||
Refresh the page
|
||||
</Button>
|
||||
</Group>
|
||||
|
||||
@@ -14,7 +14,7 @@ export function LoadingPage() {
|
||||
<RingProgress
|
||||
sections={[{ value: loadingPercentage, color: theme.primaryColor }]}
|
||||
label={
|
||||
<Text weight="bold" align="center" size="xl">
|
||||
<Text fw="bold" ta="center" size="xl">
|
||||
{loadingPercentage}%
|
||||
</Text>
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { Anchor, Box, Center, Container, Divider, Group, Image, Title, useMantineColorScheme } from "@mantine/core"
|
||||
import { Anchor, Box, Center, Container, Divider, Group, Image, Space, Title, useMantineColorScheme } from "@mantine/core"
|
||||
import { client } from "app/client"
|
||||
import { redirectToApiDocumentation, redirectToLogin, redirectToRegistration, redirectToRootCategory } from "app/redirect/thunks"
|
||||
import { useAppDispatch, useAppSelector } from "app/store"
|
||||
@@ -31,7 +31,7 @@ export function WelcomePage() {
|
||||
<Container>
|
||||
<Header />
|
||||
|
||||
<Center my="xl">
|
||||
<Center my="lg">
|
||||
<Title order={3}>Bloat-free feed reader</Title>
|
||||
</Center>
|
||||
|
||||
@@ -47,13 +47,15 @@ export function WelcomePage() {
|
||||
</Center>
|
||||
)}
|
||||
|
||||
<Divider my="xl" />
|
||||
<Divider my="lg" />
|
||||
|
||||
<Image src={image} />
|
||||
|
||||
<Divider my="xl" />
|
||||
<Divider my="lg" />
|
||||
|
||||
<Footer />
|
||||
|
||||
<Space h="lg" />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
@@ -73,9 +75,13 @@ function Header() {
|
||||
}
|
||||
|
||||
return (
|
||||
<Group position="apart">
|
||||
<PageTitle />
|
||||
<Buttons />
|
||||
<Group justify="space-between">
|
||||
<Box>
|
||||
<PageTitle />
|
||||
</Box>
|
||||
<Box>
|
||||
<Buttons />
|
||||
</Box>
|
||||
</Group>
|
||||
)
|
||||
}
|
||||
@@ -88,7 +94,7 @@ function Buttons() {
|
||||
const dark = colorScheme === "dark"
|
||||
|
||||
return (
|
||||
<Group spacing={14}>
|
||||
<Group gap={14}>
|
||||
<ActionButton
|
||||
label={<Trans>Log in</Trans>}
|
||||
icon={<TbKey size={iconSize} />}
|
||||
@@ -128,7 +134,7 @@ function Buttons() {
|
||||
function Footer() {
|
||||
const dispatch = useAppDispatch()
|
||||
return (
|
||||
<Group position="apart">
|
||||
<Group justify="space-between">
|
||||
<Group>
|
||||
<span>© CommaFeed</span>
|
||||
<Anchor variant="text" href="https://github.com/Athou/commafeed/" target="_blank" rel="noreferrer">
|
||||
|
||||
@@ -66,7 +66,7 @@ export function AdminUsersPage() {
|
||||
<Title order={3} mb="md">
|
||||
<Group>
|
||||
<Trans>Manage users</Trans>
|
||||
<ActionIcon color={theme.primaryColor} onClick={() => openUserEditModal(<Trans>Add user</Trans>)}>
|
||||
<ActionIcon color={theme.primaryColor} variant="subtle" onClick={() => openUserEditModal(<Trans>Add user</Trans>)}>
|
||||
<TbPlus size={20} />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
@@ -79,69 +79,74 @@ export function AdminUsersPage() {
|
||||
)}
|
||||
|
||||
<Table striped highlightOnHover>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
<Table.Th>
|
||||
<Trans>Id</Trans>
|
||||
</th>
|
||||
<th>
|
||||
</Table.Th>
|
||||
<Table.Th>
|
||||
<Trans>Name</Trans>
|
||||
</th>
|
||||
<th>
|
||||
</Table.Th>
|
||||
<Table.Th>
|
||||
<Trans>E-mail</Trans>
|
||||
</th>
|
||||
<th>
|
||||
</Table.Th>
|
||||
<Table.Th>
|
||||
<Trans>Date created</Trans>
|
||||
</th>
|
||||
<th>
|
||||
</Table.Th>
|
||||
<Table.Th>
|
||||
<Trans>Last login date</Trans>
|
||||
</th>
|
||||
<th>
|
||||
</Table.Th>
|
||||
<Table.Th>
|
||||
<Trans>Admin</Trans>
|
||||
</th>
|
||||
<th>
|
||||
</Table.Th>
|
||||
<Table.Th>
|
||||
<Trans>Enabled</Trans>
|
||||
</th>
|
||||
<th>
|
||||
</Table.Th>
|
||||
<Table.Th>
|
||||
<Trans>Actions</Trans>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</Table.Th>
|
||||
</Table.Tr>
|
||||
</Table.Thead>
|
||||
<Table.Tbody>
|
||||
{users?.map(u => (
|
||||
<tr key={u.id}>
|
||||
<td>{u.id}</td>
|
||||
<td>{u.name}</td>
|
||||
<td>{u.email}</td>
|
||||
<td>
|
||||
<Table.Tr key={u.id}>
|
||||
<Table.Td>{u.id}</Table.Td>
|
||||
<Table.Td>{u.name}</Table.Td>
|
||||
<Table.Td>{u.email}</Table.Td>
|
||||
<Table.Td>
|
||||
<RelativeDate date={u.created} />
|
||||
</td>
|
||||
<td>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<RelativeDate date={u.lastLogin} />
|
||||
</td>
|
||||
<td>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<BooleanIcon value={u.admin} />
|
||||
</td>
|
||||
<td>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<BooleanIcon value={u.enabled} />
|
||||
</td>
|
||||
<td>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Group>
|
||||
<ActionIcon color={theme.primaryColor} onClick={() => openUserEditModal(<Trans>Edit user</Trans>, u)}>
|
||||
<ActionIcon
|
||||
color={theme.primaryColor}
|
||||
variant="subtle"
|
||||
onClick={() => openUserEditModal(<Trans>Edit user</Trans>, u)}
|
||||
>
|
||||
<TbPencil size={18} />
|
||||
</ActionIcon>
|
||||
<ActionIcon
|
||||
color={theme.primaryColor}
|
||||
variant="subtle"
|
||||
onClick={() => openUserDeleteModal(u)}
|
||||
loading={deleteUser.loading}
|
||||
>
|
||||
<TbTrash size={18} />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
</td>
|
||||
</tr>
|
||||
</Table.Td>
|
||||
</Table.Tr>
|
||||
))}
|
||||
</tbody>
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
</Container>
|
||||
)
|
||||
|
||||
@@ -33,10 +33,10 @@ export function MetricsPage() {
|
||||
return (
|
||||
<Tabs defaultValue="stats">
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value="stats" icon={<TbChartAreaLine size={14} />}>
|
||||
<Tabs.Tab value="stats" leftSection={<TbChartAreaLine size={14} />}>
|
||||
Stats
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab value="timers" icon={<TbClock size={14} />}>
|
||||
<Tabs.Tab value="timers" leftSection={<TbClock size={14} />}>
|
||||
Timers
|
||||
</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
|
||||
@@ -67,7 +67,7 @@ export function AboutPage() {
|
||||
|
||||
return (
|
||||
<Container size="xl">
|
||||
<SimpleGrid cols={2} breakpoints={[{ maxWidth: Constants.layout.mobileBreakpoint, cols: 1 }]}>
|
||||
<SimpleGrid cols={{ base: 1, [Constants.layout.mobileBreakpointName]: 2 }}>
|
||||
<Section title={<Trans>About</Trans>} icon={<TbHelp size={24} />}>
|
||||
<Box>
|
||||
<Trans>
|
||||
|
||||
@@ -10,13 +10,13 @@ export function AddPage() {
|
||||
<Container size="sm" px={0}>
|
||||
<Tabs defaultValue="subscribe">
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value="subscribe" icon={<TbRss size={16} />}>
|
||||
<Tabs.Tab value="subscribe" leftSection={<TbRss size={16} />}>
|
||||
<Trans>Subscribe</Trans>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab value="category" icon={<TbFolderPlus size={16} />}>
|
||||
<Tabs.Tab value="category" leftSection={<TbFolderPlus size={16} />}>
|
||||
<Trans>Add category</Trans>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab value="opml" icon={<TbFileImport size={16} />}>
|
||||
<Tabs.Tab value="opml" leftSection={<TbFileImport size={16} />}>
|
||||
<Trans>OPML</Trans>
|
||||
</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
|
||||
@@ -127,13 +127,13 @@ export function CategoryDetailsPage() {
|
||||
</Button>
|
||||
{editable && (
|
||||
<>
|
||||
<Button type="submit" leftIcon={<TbDeviceFloppy size={16} />} loading={modifyCategory.loading}>
|
||||
<Button type="submit" leftSection={<TbDeviceFloppy size={16} />} loading={modifyCategory.loading}>
|
||||
<Trans>Save</Trans>
|
||||
</Button>
|
||||
<Divider orientation="vertical" />
|
||||
<Button
|
||||
color="red"
|
||||
leftIcon={<TbTrash size={16} />}
|
||||
leftSection={<TbTrash size={16} />}
|
||||
onClick={() => openDeleteCategoryModal()}
|
||||
loading={deleteCategory.loading}
|
||||
>
|
||||
|
||||
@@ -166,13 +166,13 @@ export function FeedDetailsPage() {
|
||||
<Button variant="default" onClick={async () => await dispatch(redirectToSelectedSource())}>
|
||||
<Trans>Cancel</Trans>
|
||||
</Button>
|
||||
<Button type="submit" leftIcon={<TbDeviceFloppy size={16} />} loading={modifyFeed.loading}>
|
||||
<Button type="submit" leftSection={<TbDeviceFloppy size={16} />} loading={modifyFeed.loading}>
|
||||
<Trans>Save</Trans>
|
||||
</Button>
|
||||
<Divider orientation="vertical" />
|
||||
<Button
|
||||
color="red"
|
||||
leftIcon={<TbTrash size={16} />}
|
||||
leftSection={<TbTrash size={16} />}
|
||||
onClick={() => openUnsubscribeModal()}
|
||||
loading={unsubscribe.loading}
|
||||
>
|
||||
|
||||
@@ -73,7 +73,7 @@ export function FeedEntriesPage(props: FeedEntriesPageProps) {
|
||||
return (
|
||||
// add some room at the bottom of the page in order to be able to scroll the current entry at the top of the page when expanding
|
||||
<Box mb={viewport.height - Constants.layout.headerHeight - 210}>
|
||||
<Group spacing="xl">
|
||||
<Group gap="xl">
|
||||
{sourceWebsiteUrl && (
|
||||
<a href={sourceWebsiteUrl} target="_blank" rel="noreferrer" className={classes.sourceWebsiteLink}>
|
||||
<Title order={3}>{sourceLabel}</Title>
|
||||
|
||||
@@ -1,88 +1,32 @@
|
||||
import {
|
||||
ActionIcon,
|
||||
AppShell,
|
||||
Box,
|
||||
Burger,
|
||||
Center,
|
||||
DEFAULT_THEME,
|
||||
Group,
|
||||
Header,
|
||||
type MantineTheme,
|
||||
Navbar,
|
||||
ScrollArea,
|
||||
Title,
|
||||
useMantineTheme,
|
||||
} from "@mantine/core"
|
||||
import { Trans } from "@lingui/macro"
|
||||
import { ActionIcon, AppShell, Box, Center, Group, ScrollArea, Title, useMantineTheme } from "@mantine/core"
|
||||
import { Constants } from "app/constants"
|
||||
import { redirectToAdd, redirectToRootCategory } from "app/redirect/thunks"
|
||||
import { useAppDispatch, useAppSelector } from "app/store"
|
||||
import { setMobileMenuOpen, setSidebarWidth } from "app/tree/slice"
|
||||
import { reloadTree } from "app/tree/thunks"
|
||||
import { reloadProfile, reloadSettings, reloadTags } from "app/user/thunks"
|
||||
import { ActionButton } from "components/ActionButton"
|
||||
import { AnnouncementDialog } from "components/AnnouncementDialog"
|
||||
import { Loader } from "components/Loader"
|
||||
import { Logo } from "components/Logo"
|
||||
import { OnDesktop } from "components/responsive/OnDesktop"
|
||||
import { OnMobile } from "components/responsive/OnMobile"
|
||||
import { useAppLoading } from "hooks/useAppLoading"
|
||||
import { useMobile } from "hooks/useMobile"
|
||||
import { useWebSocket } from "hooks/useWebSocket"
|
||||
import { LoadingPage } from "pages/LoadingPage"
|
||||
import { Resizable } from "re-resizable"
|
||||
import { type ReactNode, Suspense, useEffect } from "react"
|
||||
import { TbPlus } from "react-icons/tb"
|
||||
import Draggable from "react-draggable"
|
||||
import { TbMenu2, TbPlus, TbX } from "react-icons/tb"
|
||||
import { Outlet } from "react-router-dom"
|
||||
import { tss } from "tss"
|
||||
|
||||
interface LayoutProps {
|
||||
sidebar: ReactNode
|
||||
sidebarWidth: number
|
||||
sidebarVisible: boolean
|
||||
header: ReactNode
|
||||
}
|
||||
|
||||
const sidebarPadding = DEFAULT_THEME.spacing.xs
|
||||
const sidebarRightBorderWidth = "1px"
|
||||
|
||||
const useStyles = tss
|
||||
.withParams<{
|
||||
theme: MantineTheme
|
||||
sidebarWidth: number
|
||||
}>()
|
||||
.create(({ theme, sidebarWidth }) => ({
|
||||
sidebar: {
|
||||
"& .mantine-ScrollArea-scrollbar[data-orientation='horizontal']": {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
sidebarContentResizeWrapper: {
|
||||
padding: sidebarPadding,
|
||||
minHeight: `calc(100vh - ${Constants.layout.headerHeight}px)`,
|
||||
},
|
||||
sidebarContent: {
|
||||
maxWidth: `calc(${sidebarWidth}px - ${sidebarPadding} * 2 - ${sidebarRightBorderWidth})`,
|
||||
[theme.fn.smallerThan(Constants.layout.mobileBreakpoint)]: {
|
||||
maxWidth: `calc(100vw - ${sidebarPadding} * 2 - ${sidebarRightBorderWidth})`,
|
||||
},
|
||||
},
|
||||
mainContentWrapper: {
|
||||
paddingTop: Constants.layout.headerHeight,
|
||||
paddingLeft: sidebarWidth,
|
||||
paddingRight: 0,
|
||||
paddingBottom: 0,
|
||||
[theme.fn.smallerThan(Constants.layout.mobileBreakpoint)]: {
|
||||
paddingLeft: 0,
|
||||
},
|
||||
},
|
||||
mainContent: {
|
||||
maxWidth: `calc(100vw - ${sidebarWidth}px)`,
|
||||
padding: theme.spacing.md,
|
||||
[theme.fn.smallerThan(Constants.layout.mobileBreakpoint)]: {
|
||||
maxWidth: "100vw",
|
||||
padding: "6px",
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
function LogoAndTitle() {
|
||||
const dispatch = useAppDispatch()
|
||||
return (
|
||||
@@ -97,21 +41,13 @@ function LogoAndTitle() {
|
||||
|
||||
export default function Layout(props: LayoutProps) {
|
||||
const theme = useMantineTheme()
|
||||
const { classes } = useStyles({
|
||||
theme,
|
||||
sidebarWidth: props.sidebarWidth,
|
||||
})
|
||||
const { loading } = useAppLoading()
|
||||
const mobile = useMobile()
|
||||
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
||||
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
||||
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
||||
const sidebarHidden = props.sidebarWidth === 0
|
||||
const dispatch = useAppDispatch()
|
||||
useWebSocket()
|
||||
|
||||
const handleResize = (element: HTMLElement) => dispatch(setSidebarWidth(element.offsetWidth))
|
||||
|
||||
useEffect(() => {
|
||||
// load initial data
|
||||
dispatch(reloadSettings())
|
||||
@@ -132,18 +68,20 @@ export default function Layout(props: LayoutProps) {
|
||||
}, [dispatch, webSocketConnected, treeReloadInterval])
|
||||
|
||||
const burger = (
|
||||
<Center>
|
||||
<Burger
|
||||
color={theme.fn.variant({ color: theme.primaryColor, variant: "subtle" }).color}
|
||||
opened={mobileMenuOpen}
|
||||
onClick={() => dispatch(setMobileMenuOpen(!mobileMenuOpen))}
|
||||
size="sm"
|
||||
/>
|
||||
</Center>
|
||||
<ActionButton
|
||||
label={mobileMenuOpen ? <Trans>Open menu</Trans> : <Trans>Close menu</Trans>}
|
||||
icon={mobileMenuOpen ? <TbX size={18} /> : <TbMenu2 size={18} />}
|
||||
onClick={() => dispatch(setMobileMenuOpen(!mobileMenuOpen))}
|
||||
></ActionButton>
|
||||
)
|
||||
|
||||
const addButton = (
|
||||
<ActionIcon color={theme.primaryColor} onClick={async () => await dispatch(redirectToAdd())} aria-label="Subscribe">
|
||||
<ActionIcon
|
||||
color={theme.primaryColor}
|
||||
variant="subtle"
|
||||
onClick={async () => await dispatch(redirectToAdd())}
|
||||
aria-label="Subscribe"
|
||||
>
|
||||
<TbPlus size={18} />
|
||||
</ActionIcon>
|
||||
)
|
||||
@@ -151,77 +89,80 @@ export default function Layout(props: LayoutProps) {
|
||||
if (loading) return <LoadingPage />
|
||||
return (
|
||||
<AppShell
|
||||
fixed
|
||||
navbarOffsetBreakpoint={Constants.layout.mobileBreakpoint}
|
||||
classNames={{ main: classes.mainContentWrapper }}
|
||||
navbar={
|
||||
<Navbar
|
||||
id="sidebar"
|
||||
hiddenBreakpoint={sidebarHidden ? 99999999 : Constants.layout.mobileBreakpoint}
|
||||
hidden={sidebarHidden || !mobileMenuOpen}
|
||||
width={{ md: props.sidebarWidth }}
|
||||
className={classes.sidebar}
|
||||
>
|
||||
<Navbar.Section grow component={ScrollArea} mx={mobile ? 0 : "-sm"} px={mobile ? 0 : "sm"}>
|
||||
<Resizable
|
||||
enable={{
|
||||
top: false,
|
||||
right: !mobile,
|
||||
bottom: false,
|
||||
left: false,
|
||||
topRight: false,
|
||||
bottomRight: false,
|
||||
bottomLeft: false,
|
||||
topLeft: false,
|
||||
}}
|
||||
onResize={(e, dir, el) => handleResize(el)}
|
||||
minWidth={120}
|
||||
className={classes.sidebarContentResizeWrapper}
|
||||
>
|
||||
<Box className={classes.sidebarContent}>{props.sidebar}</Box>
|
||||
</Resizable>
|
||||
</Navbar.Section>
|
||||
</Navbar>
|
||||
}
|
||||
header={
|
||||
<Header id="header" height={Constants.layout.headerHeight} p="md">
|
||||
<OnMobile>
|
||||
{mobileMenuOpen && (
|
||||
<Group position="apart">
|
||||
<Box>{burger}</Box>
|
||||
<Box>
|
||||
<LogoAndTitle />
|
||||
</Box>
|
||||
<Box>{addButton}</Box>
|
||||
</Group>
|
||||
)}
|
||||
{!mobileMenuOpen && (
|
||||
<Group>
|
||||
<Box>{burger}</Box>
|
||||
<Box sx={{ flexGrow: 1 }}>{props.header}</Box>
|
||||
</Group>
|
||||
)}
|
||||
</OnMobile>
|
||||
<OnDesktop>
|
||||
<Group>
|
||||
<Group position="apart" sx={{ width: props.sidebarWidth - 16 }}>
|
||||
<Box>
|
||||
<LogoAndTitle />
|
||||
</Box>
|
||||
<Box>{addButton}</Box>
|
||||
</Group>
|
||||
<Box sx={{ flexGrow: 1 }}>{props.header}</Box>
|
||||
</Group>
|
||||
</OnDesktop>
|
||||
</Header>
|
||||
}
|
||||
header={{ height: Constants.layout.headerHeight }}
|
||||
navbar={{
|
||||
width: props.sidebarWidth,
|
||||
breakpoint: Constants.layout.mobileBreakpoint,
|
||||
collapsed: { mobile: !mobileMenuOpen, desktop: !props.sidebarVisible },
|
||||
}}
|
||||
padding={{ base: 6, [Constants.layout.mobileBreakpointName]: "md" }}
|
||||
>
|
||||
<Box id="content" className={classes.mainContent}>
|
||||
<AppShell.Header id="header">
|
||||
<OnMobile>
|
||||
{mobileMenuOpen && (
|
||||
<Group justify="space-between" p="md">
|
||||
<Box>{burger}</Box>
|
||||
<Box>
|
||||
<LogoAndTitle />
|
||||
</Box>
|
||||
<Box>{addButton}</Box>
|
||||
</Group>
|
||||
)}
|
||||
{!mobileMenuOpen && (
|
||||
<Group p="md">
|
||||
<Box>{burger}</Box>
|
||||
<Box style={{ flexGrow: 1 }}>{props.header}</Box>
|
||||
</Group>
|
||||
)}
|
||||
</OnMobile>
|
||||
<OnDesktop>
|
||||
<Group p="md">
|
||||
<Group justify="space-between" style={{ width: props.sidebarWidth - 16 }}>
|
||||
<Box>
|
||||
<LogoAndTitle />
|
||||
</Box>
|
||||
<Box>{addButton}</Box>
|
||||
</Group>
|
||||
<Box style={{ flexGrow: 1 }}>{props.header}</Box>
|
||||
</Group>
|
||||
</OnDesktop>
|
||||
</AppShell.Header>
|
||||
<AppShell.Navbar id="sidebar" p="xs">
|
||||
<AppShell.Section grow component={ScrollArea} mx="-sm" px="sm">
|
||||
<Box>{props.sidebar}</Box>
|
||||
</AppShell.Section>
|
||||
</AppShell.Navbar>
|
||||
<Draggable
|
||||
axis="x"
|
||||
defaultPosition={{
|
||||
x: props.sidebarWidth,
|
||||
y: Constants.layout.headerHeight,
|
||||
}}
|
||||
bounds={{
|
||||
left: 120,
|
||||
right: 1000,
|
||||
}}
|
||||
grid={[30, 30]}
|
||||
onDrag={(_e, data) => {
|
||||
dispatch(setSidebarWidth(data.x))
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
position: "fixed",
|
||||
height: "100%",
|
||||
width: "10px",
|
||||
cursor: "ew-resize",
|
||||
}}
|
||||
></Box>
|
||||
</Draggable>
|
||||
|
||||
<AppShell.Main id="content">
|
||||
<Suspense fallback={<Loader />}>
|
||||
<AnnouncementDialog />
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
</Box>
|
||||
</AppShell.Main>
|
||||
</AppShell>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ export function SettingsPage() {
|
||||
<Container size="sm" px={0}>
|
||||
<Tabs defaultValue="display" keepMounted={false}>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value="display" icon={<TbPhoto size={16} />}>
|
||||
<Tabs.Tab value="display" leftSection={<TbPhoto size={16} />}>
|
||||
<Trans>Display</Trans>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab value="customCode" icon={<TbCode size={16} />}>
|
||||
<Tabs.Tab value="customCode" leftSection={<TbCode size={16} />}>
|
||||
<Trans>Custom code</Trans>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab value="profile" icon={<TbUser size={16} />}>
|
||||
<Tabs.Tab value="profile" leftSection={<TbUser size={16} />}>
|
||||
<Trans>Profile</Trans>
|
||||
</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
|
||||
@@ -60,7 +60,7 @@ export function LoginPage() {
|
||||
/>
|
||||
|
||||
{serverInfos?.smtpEnabled && (
|
||||
<Anchor component={Link} to="/passwordRecovery" color="dimmed">
|
||||
<Anchor component={Link} to="/passwordRecovery" c="dimmed">
|
||||
<Trans>Forgot password?</Trans>
|
||||
</Anchor>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user