[DEV] correct models
This commit is contained in:
parent
44b4fa37d3
commit
332c65360d
@ -1,6 +0,0 @@
|
||||
{
|
||||
"display": "2025-02-09",
|
||||
"version": "0.0.1-dev\n - 2025-02-09T21:15:14+01:00",
|
||||
"commit": "0.0.1-dev\n",
|
||||
"date": "2025-02-09T21:15:14+01:00"
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
const dayjs = require('dayjs');
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
const generateAppBuild = () => {
|
||||
const getVersion = () => fs.readFileSync('version.txt', 'utf8');
|
||||
|
||||
const commit = process.env.VERCEL_GIT_COMMIT_SHA
|
||||
? process.env.VERCEL_GIT_COMMIT_SHA
|
||||
: getVersion();
|
||||
|
||||
const appBuildContent = {
|
||||
display: `${dayjs().format('YYYY-MM-DD')}`,
|
||||
version: `${commit} - ${dayjs().format()}`,
|
||||
commit,
|
||||
date: dayjs().format(),
|
||||
};
|
||||
|
||||
fs.writeFileSync(
|
||||
'./app-build.json',
|
||||
JSON.stringify(appBuildContent, null, 2)
|
||||
);
|
||||
};
|
||||
|
||||
generateAppBuild();
|
@ -7,11 +7,6 @@ const config: KnipConfig = {
|
||||
// Related to tests
|
||||
'tests/**',
|
||||
'**.conf.js',
|
||||
'steps.d.ts',
|
||||
'steps_file.js',
|
||||
'env_ci/codecept.conf.js',
|
||||
// Generic components are useful.
|
||||
'src/components/**',
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest watch",
|
||||
"build": "tsc && vite build",
|
||||
"static:build": "node build.js && pnpm build",
|
||||
"static:build": "pnpm build",
|
||||
"dev": "vite",
|
||||
"pretty": "prettier -w .",
|
||||
"lint": "pnpm tsc --noEmit",
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { EnvDevelopment } from './components/EnvDevelopment/EnvDevelopment';
|
||||
|
||||
import { ErrorBoundary } from '@/errors/ErrorBoundary';
|
||||
import { AppRoutes } from '@/scene/AppRoutes';
|
||||
import { ServiceContextProvider } from '@/service/ServiceContext';
|
||||
|
||||
import { EnvDevelopment } from './components/EnvDevelopment/EnvDevelopment';
|
||||
|
||||
export const App = () => {
|
||||
return (
|
||||
<ServiceContextProvider>
|
||||
|
@ -3,13 +3,14 @@ import { ReactElement, useEffect, useState } from 'react';
|
||||
import { Box, BoxProps, Flex, FlexProps } from '@chakra-ui/react';
|
||||
import { Image } from '@chakra-ui/react';
|
||||
|
||||
import { DataUrlAccess } from '@/utils/data-url-access';
|
||||
import { Icon } from './Icon';
|
||||
import { ObjectId } from '@/back-api';
|
||||
import { DataUrlAccess } from '@/utils/data-url-access';
|
||||
|
||||
export type CoversProps = Omit<BoxProps, "iconEmpty"> & {
|
||||
import { Icon } from './Icon';
|
||||
|
||||
export type CoversProps = Omit<BoxProps, 'iconEmpty'> & {
|
||||
data?: ObjectId[];
|
||||
size?: BoxProps["width"];
|
||||
size?: BoxProps['width'];
|
||||
iconEmpty?: ReactElement;
|
||||
slideshow?: boolean;
|
||||
};
|
||||
@ -33,7 +34,9 @@ export const Covers = ({
|
||||
setPreviousImageIndex(currentImageIndex);
|
||||
setTopOpacity(0.0);
|
||||
setTimeout(() => {
|
||||
setCurrentImageIndex((prevIndex) => (prevIndex + 1) % (data?.length ?? 1));
|
||||
setCurrentImageIndex(
|
||||
(prevIndex) => (prevIndex + 1) % (data?.length ?? 1)
|
||||
);
|
||||
setTopOpacity(1.0);
|
||||
}, 1500);
|
||||
}, 3000);
|
||||
@ -60,17 +63,26 @@ export const Covers = ({
|
||||
}
|
||||
if (slideshow === false || data.length === 1) {
|
||||
const url = DataUrlAccess.getThumbnailUrl(data[0]);
|
||||
return <Image loading="lazy" src={url} maxWidth={size} boxSize={size} /*{...rest}*/ />;
|
||||
return (
|
||||
<Image
|
||||
loading="lazy"
|
||||
src={url}
|
||||
maxWidth={size}
|
||||
boxSize={size} /*{...rest}*/
|
||||
/>
|
||||
);
|
||||
}
|
||||
const urlCurrent = DataUrlAccess.getThumbnailUrl(data[currentImageIndex]);
|
||||
const urlPrevious = DataUrlAccess.getThumbnailUrl(data[previousImageIndex]);
|
||||
return <Flex
|
||||
return (
|
||||
<Flex
|
||||
position="relative"
|
||||
// {...rest}
|
||||
maxWidth={size}
|
||||
width={size}
|
||||
height={size}
|
||||
overflow="hidden">
|
||||
overflow="hidden"
|
||||
>
|
||||
<Image
|
||||
src={urlPrevious}
|
||||
loading="lazy"
|
||||
@ -96,4 +108,5 @@ export const Covers = ({
|
||||
zIndex={2}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@ -1,26 +1,25 @@
|
||||
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
createListCollection,
|
||||
Dialog,
|
||||
Select,
|
||||
Span,
|
||||
Stack,
|
||||
Text,
|
||||
createListCollection,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
import { useSessionService } from '@/service/session';
|
||||
import { useLogin } from '@/scene/connection/useLogin';
|
||||
import { useSessionService } from '@/service/session';
|
||||
|
||||
export const USERS_COLLECTION = createListCollection({
|
||||
items: [
|
||||
{ label: "karadmin", value: "adminA@666" },
|
||||
{ label: "karuser", value: "userA@666" },
|
||||
{ label: "NO_USER", value: "" },
|
||||
{ label: 'karadmin', value: 'adminA@666' },
|
||||
{ label: 'karuser', value: 'userA@666' },
|
||||
{ label: 'NO_USER', value: '' },
|
||||
],
|
||||
})
|
||||
});
|
||||
|
||||
export const EnvDevelopment = () => {
|
||||
const dialog = useDisclosure();
|
||||
@ -86,14 +85,23 @@ export const EnvDevelopment = () => {
|
||||
<Dialog.Header>Development tools</Dialog.Header>
|
||||
<Dialog.Body>
|
||||
<Stack>
|
||||
<Text>User <Span color="red" fontWeight="bold">{lastError}</Span></Text>
|
||||
<Text>
|
||||
User{' '}
|
||||
<Span color="red" fontWeight="bold">
|
||||
{lastError}
|
||||
</Span>
|
||||
</Text>
|
||||
<Select.Root collection={USERS_COLLECTION}>
|
||||
<Select.Trigger>
|
||||
<Select.ValueText placeholder="Select test user" />
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
{USERS_COLLECTION.items.map((value) => (
|
||||
<Select.Item item={value} key={value.value}onClick={()=>handleChange(value.label, value.value)} >
|
||||
<Select.Item
|
||||
item={value}
|
||||
key={value.value}
|
||||
onClick={() => handleChange(value.label, value.value)}
|
||||
>
|
||||
{value.label}
|
||||
</Select.Item>
|
||||
))}
|
||||
@ -110,4 +118,3 @@ export const EnvDevelopment = () => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
FlexProps,
|
||||
} from '@chakra-ui/react';
|
||||
import { forwardRef, ReactNode } from 'react';
|
||||
import { ReactNode, forwardRef } from 'react';
|
||||
|
||||
import { Box, Flex, FlexProps } from '@chakra-ui/react';
|
||||
|
||||
export type IconProps = FlexProps & {
|
||||
children: ReactNode;
|
||||
@ -14,7 +11,8 @@ export type IconProps = FlexProps & {
|
||||
export const Icon = forwardRef<HTMLDivElement, IconProps>(
|
||||
({ children, color, sizeIcon = '1em', ...rest }, ref) => {
|
||||
return (
|
||||
<Flex flex="none"
|
||||
<Flex
|
||||
flex="none"
|
||||
minWidth={sizeIcon}
|
||||
minHeight={sizeIcon}
|
||||
maxWidth={sizeIcon}
|
||||
@ -22,7 +20,8 @@ export const Icon = forwardRef<HTMLDivElement, IconProps>(
|
||||
align="center"
|
||||
padding="1px"
|
||||
ref={ref}
|
||||
{...rest}>
|
||||
{...rest}
|
||||
>
|
||||
<Box
|
||||
marginX="auto"
|
||||
width="100%"
|
||||
|
@ -4,8 +4,8 @@ import { Flex, FlexProps } from '@chakra-ui/react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { PageLayout } from '@/components/Layout/PageLayout';
|
||||
import { colors } from '@/theme/colors';
|
||||
import { useColorModeValue } from '@/components/ui/color-mode';
|
||||
import { colors } from '@/theme/colors';
|
||||
|
||||
export type LayoutProps = FlexProps & {
|
||||
children: ReactNode;
|
||||
|
@ -1,22 +1,20 @@
|
||||
|
||||
export {
|
||||
ParameterLayoutContent as Content,
|
||||
type ParameterLayoutContentProps as ContentProps
|
||||
type ParameterLayoutContentProps as ContentProps,
|
||||
} from './ParameterLayoutContent';
|
||||
export {
|
||||
ParameterLayoutFooter as Footer,
|
||||
type ParameterLayoutFooterProps as FooterProps
|
||||
type ParameterLayoutFooterProps as FooterProps,
|
||||
} from './ParameterLayoutFooter';
|
||||
export {
|
||||
ParameterLayoutHeader as Header,
|
||||
type ParameterLayoutHeaderProps as HeaderProps
|
||||
type ParameterLayoutHeaderProps as HeaderProps,
|
||||
} from './ParameterLayoutHeader';
|
||||
export {
|
||||
ParameterLayoutHeaderBase as HeaderBase,
|
||||
type ParameterLayoutHeaderBaseProps as HeaderBaseProps
|
||||
type ParameterLayoutHeaderBaseProps as HeaderBaseProps,
|
||||
} from './ParameterLayoutHeaderBase';
|
||||
export {
|
||||
ParameterLayoutRoot as Root,
|
||||
type ParameterLayoutRootProps as RootProps
|
||||
type ParameterLayoutRootProps as RootProps,
|
||||
} from './ParameterLayoutRoot';
|
||||
|
||||
|
@ -1,19 +1,25 @@
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { ReactNode } from "react";
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
|
||||
export type ParameterLayoutContentProps = {
|
||||
children?: ReactNode;
|
||||
}
|
||||
};
|
||||
|
||||
export const ParameterLayoutContent = ({children}:ParameterLayoutContentProps) => {
|
||||
return <Flex
|
||||
export const ParameterLayoutContent = ({
|
||||
children,
|
||||
}: ParameterLayoutContentProps) => {
|
||||
return (
|
||||
<Flex
|
||||
direction="column"
|
||||
width="full"
|
||||
borderY="1px solid black"
|
||||
paddingY="15px"
|
||||
paddingX="25px"
|
||||
minHeight="10px"
|
||||
background="gray.700">
|
||||
background="gray.700"
|
||||
>
|
||||
{children}
|
||||
</Flex>
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -1,16 +1,17 @@
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { ReactNode } from "react";
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
|
||||
export type ParameterLayoutFooterProps = {
|
||||
children?: ReactNode;
|
||||
}
|
||||
};
|
||||
|
||||
export const ParameterLayoutFooter = ({children}:ParameterLayoutFooterProps) => {
|
||||
return <Flex
|
||||
width="full"
|
||||
paddingY="15px"
|
||||
paddingX="25px"
|
||||
minHeight="10px">
|
||||
export const ParameterLayoutFooter = ({
|
||||
children,
|
||||
}: ParameterLayoutFooterProps) => {
|
||||
return (
|
||||
<Flex width="full" paddingY="15px" paddingX="25px" minHeight="10px">
|
||||
{children}
|
||||
</Flex>
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { ReactNode } from "react";
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
|
||||
export type ParameterLayoutHeaderProps = {
|
||||
children?: ReactNode;
|
||||
}
|
||||
};
|
||||
|
||||
export const ParameterLayoutHeader = ({children}:ParameterLayoutHeaderProps) => {
|
||||
return <Flex
|
||||
width="full"
|
||||
paddingY="15px"
|
||||
paddingX="25px"
|
||||
minHeight="10px"
|
||||
>
|
||||
export const ParameterLayoutHeader = ({
|
||||
children,
|
||||
}: ParameterLayoutHeaderProps) => {
|
||||
return (
|
||||
<Flex width="full" paddingY="15px" paddingX="25px" minHeight="10px">
|
||||
{children}
|
||||
</Flex>
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -1,23 +1,24 @@
|
||||
import { Flex, Text } from "@chakra-ui/react";
|
||||
import { ParameterLayoutHeader } from "./ParameterLayoutHeader";
|
||||
import { Flex, Text } from '@chakra-ui/react';
|
||||
|
||||
import { ParameterLayoutHeader } from './ParameterLayoutHeader';
|
||||
|
||||
export type ParameterLayoutHeaderBaseProps = {
|
||||
title: string;
|
||||
description?: string,
|
||||
}
|
||||
description?: string;
|
||||
};
|
||||
|
||||
export const ParameterLayoutHeaderBase = ({
|
||||
title,
|
||||
description,
|
||||
}: ParameterLayoutHeaderBaseProps) => {
|
||||
return <ParameterLayoutHeader>
|
||||
return (
|
||||
<ParameterLayoutHeader>
|
||||
<Flex direction="column">
|
||||
<Text
|
||||
fontSize="25px"
|
||||
fontWeight="bold">
|
||||
<Text fontSize="25px" fontWeight="bold">
|
||||
{title}
|
||||
</Text>
|
||||
{description && <Text>{description}</Text>}
|
||||
</Flex>
|
||||
</ParameterLayoutHeader>
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -1,17 +1,24 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { VStack } from '@chakra-ui/react';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
export type ParameterLayoutRootProps = {
|
||||
children?: ReactNode;
|
||||
}
|
||||
};
|
||||
|
||||
export const ParameterLayoutRoot = ({ children }: ParameterLayoutRootProps) => {
|
||||
return <VStack gap="0px" marginX="15%" marginY="20px" justify="center"
|
||||
return (
|
||||
<VStack
|
||||
gap="0px"
|
||||
marginX="15%"
|
||||
marginY="20px"
|
||||
justify="center"
|
||||
//borderRadius="20px"
|
||||
borderRadius="0px"
|
||||
border="1px solid black"
|
||||
background="gray.500">
|
||||
background="gray.500"
|
||||
>
|
||||
{children}
|
||||
</VStack>
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -1,9 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import {
|
||||
Group,
|
||||
Input,
|
||||
} from '@chakra-ui/react';
|
||||
import { Group, Input } from '@chakra-ui/react';
|
||||
import { MdSearch } from 'react-icons/md';
|
||||
|
||||
export type SearchInputProps = {
|
||||
|
@ -2,15 +2,15 @@ import { ReactNode } from 'react';
|
||||
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
ConditionalValue,
|
||||
Flex,
|
||||
HStack,
|
||||
IconButton,
|
||||
Text,
|
||||
useDisclosure,
|
||||
Button,
|
||||
ConditionalValue,
|
||||
Span,
|
||||
Text,
|
||||
chakra,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
LuAlignJustify,
|
||||
@ -22,13 +22,18 @@ import {
|
||||
LuSettings,
|
||||
LuSun,
|
||||
} from 'react-icons/lu';
|
||||
import {
|
||||
MdHelp,
|
||||
MdHome,
|
||||
MdKey,
|
||||
MdMore,
|
||||
MdOutlineDashboardCustomize,
|
||||
MdOutlineGroup,
|
||||
MdSettings,
|
||||
MdSupervisedUserCircle,
|
||||
} from 'react-icons/md';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { useServiceContext } from '@/service/ServiceContext';
|
||||
import { colors } from '@/theme/colors';
|
||||
import { useSessionService } from '@/service/session';
|
||||
import { MdHelp, MdHome, MdKey, MdMore, MdOutlineDashboardCustomize, MdOutlineGroup, MdSettings, MdSupervisedUserCircle } from 'react-icons/md';
|
||||
import { MenuContent, MenuItem, MenuRoot, MenuTrigger } from '@/components/ui/menu';
|
||||
import { useColorMode, useColorModeValue } from '@/components/ui/color-mode';
|
||||
import {
|
||||
DrawerBody,
|
||||
@ -36,11 +41,22 @@ import {
|
||||
DrawerHeader,
|
||||
DrawerRoot,
|
||||
} from '@/components/ui/drawer';
|
||||
import {
|
||||
MenuContent,
|
||||
MenuItem,
|
||||
MenuRoot,
|
||||
MenuTrigger,
|
||||
} from '@/components/ui/menu';
|
||||
import { useServiceContext } from '@/service/ServiceContext';
|
||||
import { useSessionService } from '@/service/session';
|
||||
import { colors } from '@/theme/colors';
|
||||
|
||||
export const TOP_BAR_HEIGHT = '50px';
|
||||
|
||||
export const BUTTON_TOP_BAR_PROPERTY = {
|
||||
variant: "ghost" as ConditionalValue<"ghost" | "outline" | "solid" | "subtle" | "surface" | "plain" | undefined>,
|
||||
variant: 'ghost' as ConditionalValue<
|
||||
'ghost' | 'outline' | 'solid' | 'subtle' | 'surface' | 'plain' | undefined
|
||||
>,
|
||||
//colorPalette: "brand",
|
||||
fontSize: '20px',
|
||||
textTransform: 'uppercase',
|
||||
@ -52,13 +68,20 @@ export type TopBarProps = {
|
||||
title?: string;
|
||||
};
|
||||
|
||||
const ButtonMenuLeft = ({ dest, title, icon,
|
||||
onClickEnd = () => { }, }: {
|
||||
dest: string, title: string, icon: ReactNode
|
||||
const ButtonMenuLeft = ({
|
||||
dest,
|
||||
title,
|
||||
icon,
|
||||
onClickEnd = () => {},
|
||||
}: {
|
||||
dest: string;
|
||||
title: string;
|
||||
icon: ReactNode;
|
||||
onClickEnd?: () => void;
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
return <>
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
background="#00000000"
|
||||
borderRadius="0px"
|
||||
@ -69,14 +92,17 @@ const ButtonMenuLeft = ({ dest, title, icon,
|
||||
width="full"
|
||||
{...BUTTON_TOP_BAR_PROPERTY}
|
||||
>
|
||||
<Box asChild style={{ width: "45px", height: "45px" }}>{icon}</Box>
|
||||
<Box asChild style={{ width: '45px', height: '45px' }}>
|
||||
{icon}
|
||||
</Box>
|
||||
<Text paddingLeft="3px" fontWeight="bold" marginRight="auto">
|
||||
{title}
|
||||
</Text>
|
||||
</Button>
|
||||
<Box marginY="5" marginX="10" height="2px" background="brand.600" />
|
||||
</>
|
||||
}
|
||||
);
|
||||
};
|
||||
export const TopBar = ({ title, children }: TopBarProps) => {
|
||||
const { colorMode, toggleColorMode } = useColorMode();
|
||||
|
||||
@ -138,7 +164,10 @@ export const TopBar = ({ title, children }: TopBarProps) => {
|
||||
<Flex right="0">
|
||||
{!session?.token && (
|
||||
<>
|
||||
<Button {...BUTTON_TOP_BAR_PROPERTY} onClick={() => navigate('/login')}>
|
||||
<Button
|
||||
{...BUTTON_TOP_BAR_PROPERTY}
|
||||
onClick={() => navigate('/login')}
|
||||
>
|
||||
<LuLogIn />
|
||||
<Text paddingLeft="3px" fontWeight="bold">
|
||||
Sign-in
|
||||
@ -163,24 +192,55 @@ export const TopBar = ({ title, children }: TopBarProps) => {
|
||||
//asChild
|
||||
{...BUTTON_TOP_BAR_PROPERTY}
|
||||
width={TOP_BAR_HEIGHT}
|
||||
><LuCircleUserRound/></IconButton>
|
||||
>
|
||||
<LuCircleUserRound />
|
||||
</IconButton>
|
||||
</MenuTrigger>
|
||||
<MenuContent>
|
||||
<MenuItem value="user" valueText="user" color={useColorModeValue('brand.800', 'brand.200')}>
|
||||
<MenuItem
|
||||
value="user"
|
||||
valueText="user"
|
||||
color={useColorModeValue('brand.800', 'brand.200')}
|
||||
>
|
||||
<MdSupervisedUserCircle />
|
||||
<Box flex="1">Sign in as {session?.login ?? 'Fail'}</Box>
|
||||
</MenuItem>
|
||||
<MenuItem value="Settings" valueText="Settings" onClick={() => navigate('/settings')}><LuSettings />Settings</MenuItem>
|
||||
<MenuItem value="Help" valueText="Help" onClick={() => navigate('/help')}><MdHelp /> Help</MenuItem>
|
||||
<MenuItem value="Sign-out" valueText="Sign-out" onClick={() => navigate('/signout')}>
|
||||
<MenuItem
|
||||
value="Settings"
|
||||
valueText="Settings"
|
||||
onClick={() => navigate('/settings')}
|
||||
>
|
||||
<LuSettings />
|
||||
Settings
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
value="Help"
|
||||
valueText="Help"
|
||||
onClick={() => navigate('/help')}
|
||||
>
|
||||
<MdHelp /> Help
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
value="Sign-out"
|
||||
valueText="Sign-out"
|
||||
onClick={() => navigate('/signout')}
|
||||
>
|
||||
<LuLogOut /> Sign-out
|
||||
</MenuItem>
|
||||
{colorMode === 'light' ? (
|
||||
<MenuItem value="set-dark" valueText="set-dark" onClick={toggleColorMode}>
|
||||
<MenuItem
|
||||
value="set-dark"
|
||||
valueText="set-dark"
|
||||
onClick={toggleColorMode}
|
||||
>
|
||||
<LuMoon /> Set dark mode
|
||||
</MenuItem>
|
||||
) : (
|
||||
<MenuItem value="set-light" valueText="set-light" onClick={toggleColorMode}>
|
||||
<MenuItem
|
||||
value="set-light"
|
||||
valueText="set-light"
|
||||
onClick={toggleColorMode}
|
||||
>
|
||||
<LuSun /> Set light mode
|
||||
</MenuItem>
|
||||
)}
|
||||
@ -194,8 +254,7 @@ export const TopBar = ({ title, children }: TopBarProps) => {
|
||||
open={drawerDisclose.open}
|
||||
data-testid="top-bar_drawer-root"
|
||||
>
|
||||
<DrawerContent
|
||||
data-testid="top-bar_drawer-content">
|
||||
<DrawerContent data-testid="top-bar_drawer-content">
|
||||
<DrawerHeader
|
||||
paddingY="auto"
|
||||
as="button"
|
||||
@ -205,21 +264,43 @@ export const TopBar = ({ title, children }: TopBarProps) => {
|
||||
color={useColorModeValue('brand.900', 'brand.50')}
|
||||
textTransform="uppercase"
|
||||
>
|
||||
<HStack
|
||||
{...BUTTON_TOP_BAR_PROPERTY} cursor="pointer">
|
||||
<HStack {...BUTTON_TOP_BAR_PROPERTY} cursor="pointer">
|
||||
<LuArrowBigLeft />
|
||||
<Span paddingLeft="3px">
|
||||
karso
|
||||
</Span>
|
||||
<Span paddingLeft="3px">karso</Span>
|
||||
</HStack>
|
||||
</DrawerHeader>
|
||||
<DrawerBody paddingX="0px">
|
||||
<Box marginY="3" />
|
||||
<ButtonMenuLeft onClickEnd={drawerDisclose.onClose} dest="/" title="Home" icon={<MdHome />} />
|
||||
<ButtonMenuLeft onClickEnd={drawerDisclose.onClose} dest="/change-password" title="Change password" icon={<MdKey />} />
|
||||
<ButtonMenuLeft onClickEnd={drawerDisclose.onClose} dest="/admin-settings" title="Admin settings" icon={<MdSettings />} />
|
||||
<ButtonMenuLeft onClickEnd={drawerDisclose.onClose} dest="/manage-account" title="Manage account" icon={<MdOutlineGroup />} />
|
||||
<ButtonMenuLeft onClickEnd={drawerDisclose.onClose} dest="/manage-application" title="Manage application" icon={<MdOutlineDashboardCustomize />} />
|
||||
<ButtonMenuLeft
|
||||
onClickEnd={drawerDisclose.onClose}
|
||||
dest="/"
|
||||
title="Home"
|
||||
icon={<MdHome />}
|
||||
/>
|
||||
<ButtonMenuLeft
|
||||
onClickEnd={drawerDisclose.onClose}
|
||||
dest="/change-password"
|
||||
title="Change password"
|
||||
icon={<MdKey />}
|
||||
/>
|
||||
<ButtonMenuLeft
|
||||
onClickEnd={drawerDisclose.onClose}
|
||||
dest="/admin-settings"
|
||||
title="Admin settings"
|
||||
icon={<MdSettings />}
|
||||
/>
|
||||
<ButtonMenuLeft
|
||||
onClickEnd={drawerDisclose.onClose}
|
||||
dest="/manage-account"
|
||||
title="Manage account"
|
||||
icon={<MdOutlineGroup />}
|
||||
/>
|
||||
<ButtonMenuLeft
|
||||
onClickEnd={drawerDisclose.onClose}
|
||||
dest="/manage-application"
|
||||
title="Manage application"
|
||||
icon={<MdOutlineDashboardCustomize />}
|
||||
/>
|
||||
</DrawerBody>
|
||||
</DrawerContent>
|
||||
</DrawerRoot>
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { ReactNode, useState } from 'react';
|
||||
|
||||
import { LuMenu } from 'react-icons/lu';
|
||||
import { MenuContent, MenuItem, MenuRoot, MenuTrigger } from '../ui/menu';
|
||||
import { Button } from '../ui/button';
|
||||
|
||||
import { Button } from '../ui/button';
|
||||
import { MenuContent, MenuItem, MenuRoot, MenuTrigger } from '../ui/menu';
|
||||
|
||||
export type MenuElement = {
|
||||
icon?: ReactNode;
|
||||
@ -20,22 +20,28 @@ export const ContextMenu = ({ elements }: ContextMenuProps) => {
|
||||
return <></>;
|
||||
}
|
||||
return (
|
||||
<MenuRoot
|
||||
data-testid="context-menu">
|
||||
<MenuTrigger asChild
|
||||
<MenuRoot data-testid="context-menu">
|
||||
<MenuTrigger
|
||||
asChild
|
||||
marginY="auto"
|
||||
marginRight="4px"
|
||||
data-testid="context-menu_trigger">
|
||||
data-testid="context-menu_trigger"
|
||||
>
|
||||
{/* This is very stupid, we need to set as span to prevent a button in button... WTF */}
|
||||
<Button variant="ghost" color="brand.500">
|
||||
<LuMenu />
|
||||
</Button>
|
||||
</MenuTrigger>
|
||||
<MenuContent
|
||||
data-testid="context-menu_content">
|
||||
<MenuContent data-testid="context-menu_content">
|
||||
{elements?.map((data) => (
|
||||
<MenuItem key={data.name} value={data.name} onClick={data.onClick} height="65px" fontSize="25px"
|
||||
data-test-id="context-menu_item" >
|
||||
<MenuItem
|
||||
key={data.name}
|
||||
value={data.name}
|
||||
onClick={data.onClick}
|
||||
height="65px"
|
||||
fontSize="25px"
|
||||
data-test-id="context-menu_item"
|
||||
>
|
||||
{data.icon}
|
||||
{data.name}
|
||||
</MenuItem>
|
||||
|
@ -3,6 +3,7 @@ import { RefObject } from 'react';
|
||||
import { Input } from '@chakra-ui/react';
|
||||
|
||||
import { FormGroup, FormGroupProps } from '@/components/form/FormGroup';
|
||||
|
||||
import { useFormidableContextElement } from '../formidable';
|
||||
|
||||
export type FormInputProps = {
|
||||
@ -21,10 +22,7 @@ export const FormInput = ({
|
||||
}: FormInputProps) => {
|
||||
const { value, onChange } = useFormidableContextElement(name);
|
||||
return (
|
||||
<FormGroup
|
||||
name={name}
|
||||
{...rest}
|
||||
>
|
||||
<FormGroup name={name} {...rest}>
|
||||
<Input
|
||||
ref={ref}
|
||||
type="text"
|
||||
|
@ -4,6 +4,7 @@ import { Box } from '@chakra-ui/react';
|
||||
|
||||
import { FormSelect } from '@/components/form/FormSelect';
|
||||
import { useFormidable } from '@/components/formidable/FormidableConfig';
|
||||
|
||||
import { Formidable } from '../formidable';
|
||||
|
||||
export default {
|
||||
|
@ -4,6 +4,7 @@ import { Box } from '@chakra-ui/react';
|
||||
|
||||
import { FormSelectMultiple } from '@/components/form/FormSelectMultiple';
|
||||
import { useFormidable } from '@/components/formidable/FormidableConfig';
|
||||
|
||||
import { Formidable } from '../formidable';
|
||||
|
||||
export default {
|
||||
|
@ -1,6 +1,8 @@
|
||||
export {type FormidableConfig as config,
|
||||
useFormidable
|
||||
export {
|
||||
type FormidableConfig as config,
|
||||
useFormidable,
|
||||
} from './FormidableConfig';
|
||||
export {FormidableForm as From,
|
||||
type FormidableFormProps as FormProps
|
||||
export {
|
||||
FormidableForm as From,
|
||||
type FormidableFormProps as FormProps,
|
||||
} from './FormidableForm';
|
@ -1,11 +1,7 @@
|
||||
export * as Formidable from './Fromidable';
|
||||
export {
|
||||
useFormidableContext,
|
||||
useFormidableContextElement
|
||||
} from './FormidableContext'
|
||||
export {
|
||||
useFormidable
|
||||
} from './FormidableConfig';
|
||||
export {
|
||||
zodResolver
|
||||
} from './utils';
|
||||
useFormidableContextElement,
|
||||
} from './FormidableContext';
|
||||
export { useFormidable } from './FormidableConfig';
|
||||
export { zodResolver } from './utils';
|
||||
|
@ -1,11 +1,15 @@
|
||||
import { useRef } from 'react';
|
||||
|
||||
import {
|
||||
Button,
|
||||
UseDisclosureReturn,
|
||||
} from '@chakra-ui/react';
|
||||
import { Button, UseDisclosureReturn } from '@chakra-ui/react';
|
||||
|
||||
import {
|
||||
DialogBody,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogRoot,
|
||||
} from '@/components/ui/dialog';
|
||||
|
||||
import { DialogBody, DialogContent, DialogFooter, DialogHeader, DialogRoot } from '@/components/ui/dialog';
|
||||
export type ConfirmPopUpProps = {
|
||||
title: string;
|
||||
body: string;
|
||||
@ -27,7 +31,8 @@ export const ConfirmPopUp = ({
|
||||
};
|
||||
const cancelRef = useRef<HTMLButtonElement>(null);
|
||||
return (
|
||||
<DialogRoot role="alertdialog"
|
||||
<DialogRoot
|
||||
role="alertdialog"
|
||||
open={disclosure.open}
|
||||
//leastDestructiveRef={cancelRef}
|
||||
onOpenChange={disclosure.onClose}
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { useRef } from 'react';
|
||||
|
||||
import { Button, Flex, Progress, Text } from '@chakra-ui/react';
|
||||
|
||||
import {
|
||||
Flex,
|
||||
Progress,
|
||||
Text,
|
||||
Button,
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
import { DialogBody, DialogContent, DialogFooter, DialogHeader, DialogRoot } from '@/components/ui/dialog';
|
||||
|
||||
DialogBody,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogRoot,
|
||||
} from '@/components/ui/dialog';
|
||||
|
||||
export type PopUpUploadProgressProps = {
|
||||
title: string;
|
||||
|
@ -109,7 +109,13 @@ export const SelectMultiple = ({
|
||||
return (
|
||||
<Flex direction="column" width="full" gap="0px">
|
||||
{selectedOptions && (
|
||||
<HStack wrap="wrap" gap="5px" justify="left" width="full" marginBottom="2px">
|
||||
<HStack
|
||||
wrap="wrap"
|
||||
gap="5px"
|
||||
justify="left"
|
||||
width="full"
|
||||
marginBottom="2px"
|
||||
>
|
||||
{selectedOptions.map((data) => (
|
||||
<Flex align="flex-start" key={data[keyKey]}>
|
||||
<Tag.Root
|
||||
@ -119,7 +125,10 @@ export const SelectMultiple = ({
|
||||
backgroundColor="green.800"
|
||||
>
|
||||
<Tag.Label>{data[keyValue] ?? `id=${data[keyKey]}`}</Tag.Label>
|
||||
<Tag.CloseTrigger boxSize="5" onClick={() => selectValue(data)} />
|
||||
<Tag.CloseTrigger
|
||||
boxSize="5"
|
||||
onClick={() => selectValue(data)}
|
||||
/>
|
||||
</Tag.Root>
|
||||
</Flex>
|
||||
))}
|
||||
@ -134,7 +143,13 @@ export const SelectMultiple = ({
|
||||
//onSubmit={onSubmit}
|
||||
onFocus={() => setShowList(true)}
|
||||
onBlur={() => setTimeout(() => setShowList(false), 200)}
|
||||
value={showList ? (currentSearch ?? '') : hasSuggestion ? `suggest: ${currentSearch}` : ''}
|
||||
value={
|
||||
showList
|
||||
? (currentSearch ?? '')
|
||||
: hasSuggestion
|
||||
? `suggest: ${currentSearch}`
|
||||
: ''
|
||||
}
|
||||
borderRadius="5px 0 0 5px"
|
||||
/>
|
||||
<Button
|
||||
|
@ -50,7 +50,9 @@ export const SelectSingle = ({
|
||||
onCreate ? suggestion : undefined
|
||||
);
|
||||
useEffect(() => {
|
||||
console.log(`Update suggestion : ${onCreate} ${suggestion} ==> ${onCreate ? suggestion : undefined} .. ${onCreate && !isNullOrUndefined(suggestion) ? true : false}`);
|
||||
console.log(
|
||||
`Update suggestion : ${onCreate} ${suggestion} ==> ${onCreate ? suggestion : undefined} .. ${onCreate && !isNullOrUndefined(suggestion) ? true : false}`
|
||||
);
|
||||
setCurrentSearch(onCreate ? suggestion : undefined);
|
||||
setHasSuggestion(onCreate && !isNullOrUndefined(suggestion) ? true : false);
|
||||
}, [suggestion]);
|
||||
@ -110,7 +112,10 @@ export const SelectSingle = ({
|
||||
onFocus={() => setShowList(true)}
|
||||
onBlur={() => setTimeout(() => setShowList(false), 200)}
|
||||
value={
|
||||
showList ? (currentSearch ?? '') : (selectedOptions?.name ?? (hasSuggestion ? `suggest: ${currentSearch}` : ''))
|
||||
showList
|
||||
? (currentSearch ?? '')
|
||||
: (selectedOptions?.name ??
|
||||
(hasSuggestion ? `suggest: ${currentSearch}` : ''))
|
||||
}
|
||||
backgroundColor={
|
||||
showList || !selectedOptions ? undefined : 'green.800'
|
||||
|
@ -1,24 +1,25 @@
|
||||
"use client"
|
||||
'use client';
|
||||
|
||||
import type { GroupProps, SlotRecipeProps } from "@chakra-ui/react"
|
||||
import { Avatar as ChakraAvatar, Group } from "@chakra-ui/react"
|
||||
import * as React from "react"
|
||||
import * as React from 'react';
|
||||
|
||||
type ImageProps = React.ImgHTMLAttributes<HTMLImageElement>
|
||||
import type { GroupProps, SlotRecipeProps } from '@chakra-ui/react';
|
||||
import { Avatar as ChakraAvatar, Group } from '@chakra-ui/react';
|
||||
|
||||
type ImageProps = React.ImgHTMLAttributes<HTMLImageElement>;
|
||||
|
||||
export interface AvatarProps extends ChakraAvatar.RootProps {
|
||||
name?: string
|
||||
src?: string
|
||||
srcSet?: string
|
||||
loading?: ImageProps["loading"]
|
||||
icon?: React.ReactElement
|
||||
fallback?: React.ReactNode
|
||||
name?: string;
|
||||
src?: string;
|
||||
srcSet?: string;
|
||||
loading?: ImageProps['loading'];
|
||||
icon?: React.ReactElement;
|
||||
fallback?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const Avatar = React.forwardRef<HTMLDivElement, AvatarProps>(
|
||||
function Avatar(props, ref) {
|
||||
const { name, src, srcSet, loading, icon, fallback, children, ...rest } =
|
||||
props
|
||||
props;
|
||||
return (
|
||||
<ChakraAvatar.Root ref={ref} {...rest}>
|
||||
<AvatarFallback name={name} icon={icon}>
|
||||
@ -27,18 +28,18 @@ export const Avatar = React.forwardRef<HTMLDivElement, AvatarProps>(
|
||||
<ChakraAvatar.Image src={src} srcSet={srcSet} loading={loading} />
|
||||
{children}
|
||||
</ChakraAvatar.Root>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
interface AvatarFallbackProps extends ChakraAvatar.FallbackProps {
|
||||
name?: string
|
||||
icon?: React.ReactElement
|
||||
name?: string;
|
||||
icon?: React.ReactElement;
|
||||
}
|
||||
|
||||
const AvatarFallback = React.forwardRef<HTMLDivElement, AvatarFallbackProps>(
|
||||
function AvatarFallback(props, ref) {
|
||||
const { name, icon, children, ...rest } = props
|
||||
const { name, icon, children, ...rest } = props;
|
||||
return (
|
||||
<ChakraAvatar.Fallback ref={ref} {...rest}>
|
||||
{children}
|
||||
@ -47,28 +48,28 @@ const AvatarFallback = React.forwardRef<HTMLDivElement, AvatarFallbackProps>(
|
||||
<ChakraAvatar.Icon asChild={!!icon}>{icon}</ChakraAvatar.Icon>
|
||||
)}
|
||||
</ChakraAvatar.Fallback>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
function getInitials(name: string) {
|
||||
const names = name.trim().split(" ")
|
||||
const firstName = names[0] != null ? names[0] : ""
|
||||
const lastName = names.length > 1 ? names[names.length - 1] : ""
|
||||
const names = name.trim().split(' ');
|
||||
const firstName = names[0] != null ? names[0] : '';
|
||||
const lastName = names.length > 1 ? names[names.length - 1] : '';
|
||||
return firstName && lastName
|
||||
? `${firstName.charAt(0)}${lastName.charAt(0)}`
|
||||
: firstName.charAt(0)
|
||||
: firstName.charAt(0);
|
||||
}
|
||||
|
||||
interface AvatarGroupProps extends GroupProps, SlotRecipeProps<"avatar"> {}
|
||||
interface AvatarGroupProps extends GroupProps, SlotRecipeProps<'avatar'> {}
|
||||
|
||||
export const AvatarGroup = React.forwardRef<HTMLDivElement, AvatarGroupProps>(
|
||||
function AvatarGroup(props, ref) {
|
||||
const { size, variant, borderless, ...rest } = props
|
||||
const { size, variant, borderless, ...rest } = props;
|
||||
return (
|
||||
<ChakraAvatar.PropsProvider value={{ size, variant, borderless }}>
|
||||
<Group gap="0" spaceX="-3" ref={ref} {...rest} />
|
||||
</ChakraAvatar.PropsProvider>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -1,22 +1,23 @@
|
||||
import type { ButtonProps as ChakraButtonProps } from "@chakra-ui/react"
|
||||
import * as React from 'react';
|
||||
|
||||
import type { ButtonProps as ChakraButtonProps } from '@chakra-ui/react';
|
||||
import {
|
||||
AbsoluteCenter,
|
||||
Button as ChakraButton,
|
||||
Span,
|
||||
Spinner,
|
||||
} from "@chakra-ui/react"
|
||||
import * as React from "react"
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
interface ButtonLoadingProps {
|
||||
loading?: boolean
|
||||
loadingText?: React.ReactNode
|
||||
loading?: boolean;
|
||||
loadingText?: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface ButtonProps extends ChakraButtonProps, ButtonLoadingProps {}
|
||||
|
||||
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
function Button(props, ref) {
|
||||
const { loading, disabled, loadingText, children, ...rest } = props
|
||||
const { loading, disabled, loadingText, children, ...rest } = props;
|
||||
return (
|
||||
<ChakraButton disabled={loading || disabled} ref={ref} {...rest}>
|
||||
{loading && !loadingText ? (
|
||||
@ -35,6 +36,6 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
children
|
||||
)}
|
||||
</ChakraButton>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -1,15 +1,16 @@
|
||||
import { Checkbox as ChakraCheckbox } from "@chakra-ui/react"
|
||||
import * as React from "react"
|
||||
import * as React from 'react';
|
||||
|
||||
import { Checkbox as ChakraCheckbox } from '@chakra-ui/react';
|
||||
|
||||
export interface CheckboxProps extends ChakraCheckbox.RootProps {
|
||||
icon?: React.ReactNode
|
||||
inputProps?: React.InputHTMLAttributes<HTMLInputElement>
|
||||
rootRef?: React.Ref<HTMLLabelElement>
|
||||
icon?: React.ReactNode;
|
||||
inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
|
||||
rootRef?: React.Ref<HTMLLabelElement>;
|
||||
}
|
||||
|
||||
export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
function Checkbox(props, ref) {
|
||||
const { icon, children, inputProps, rootRef, ...rest } = props
|
||||
const { icon, children, inputProps, rootRef, ...rest } = props;
|
||||
return (
|
||||
<ChakraCheckbox.Root ref={rootRef} {...rest}>
|
||||
<ChakraCheckbox.HiddenInput ref={ref} {...inputProps} />
|
||||
@ -20,6 +21,6 @@ export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
|
||||
<ChakraCheckbox.Label>{children}</ChakraCheckbox.Label>
|
||||
)}
|
||||
</ChakraCheckbox.Root>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -1,9 +1,10 @@
|
||||
import type { ButtonProps } from "@chakra-ui/react"
|
||||
import { IconButton as ChakraIconButton } from "@chakra-ui/react"
|
||||
import * as React from "react"
|
||||
import { LuX } from "react-icons/lu"
|
||||
import * as React from 'react';
|
||||
|
||||
export type CloseButtonProps = ButtonProps
|
||||
import type { ButtonProps } from '@chakra-ui/react';
|
||||
import { IconButton as ChakraIconButton } from '@chakra-ui/react';
|
||||
import { LuX } from 'react-icons/lu';
|
||||
|
||||
export type CloseButtonProps = ButtonProps;
|
||||
|
||||
export const CloseButton = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
@ -13,5 +14,5 @@ export const CloseButton = React.forwardRef<
|
||||
<ChakraIconButton variant="ghost" aria-label="Close" ref={ref} {...props}>
|
||||
{props.children ?? <LuX />}
|
||||
</ChakraIconButton>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
@ -1,57 +1,58 @@
|
||||
"use client"
|
||||
'use client';
|
||||
|
||||
import type { IconButtonProps } from "@chakra-ui/react"
|
||||
import { ClientOnly, IconButton, Skeleton } from "@chakra-ui/react"
|
||||
import { ThemeProvider, useTheme } from "next-themes"
|
||||
import type { ThemeProviderProps } from "next-themes"
|
||||
import * as React from "react"
|
||||
import { LuMoon, LuSun } from "react-icons/lu"
|
||||
import * as React from 'react';
|
||||
|
||||
import type { IconButtonProps } from '@chakra-ui/react';
|
||||
import { ClientOnly, IconButton, Skeleton } from '@chakra-ui/react';
|
||||
import { ThemeProvider, useTheme } from 'next-themes';
|
||||
import type { ThemeProviderProps } from 'next-themes';
|
||||
import { LuMoon, LuSun } from 'react-icons/lu';
|
||||
|
||||
export interface ColorModeProviderProps extends ThemeProviderProps {}
|
||||
|
||||
export function ColorModeProvider(props: ColorModeProviderProps) {
|
||||
return (
|
||||
<ThemeProvider attribute="class" disableTransitionOnChange {...props} />
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export type ColorMode = "light" | "dark"
|
||||
export type ColorMode = 'light' | 'dark';
|
||||
|
||||
export interface UseColorModeReturn {
|
||||
colorMode: ColorMode
|
||||
setColorMode: (colorMode: ColorMode) => void
|
||||
toggleColorMode: () => void
|
||||
colorMode: ColorMode;
|
||||
setColorMode: (colorMode: ColorMode) => void;
|
||||
toggleColorMode: () => void;
|
||||
}
|
||||
|
||||
export function useColorMode(): UseColorModeReturn {
|
||||
const { resolvedTheme, setTheme } = useTheme()
|
||||
const { resolvedTheme, setTheme } = useTheme();
|
||||
const toggleColorMode = () => {
|
||||
setTheme(resolvedTheme === "light" ? "dark" : "light")
|
||||
}
|
||||
setTheme(resolvedTheme === 'light' ? 'dark' : 'light');
|
||||
};
|
||||
return {
|
||||
colorMode: resolvedTheme as ColorMode,
|
||||
setColorMode: setTheme,
|
||||
toggleColorMode,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function useColorModeValue<T>(light: T, dark: T) {
|
||||
const { colorMode } = useColorMode()
|
||||
return colorMode === "dark" ? dark : light
|
||||
const { colorMode } = useColorMode();
|
||||
return colorMode === 'dark' ? dark : light;
|
||||
}
|
||||
|
||||
export function ColorModeIcon() {
|
||||
const { colorMode } = useColorMode()
|
||||
return colorMode === "dark" ? <LuMoon /> : <LuSun />
|
||||
const { colorMode } = useColorMode();
|
||||
return colorMode === 'dark' ? <LuMoon /> : <LuSun />;
|
||||
}
|
||||
|
||||
interface ColorModeButtonProps extends Omit<IconButtonProps, "aria-label"> {}
|
||||
interface ColorModeButtonProps extends Omit<IconButtonProps, 'aria-label'> {}
|
||||
|
||||
export const ColorModeButton = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
ColorModeButtonProps
|
||||
>(function ColorModeButton(props, ref) {
|
||||
const { toggleColorMode } = useColorMode()
|
||||
const { toggleColorMode } = useColorMode();
|
||||
return (
|
||||
<ClientOnly fallback={<Skeleton boxSize="8" />}>
|
||||
<IconButton
|
||||
@ -63,13 +64,13 @@ export const ColorModeButton = React.forwardRef<
|
||||
{...props}
|
||||
css={{
|
||||
_icon: {
|
||||
width: "5",
|
||||
height: "5",
|
||||
width: '5',
|
||||
height: '5',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ColorModeIcon />
|
||||
</IconButton>
|
||||
</ClientOnly>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { Dialog as ChakraDialog, Portal } from "@chakra-ui/react"
|
||||
import { CloseButton } from "./close-button"
|
||||
import * as React from "react"
|
||||
import * as React from 'react';
|
||||
|
||||
import { Dialog as ChakraDialog, Portal } from '@chakra-ui/react';
|
||||
|
||||
import { CloseButton } from './close-button';
|
||||
|
||||
interface DialogContentProps extends ChakraDialog.ContentProps {
|
||||
portalled?: boolean
|
||||
portalRef?: React.RefObject<HTMLElement>
|
||||
backdrop?: boolean
|
||||
portalled?: boolean;
|
||||
portalRef?: React.RefObject<HTMLElement>;
|
||||
backdrop?: boolean;
|
||||
}
|
||||
|
||||
export const DialogContent = React.forwardRef<
|
||||
@ -18,7 +20,7 @@ export const DialogContent = React.forwardRef<
|
||||
portalRef,
|
||||
backdrop = true,
|
||||
...rest
|
||||
} = props
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Portal disabled={!portalled} container={portalRef}>
|
||||
@ -29,8 +31,8 @@ export const DialogContent = React.forwardRef<
|
||||
</ChakraDialog.Content>
|
||||
</ChakraDialog.Positioner>
|
||||
</Portal>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const DialogCloseTrigger = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
@ -48,15 +50,15 @@ export const DialogCloseTrigger = React.forwardRef<
|
||||
{props.children}
|
||||
</CloseButton>
|
||||
</ChakraDialog.CloseTrigger>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const DialogRoot = ChakraDialog.Root
|
||||
export const DialogFooter = ChakraDialog.Footer
|
||||
export const DialogHeader = ChakraDialog.Header
|
||||
export const DialogBody = ChakraDialog.Body
|
||||
export const DialogBackdrop = ChakraDialog.Backdrop
|
||||
export const DialogTitle = ChakraDialog.Title
|
||||
export const DialogDescription = ChakraDialog.Description
|
||||
export const DialogTrigger = ChakraDialog.Trigger
|
||||
export const DialogActionTrigger = ChakraDialog.ActionTrigger
|
||||
export const DialogRoot = ChakraDialog.Root;
|
||||
export const DialogFooter = ChakraDialog.Footer;
|
||||
export const DialogHeader = ChakraDialog.Header;
|
||||
export const DialogBody = ChakraDialog.Body;
|
||||
export const DialogBackdrop = ChakraDialog.Backdrop;
|
||||
export const DialogTitle = ChakraDialog.Title;
|
||||
export const DialogDescription = ChakraDialog.Description;
|
||||
export const DialogTrigger = ChakraDialog.Trigger;
|
||||
export const DialogActionTrigger = ChakraDialog.ActionTrigger;
|
||||
|
@ -1,18 +1,20 @@
|
||||
import { Drawer as ChakraDrawer, Portal } from "@chakra-ui/react"
|
||||
import { CloseButton } from "./close-button"
|
||||
import * as React from "react"
|
||||
import * as React from 'react';
|
||||
|
||||
import { Drawer as ChakraDrawer, Portal } from '@chakra-ui/react';
|
||||
|
||||
import { CloseButton } from './close-button';
|
||||
|
||||
interface DrawerContentProps extends ChakraDrawer.ContentProps {
|
||||
portalled?: boolean
|
||||
portalRef?: React.RefObject<HTMLElement>
|
||||
offset?: ChakraDrawer.ContentProps["padding"]
|
||||
portalled?: boolean;
|
||||
portalRef?: React.RefObject<HTMLElement>;
|
||||
offset?: ChakraDrawer.ContentProps['padding'];
|
||||
}
|
||||
|
||||
export const DrawerContent = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
DrawerContentProps
|
||||
>(function DrawerContent(props, ref) {
|
||||
const { children, portalled = true, portalRef, offset, ...rest } = props
|
||||
const { children, portalled = true, portalRef, offset, ...rest } = props;
|
||||
return (
|
||||
<Portal disabled={!portalled} container={portalRef}>
|
||||
<ChakraDrawer.Positioner padding={offset}>
|
||||
@ -21,8 +23,8 @@ export const DrawerContent = React.forwardRef<
|
||||
</ChakraDrawer.Content>
|
||||
</ChakraDrawer.Positioner>
|
||||
</Portal>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const DrawerCloseTrigger = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
@ -38,15 +40,15 @@ export const DrawerCloseTrigger = React.forwardRef<
|
||||
>
|
||||
<CloseButton size="sm" ref={ref} />
|
||||
</ChakraDrawer.CloseTrigger>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const DrawerTrigger = ChakraDrawer.Trigger
|
||||
export const DrawerRoot = ChakraDrawer.Root
|
||||
export const DrawerFooter = ChakraDrawer.Footer
|
||||
export const DrawerHeader = ChakraDrawer.Header
|
||||
export const DrawerBody = ChakraDrawer.Body
|
||||
export const DrawerBackdrop = ChakraDrawer.Backdrop
|
||||
export const DrawerDescription = ChakraDrawer.Description
|
||||
export const DrawerTitle = ChakraDrawer.Title
|
||||
export const DrawerActionTrigger = ChakraDrawer.ActionTrigger
|
||||
export const DrawerTrigger = ChakraDrawer.Trigger;
|
||||
export const DrawerRoot = ChakraDrawer.Root;
|
||||
export const DrawerFooter = ChakraDrawer.Footer;
|
||||
export const DrawerHeader = ChakraDrawer.Header;
|
||||
export const DrawerBody = ChakraDrawer.Body;
|
||||
export const DrawerBackdrop = ChakraDrawer.Backdrop;
|
||||
export const DrawerDescription = ChakraDrawer.Description;
|
||||
export const DrawerTitle = ChakraDrawer.Title;
|
||||
export const DrawerActionTrigger = ChakraDrawer.ActionTrigger;
|
||||
|
@ -1,17 +1,18 @@
|
||||
import { Field as ChakraField } from "@chakra-ui/react"
|
||||
import * as React from "react"
|
||||
import * as React from 'react';
|
||||
|
||||
export interface FieldProps extends Omit<ChakraField.RootProps, "label"> {
|
||||
label?: React.ReactNode
|
||||
helperText?: React.ReactNode
|
||||
errorText?: React.ReactNode
|
||||
optionalText?: React.ReactNode
|
||||
import { Field as ChakraField } from '@chakra-ui/react';
|
||||
|
||||
export interface FieldProps extends Omit<ChakraField.RootProps, 'label'> {
|
||||
label?: React.ReactNode;
|
||||
helperText?: React.ReactNode;
|
||||
errorText?: React.ReactNode;
|
||||
optionalText?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const Field = React.forwardRef<HTMLDivElement, FieldProps>(
|
||||
function Field(props, ref) {
|
||||
const { label, children, helperText, errorText, optionalText, ...rest } =
|
||||
props
|
||||
props;
|
||||
return (
|
||||
<ChakraField.Root ref={ref} {...rest}>
|
||||
{label && (
|
||||
@ -28,6 +29,6 @@ export const Field = React.forwardRef<HTMLDivElement, FieldProps>(
|
||||
<ChakraField.ErrorText>{errorText}</ChakraField.ErrorText>
|
||||
)}
|
||||
</ChakraField.Root>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -1,15 +1,16 @@
|
||||
import type { BoxProps, InputElementProps } from "@chakra-ui/react"
|
||||
import { Group, InputElement } from "@chakra-ui/react"
|
||||
import * as React from "react"
|
||||
import * as React from 'react';
|
||||
|
||||
import type { BoxProps, InputElementProps } from '@chakra-ui/react';
|
||||
import { Group, InputElement } from '@chakra-ui/react';
|
||||
|
||||
export interface InputGroupProps extends BoxProps {
|
||||
startElementProps?: InputElementProps
|
||||
endElementProps?: InputElementProps
|
||||
startElement?: React.ReactNode
|
||||
endElement?: React.ReactNode
|
||||
children: React.ReactElement<InputElementProps>
|
||||
startOffset?: InputElementProps["paddingStart"]
|
||||
endOffset?: InputElementProps["paddingEnd"]
|
||||
startElementProps?: InputElementProps;
|
||||
endElementProps?: InputElementProps;
|
||||
startElement?: React.ReactNode;
|
||||
endElement?: React.ReactNode;
|
||||
children: React.ReactElement<InputElementProps>;
|
||||
startOffset?: InputElementProps['paddingStart'];
|
||||
endOffset?: InputElementProps['paddingEnd'];
|
||||
}
|
||||
|
||||
export const InputGroup = React.forwardRef<HTMLDivElement, InputGroupProps>(
|
||||
@ -20,13 +21,13 @@ export const InputGroup = React.forwardRef<HTMLDivElement, InputGroupProps>(
|
||||
endElement,
|
||||
endElementProps,
|
||||
children,
|
||||
startOffset = "6px",
|
||||
endOffset = "6px",
|
||||
startOffset = '6px',
|
||||
endOffset = '6px',
|
||||
...rest
|
||||
} = props
|
||||
} = props;
|
||||
|
||||
const child =
|
||||
React.Children.only<React.ReactElement<InputElementProps>>(children)
|
||||
React.Children.only<React.ReactElement<InputElementProps>>(children);
|
||||
|
||||
return (
|
||||
<Group ref={ref} {...rest}>
|
||||
@ -48,6 +49,6 @@ export const InputGroup = React.forwardRef<HTMLDivElement, InputGroupProps>(
|
||||
</InputElement>
|
||||
)}
|
||||
</Group>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -1,26 +1,27 @@
|
||||
"use client"
|
||||
'use client';
|
||||
|
||||
import { AbsoluteCenter, Menu as ChakraMenu, Portal } from "@chakra-ui/react"
|
||||
import * as React from "react"
|
||||
import { LuCheck, LuChevronRight } from "react-icons/lu"
|
||||
import * as React from 'react';
|
||||
|
||||
import { AbsoluteCenter, Menu as ChakraMenu, Portal } from '@chakra-ui/react';
|
||||
import { LuCheck, LuChevronRight } from 'react-icons/lu';
|
||||
|
||||
interface MenuContentProps extends ChakraMenu.ContentProps {
|
||||
portalled?: boolean
|
||||
portalRef?: React.RefObject<HTMLElement>
|
||||
portalled?: boolean;
|
||||
portalRef?: React.RefObject<HTMLElement>;
|
||||
}
|
||||
|
||||
export const MenuContent = React.forwardRef<HTMLDivElement, MenuContentProps>(
|
||||
function MenuContent(props, ref) {
|
||||
const { portalled = true, portalRef, ...rest } = props
|
||||
const { portalled = true, portalRef, ...rest } = props;
|
||||
return (
|
||||
<Portal disabled={!portalled} container={portalRef}>
|
||||
<ChakraMenu.Positioner>
|
||||
<ChakraMenu.Content ref={ref} {...rest} />
|
||||
</ChakraMenu.Positioner>
|
||||
</Portal>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const MenuArrow = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
@ -30,8 +31,8 @@ export const MenuArrow = React.forwardRef<
|
||||
<ChakraMenu.Arrow ref={ref} {...props}>
|
||||
<ChakraMenu.ArrowTip />
|
||||
</ChakraMenu.Arrow>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const MenuCheckboxItem = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
@ -44,14 +45,14 @@ export const MenuCheckboxItem = React.forwardRef<
|
||||
</ChakraMenu.ItemIndicator>
|
||||
{props.children}
|
||||
</ChakraMenu.CheckboxItem>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const MenuRadioItem = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
ChakraMenu.RadioItemProps
|
||||
>(function MenuRadioItem(props, ref) {
|
||||
const { children, ...rest } = props
|
||||
const { children, ...rest } = props;
|
||||
return (
|
||||
<ChakraMenu.RadioItem ps="8" ref={ref} {...rest}>
|
||||
<AbsoluteCenter axis="horizontal" left="4" asChild>
|
||||
@ -61,14 +62,14 @@ export const MenuRadioItem = React.forwardRef<
|
||||
</AbsoluteCenter>
|
||||
<ChakraMenu.ItemText>{children}</ChakraMenu.ItemText>
|
||||
</ChakraMenu.RadioItem>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const MenuItemGroup = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
ChakraMenu.ItemGroupProps
|
||||
>(function MenuItemGroup(props, ref) {
|
||||
const { title, children, ...rest } = props
|
||||
const { title, children, ...rest } = props;
|
||||
return (
|
||||
<ChakraMenu.ItemGroup ref={ref} {...rest}>
|
||||
{title && (
|
||||
@ -78,33 +79,33 @@ export const MenuItemGroup = React.forwardRef<
|
||||
)}
|
||||
{children}
|
||||
</ChakraMenu.ItemGroup>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export interface MenuTriggerItemProps extends ChakraMenu.ItemProps {
|
||||
startIcon?: React.ReactNode
|
||||
startIcon?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const MenuTriggerItem = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
MenuTriggerItemProps
|
||||
>(function MenuTriggerItem(props, ref) {
|
||||
const { startIcon, children, ...rest } = props
|
||||
const { startIcon, children, ...rest } = props;
|
||||
return (
|
||||
<ChakraMenu.TriggerItem ref={ref} {...rest}>
|
||||
{startIcon}
|
||||
{children}
|
||||
<LuChevronRight />
|
||||
</ChakraMenu.TriggerItem>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const MenuRadioItemGroup = ChakraMenu.RadioItemGroup
|
||||
export const MenuContextTrigger = ChakraMenu.ContextTrigger
|
||||
export const MenuRoot = ChakraMenu.Root
|
||||
export const MenuSeparator = ChakraMenu.Separator
|
||||
export const MenuRadioItemGroup = ChakraMenu.RadioItemGroup;
|
||||
export const MenuContextTrigger = ChakraMenu.ContextTrigger;
|
||||
export const MenuRoot = ChakraMenu.Root;
|
||||
export const MenuSeparator = ChakraMenu.Separator;
|
||||
|
||||
export const MenuItem = ChakraMenu.Item
|
||||
export const MenuItemText = ChakraMenu.ItemText
|
||||
export const MenuItemCommand = ChakraMenu.ItemCommand
|
||||
export const MenuTrigger = ChakraMenu.Trigger
|
||||
export const MenuItem = ChakraMenu.Item;
|
||||
export const MenuItemText = ChakraMenu.ItemText;
|
||||
export const MenuItemCommand = ChakraMenu.ItemCommand;
|
||||
export const MenuTrigger = ChakraMenu.Trigger;
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { NumberInput as ChakraNumberInput } from "@chakra-ui/react"
|
||||
import * as React from "react"
|
||||
import * as React from 'react';
|
||||
|
||||
import { NumberInput as ChakraNumberInput } from '@chakra-ui/react';
|
||||
|
||||
export interface NumberInputProps extends ChakraNumberInput.RootProps {}
|
||||
|
||||
@ -7,7 +8,7 @@ export const NumberInputRoot = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
NumberInputProps
|
||||
>(function NumberInput(props, ref) {
|
||||
const { children, ...rest } = props
|
||||
const { children, ...rest } = props;
|
||||
return (
|
||||
<ChakraNumberInput.Root ref={ref} variant="outline" {...rest}>
|
||||
{children}
|
||||
@ -16,9 +17,9 @@ export const NumberInputRoot = React.forwardRef<
|
||||
<ChakraNumberInput.DecrementTrigger />
|
||||
</ChakraNumberInput.Control>
|
||||
</ChakraNumberInput.Root>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const NumberInputField = ChakraNumberInput.Input
|
||||
export const NumberInputScrubber = ChakraNumberInput.Scrubber
|
||||
export const NumberInputLabel = ChakraNumberInput.Label
|
||||
export const NumberInputField = ChakraNumberInput.Input;
|
||||
export const NumberInputScrubber = ChakraNumberInput.Scrubber;
|
||||
export const NumberInputLabel = ChakraNumberInput.Label;
|
||||
|
@ -1,25 +1,27 @@
|
||||
import { Popover as ChakraPopover, Portal } from "@chakra-ui/react"
|
||||
import { CloseButton } from "./close-button"
|
||||
import * as React from "react"
|
||||
import * as React from 'react';
|
||||
|
||||
import { Popover as ChakraPopover, Portal } from '@chakra-ui/react';
|
||||
|
||||
import { CloseButton } from './close-button';
|
||||
|
||||
interface PopoverContentProps extends ChakraPopover.ContentProps {
|
||||
portalled?: boolean
|
||||
portalRef?: React.RefObject<HTMLElement>
|
||||
portalled?: boolean;
|
||||
portalRef?: React.RefObject<HTMLElement>;
|
||||
}
|
||||
|
||||
export const PopoverContent = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
PopoverContentProps
|
||||
>(function PopoverContent(props, ref) {
|
||||
const { portalled = true, portalRef, ...rest } = props
|
||||
const { portalled = true, portalRef, ...rest } = props;
|
||||
return (
|
||||
<Portal disabled={!portalled} container={portalRef}>
|
||||
<ChakraPopover.Positioner>
|
||||
<ChakraPopover.Content ref={ref} {...rest} />
|
||||
</ChakraPopover.Positioner>
|
||||
</Portal>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const PopoverArrow = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
@ -29,8 +31,8 @@ export const PopoverArrow = React.forwardRef<
|
||||
<ChakraPopover.Arrow {...props} ref={ref}>
|
||||
<ChakraPopover.ArrowTip />
|
||||
</ChakraPopover.Arrow>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const PopoverCloseTrigger = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
@ -47,13 +49,13 @@ export const PopoverCloseTrigger = React.forwardRef<
|
||||
>
|
||||
<CloseButton size="sm" />
|
||||
</ChakraPopover.CloseTrigger>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
export const PopoverTitle = ChakraPopover.Title
|
||||
export const PopoverDescription = ChakraPopover.Description
|
||||
export const PopoverFooter = ChakraPopover.Footer
|
||||
export const PopoverHeader = ChakraPopover.Header
|
||||
export const PopoverRoot = ChakraPopover.Root
|
||||
export const PopoverBody = ChakraPopover.Body
|
||||
export const PopoverTrigger = ChakraPopover.Trigger
|
||||
export const PopoverTitle = ChakraPopover.Title;
|
||||
export const PopoverDescription = ChakraPopover.Description;
|
||||
export const PopoverFooter = ChakraPopover.Footer;
|
||||
export const PopoverHeader = ChakraPopover.Header;
|
||||
export const PopoverRoot = ChakraPopover.Root;
|
||||
export const PopoverBody = ChakraPopover.Body;
|
||||
export const PopoverTrigger = ChakraPopover.Trigger;
|
||||
|
@ -1,15 +1,13 @@
|
||||
"use client"
|
||||
'use client';
|
||||
|
||||
import { ChakraProvider, defaultSystem } from "@chakra-ui/react"
|
||||
import {
|
||||
ColorModeProvider,
|
||||
type ColorModeProviderProps,
|
||||
} from "./color-mode"
|
||||
import { ChakraProvider, defaultSystem } from '@chakra-ui/react';
|
||||
|
||||
import { ColorModeProvider, type ColorModeProviderProps } from './color-mode';
|
||||
|
||||
export function Provider(props: ColorModeProviderProps) {
|
||||
return (
|
||||
<ChakraProvider value={defaultSystem}>
|
||||
<ColorModeProvider {...props} />
|
||||
</ChakraProvider>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
import { RadioGroup as ChakraRadioGroup } from "@chakra-ui/react"
|
||||
import * as React from "react"
|
||||
import * as React from 'react';
|
||||
|
||||
import { RadioGroup as ChakraRadioGroup } from '@chakra-ui/react';
|
||||
|
||||
export interface RadioProps extends ChakraRadioGroup.ItemProps {
|
||||
rootRef?: React.Ref<HTMLDivElement>
|
||||
inputProps?: React.InputHTMLAttributes<HTMLInputElement>
|
||||
rootRef?: React.Ref<HTMLDivElement>;
|
||||
inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
|
||||
}
|
||||
|
||||
export const Radio = React.forwardRef<HTMLInputElement, RadioProps>(
|
||||
function Radio(props, ref) {
|
||||
const { children, inputProps, rootRef, ...rest } = props
|
||||
const { children, inputProps, rootRef, ...rest } = props;
|
||||
return (
|
||||
<ChakraRadioGroup.Item ref={rootRef} {...rest}>
|
||||
<ChakraRadioGroup.ItemHiddenInput ref={ref} {...inputProps} />
|
||||
@ -17,8 +18,8 @@ export const Radio = React.forwardRef<HTMLInputElement, RadioProps>(
|
||||
<ChakraRadioGroup.ItemText>{children}</ChakraRadioGroup.ItemText>
|
||||
)}
|
||||
</ChakraRadioGroup.Item>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const RadioGroup = ChakraRadioGroup.Root
|
||||
export const RadioGroup = ChakraRadioGroup.Root;
|
||||
|
@ -1,23 +1,24 @@
|
||||
import { Slider as ChakraSlider, For, HStack } from "@chakra-ui/react"
|
||||
import * as React from "react"
|
||||
import * as React from 'react';
|
||||
|
||||
import { Slider as ChakraSlider, For, HStack } from '@chakra-ui/react';
|
||||
|
||||
export interface SliderProps extends ChakraSlider.RootProps {
|
||||
marks?: Array<number | { value: number; label: React.ReactNode }>
|
||||
label?: React.ReactNode
|
||||
showValue?: boolean
|
||||
marks?: Array<number | { value: number; label: React.ReactNode }>;
|
||||
label?: React.ReactNode;
|
||||
showValue?: boolean;
|
||||
}
|
||||
|
||||
export const Slider = React.forwardRef<HTMLDivElement, SliderProps>(
|
||||
function Slider(props, ref) {
|
||||
const { marks: marksProp, label, showValue, ...rest } = props
|
||||
const value = props.defaultValue ?? props.value
|
||||
const { marks: marksProp, label, showValue, ...rest } = props;
|
||||
const value = props.defaultValue ?? props.value;
|
||||
|
||||
const marks = marksProp?.map((mark) => {
|
||||
if (typeof mark === "number") return { value: mark, label: undefined }
|
||||
return mark
|
||||
})
|
||||
if (typeof mark === 'number') return { value: mark, label: undefined };
|
||||
return mark;
|
||||
});
|
||||
|
||||
const hasMarkLabel = !!marks?.some((mark) => mark.label)
|
||||
const hasMarkLabel = !!marks?.some((mark) => mark.label);
|
||||
|
||||
return (
|
||||
<ChakraSlider.Root ref={ref} thumbAlignment="center" {...rest}>
|
||||
@ -38,12 +39,12 @@ export const Slider = React.forwardRef<HTMLDivElement, SliderProps>(
|
||||
<SliderMarks marks={marks} />
|
||||
</ChakraSlider.Control>
|
||||
</ChakraSlider.Root>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
function SliderThumbs(props: { value?: number[] }) {
|
||||
const { value } = props
|
||||
const { value } = props;
|
||||
return (
|
||||
<For each={value}>
|
||||
{(_, index) => (
|
||||
@ -52,31 +53,31 @@ function SliderThumbs(props: { value?: number[] }) {
|
||||
</ChakraSlider.Thumb>
|
||||
)}
|
||||
</For>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
interface SliderMarksProps {
|
||||
marks?: Array<number | { value: number; label: React.ReactNode }>
|
||||
marks?: Array<number | { value: number; label: React.ReactNode }>;
|
||||
}
|
||||
|
||||
const SliderMarks = React.forwardRef<HTMLDivElement, SliderMarksProps>(
|
||||
function SliderMarks(props, ref) {
|
||||
const { marks } = props
|
||||
if (!marks?.length) return null
|
||||
const { marks } = props;
|
||||
if (!marks?.length) return null;
|
||||
|
||||
return (
|
||||
<ChakraSlider.MarkerGroup ref={ref}>
|
||||
{marks.map((mark, index) => {
|
||||
const value = typeof mark === "number" ? mark : mark.value
|
||||
const label = typeof mark === "number" ? undefined : mark.label
|
||||
const value = typeof mark === 'number' ? mark : mark.value;
|
||||
const label = typeof mark === 'number' ? undefined : mark.label;
|
||||
return (
|
||||
<ChakraSlider.Marker key={index} value={value}>
|
||||
<ChakraSlider.MarkerIndicator />
|
||||
{label}
|
||||
</ChakraSlider.Marker>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</ChakraSlider.MarkerGroup>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -1,6 +1,5 @@
|
||||
"use client"
|
||||
'use client';
|
||||
|
||||
import { RestErrorResponse } from "@/back-api";
|
||||
import {
|
||||
Toaster as ChakraToaster,
|
||||
Portal,
|
||||
@ -8,12 +7,14 @@ import {
|
||||
Stack,
|
||||
Toast,
|
||||
createToaster,
|
||||
} from "@chakra-ui/react"
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
import { RestErrorResponse } from '@/back-api';
|
||||
|
||||
export const toaster = createToaster({
|
||||
placement: "bottom-end",
|
||||
placement: 'bottom-end',
|
||||
pauseOnPageIdle: true,
|
||||
})
|
||||
});
|
||||
|
||||
export const toasterAPIError = (error: RestErrorResponse) => {
|
||||
toaster.create({
|
||||
@ -25,10 +26,10 @@ export const toasterAPIError = (error: RestErrorResponse) => {
|
||||
export const Toaster = () => {
|
||||
return (
|
||||
<Portal>
|
||||
<ChakraToaster toaster={toaster} insetInline={{ mdDown: "4" }}>
|
||||
<ChakraToaster toaster={toaster} insetInline={{ mdDown: '4' }}>
|
||||
{(toast) => (
|
||||
<Toast.Root width={{ md: "sm" }}>
|
||||
{toast.type === "loading" ? (
|
||||
<Toast.Root width={{ md: 'sm' }}>
|
||||
{toast.type === 'loading' ? (
|
||||
<Spinner size="sm" color="blue.solid" />
|
||||
) : (
|
||||
<Toast.Indicator />
|
||||
@ -47,5 +48,5 @@ export const Toaster = () => {
|
||||
)}
|
||||
</ChakraToaster>
|
||||
</Portal>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { Tooltip as ChakraTooltip, Portal } from "@chakra-ui/react"
|
||||
import * as React from "react"
|
||||
import * as React from 'react';
|
||||
|
||||
import { Tooltip as ChakraTooltip, Portal } from '@chakra-ui/react';
|
||||
|
||||
export interface TooltipProps extends ChakraTooltip.RootProps {
|
||||
showArrow?: boolean
|
||||
portalled?: boolean
|
||||
portalRef?: React.RefObject<HTMLElement>
|
||||
content: React.ReactNode
|
||||
contentProps?: ChakraTooltip.ContentProps
|
||||
disabled?: boolean
|
||||
showArrow?: boolean;
|
||||
portalled?: boolean;
|
||||
portalRef?: React.RefObject<HTMLElement>;
|
||||
content: React.ReactNode;
|
||||
contentProps?: ChakraTooltip.ContentProps;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
|
||||
@ -21,9 +22,9 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
|
||||
contentProps,
|
||||
portalRef,
|
||||
...rest
|
||||
} = props
|
||||
} = props;
|
||||
|
||||
if (disabled) return children
|
||||
if (disabled) return children;
|
||||
|
||||
return (
|
||||
<ChakraTooltip.Root {...rest}>
|
||||
@ -41,6 +42,6 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
|
||||
</ChakraTooltip.Positioner>
|
||||
</Portal>
|
||||
</ChakraTooltip.Root>
|
||||
)
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -1,28 +0,0 @@
|
||||
import dayjs from 'dayjs';
|
||||
import 'dayjs/locale/fr';
|
||||
import advancedFormat from 'dayjs/plugin/advancedFormat';
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
||||
import dayOfYear from 'dayjs/plugin/dayOfYear';
|
||||
import duration from 'dayjs/plugin/duration';
|
||||
import isBetween from 'dayjs/plugin/isBetween';
|
||||
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
|
||||
import isToday from 'dayjs/plugin/isToday';
|
||||
import isTomorrow from 'dayjs/plugin/isTomorrow';
|
||||
import isYesterday from 'dayjs/plugin/isYesterday';
|
||||
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import weekOfYear from 'dayjs/plugin/weekOfYear';
|
||||
|
||||
dayjs.locale('fr');
|
||||
dayjs.extend(relativeTime);
|
||||
dayjs.extend(customParseFormat);
|
||||
dayjs.extend(weekOfYear);
|
||||
dayjs.extend(isSameOrAfter);
|
||||
dayjs.extend(isToday);
|
||||
dayjs.extend(isTomorrow);
|
||||
dayjs.extend(isYesterday);
|
||||
dayjs.extend(dayOfYear);
|
||||
dayjs.extend(isBetween);
|
||||
dayjs.extend(advancedFormat);
|
||||
dayjs.extend(quarterOfYear);
|
||||
dayjs.extend(duration);
|
@ -1,2 +0,0 @@
|
||||
import './axios';
|
||||
import './dayjs';
|
@ -1,2 +0,0 @@
|
||||
export const DATE_FORMAT = 'YYYY-MM-DD';
|
||||
export const DATE_FORMAT_FULL = 'dddd DD MMMM HH:mm';
|
@ -1,4 +0,0 @@
|
||||
export const BASE_WRAP_SPACING = { base: "5px", md: "10px", lg: "20px" };
|
||||
export const BASE_WRAP_WIDTH = { base: "90%", md: "45%", lg: "270px" };
|
||||
export const BASE_WRAP_HEIGHT = { base: "75px", lg: "120px" };
|
||||
export const BASE_WRAP_ICON_SIZE = { base: "50px", lg: "100px" };
|
@ -1 +0,0 @@
|
||||
export * from './date'
|
@ -42,8 +42,9 @@ export const isDevelopmentEnvironment = () => {
|
||||
return import.meta.env.MODE === 'development';
|
||||
};
|
||||
|
||||
export const environment = isDevelopmentEnvironment() ? environment_local : environment_back_prod;
|
||||
|
||||
export const environment = isDevelopmentEnvironment()
|
||||
? environment_local
|
||||
: environment_back_prod;
|
||||
|
||||
/**
|
||||
* get the current REST api URL. Depend on the VITE_API_BASE_URL env variable.
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Box, Button, Center, Heading, Link, Text } from '@chakra-ui/react';
|
||||
import { Box, Center, Heading, Link, Text } from '@chakra-ui/react';
|
||||
import { MdControlCamera } from 'react-icons/md';
|
||||
|
||||
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
||||
@ -10,15 +10,17 @@ export const Error401 = () => {
|
||||
<TopBar />
|
||||
<PageLayoutInfoCenter padding="25px">
|
||||
<Center>
|
||||
<MdControlCamera style={{ width: "250px", height: "250px", color: "orange" }} />
|
||||
<MdControlCamera
|
||||
style={{ width: '250px', height: '250px', color: 'orange' }}
|
||||
/>
|
||||
</Center>
|
||||
<Box textAlign="center">
|
||||
<Heading>Erreur 401</Heading>
|
||||
<Heading>Error 401</Heading>
|
||||
<Text color="red.600">
|
||||
Vous n'êtes pas autorisé a accéder a ce contenu.
|
||||
You are not authorized to access this content.
|
||||
</Text>
|
||||
<Link as="a" href="/">
|
||||
Retour à l'accueil
|
||||
Back to Homepage
|
||||
</Link>
|
||||
</Box>
|
||||
</PageLayoutInfoCenter>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Box, Button, Center, Heading, Link, Text } from '@chakra-ui/react';
|
||||
import { Box, Center, Heading, Link, Text } from '@chakra-ui/react';
|
||||
import { MdDangerous } from 'react-icons/md';
|
||||
|
||||
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
||||
@ -10,14 +10,14 @@ export const Error403 = () => {
|
||||
<TopBar />
|
||||
<PageLayoutInfoCenter padding="25px">
|
||||
<Center>
|
||||
<MdDangerous style={{ width: "250px", height: "250px", color: "red" }} />
|
||||
<MdDangerous
|
||||
style={{ width: '250px', height: '250px', color: 'red' }}
|
||||
/>
|
||||
</Center>
|
||||
<Box textAlign="center">
|
||||
<Heading>Erreur 403</Heading>
|
||||
<Text color="orange.600">Cette page vous est interdite</Text>
|
||||
<Link href="/">
|
||||
Retour à l'accueil
|
||||
</Link>
|
||||
<Heading>Error 403</Heading>
|
||||
<Text color="orange.600">This page is forbidden to you.</Text>
|
||||
<Link href="/">Back to Homepage</Link>
|
||||
</Box>
|
||||
</PageLayoutInfoCenter>
|
||||
</>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Box, Button, Center, Heading, Link, Text } from '@chakra-ui/react';
|
||||
import { Box, Center, Heading, Link, Text } from '@chakra-ui/react';
|
||||
import { MdSignpost } from 'react-icons/md';
|
||||
|
||||
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
|
||||
@ -10,16 +10,16 @@ export const Error404 = () => {
|
||||
<TopBar />
|
||||
<PageLayoutInfoCenter padding="25px">
|
||||
<Center>
|
||||
<MdSignpost style={{ width: "250px", height: "250px", color: "aqua" }} />
|
||||
<MdSignpost
|
||||
style={{ width: '250px', height: '250px', color: 'aqua' }}
|
||||
/>
|
||||
</Center>
|
||||
<Box textAlign="center">
|
||||
<Heading>Erreur 404</Heading>
|
||||
<Heading>Error 404</Heading>
|
||||
<Text color="gray.600">
|
||||
Cette page n'existe plus ou l'URL a changé
|
||||
This page no longer exists or the URL has changed.
|
||||
</Text>
|
||||
<Link href="/">
|
||||
Retour à l'accueil
|
||||
</Link>
|
||||
<Link href="/">Back to Homepage</Link>
|
||||
</Box>
|
||||
</PageLayoutInfoCenter>
|
||||
</>
|
||||
|
@ -1,11 +1,6 @@
|
||||
import React, { FC } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import {
|
||||
AlertDescription,
|
||||
AlertTitle,
|
||||
Box,
|
||||
Alert,
|
||||
} from '@chakra-ui/react';
|
||||
import { Alert, AlertDescription, AlertTitle, Box } from '@chakra-ui/react';
|
||||
import {
|
||||
FallbackProps,
|
||||
ErrorBoundary as ReactErrorBoundary,
|
||||
@ -17,8 +12,15 @@ const ErrorFallback = ({ error }: FallbackProps) => {
|
||||
<Alert.Root status="error" borderRadius="md">
|
||||
<Alert.Indicator height="75px" width="75px" />
|
||||
<Box flex="1">
|
||||
<AlertTitle fontWeight="bold" fontSize="35px">An unexpected error has occurred.</AlertTitle>
|
||||
<AlertDescription padding="5" marginTop="3" fontSize="20px" lineHeight="1.4">
|
||||
<AlertTitle fontWeight="bold" fontSize="35px">
|
||||
An unexpected error has occurred.
|
||||
</AlertTitle>
|
||||
<AlertDescription
|
||||
padding="5"
|
||||
marginTop="3"
|
||||
fontSize="20px"
|
||||
lineHeight="1.4"
|
||||
>
|
||||
<br />
|
||||
{error.message}
|
||||
</AlertDescription>
|
||||
@ -28,6 +30,6 @@ const ErrorFallback = ({ error }: FallbackProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const ErrorBoundary: FC<React.PropsWithChildren<unknown>> = (props) => {
|
||||
export const ErrorBoundary = ({ children }: { children: ReactNode }) => {
|
||||
return <ReactErrorBoundary FallbackComponent={ErrorFallback} {...props} />;
|
||||
};
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { StrictMode } from 'react';
|
||||
|
||||
import { ChakraProvider } from '@chakra-ui/react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
|
||||
import App from '@/App';
|
||||
import { ColorModeProvider } from './components/ui/color-mode';
|
||||
|
||||
import { ChakraProvider } from '@chakra-ui/react';
|
||||
import { systemTheme } from './theme/theme';
|
||||
import { ColorModeProvider } from './components/ui/color-mode';
|
||||
import { Toaster } from './components/ui/toaster';
|
||||
import { systemTheme } from './theme/theme';
|
||||
|
||||
// Render the app
|
||||
const rootElement = document.getElementById('root');
|
||||
|
@ -9,11 +9,12 @@ import { Error404 } from '@/errors';
|
||||
import { HelpPage } from '@/scene/home/HelpPage';
|
||||
import { HomePage } from '@/scene/home/HomePage';
|
||||
import { useHasRight } from '@/service/session';
|
||||
import { SettingsPage } from './home/SettingsPage';
|
||||
|
||||
import { ManageAccountPage } from './account/ManageAccountPage';
|
||||
import { SignInDonePage } from './connection/SignInDonePage';
|
||||
import { SignInPage } from './connection/SignInPage';
|
||||
import { SignOutPage } from './connection/SignOutPage';
|
||||
import { SignInDonePage } from './connection/SignInDonePage';
|
||||
import { ManageAccountPage } from './account/ManageAccountPage';
|
||||
import { SettingsPage } from './home/SettingsPage';
|
||||
|
||||
export const AppRoutes = () => {
|
||||
const { isReadable } = useHasRight('USER');
|
||||
@ -28,8 +29,14 @@ export const AppRoutes = () => {
|
||||
<>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
{/* Connection page after SSO */}
|
||||
<Route path="signin/:applicationName/:applicationData/*" element={<SignInDonePage />} />
|
||||
<Route path="signin/:applicationName/*" element={<SignInDonePage />} />
|
||||
<Route
|
||||
path="signin/:applicationName/:applicationData/*"
|
||||
element={<SignInDonePage />}
|
||||
/>
|
||||
<Route
|
||||
path="signin/:applicationName/*"
|
||||
element={<SignInDonePage />}
|
||||
/>
|
||||
<Route path="signout/*" element={<SignOutPage />} />
|
||||
<Route path="manage-account/*" element={<ManageAccountPage />} />
|
||||
<Route path="help" element={<HelpPage />} />
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { useSessionService } from '@/service/session';
|
||||
|
||||
export const SignOutPage = () => {
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { UserResource } from '@/back-api';
|
||||
import { toaster, toasterAPIError } from '@/components/ui/toaster';
|
||||
import { useSessionService } from '@/service/session';
|
||||
//import { useSessionContext } from '@/context/SessionContext';
|
||||
import { getRestConfig } from '@/utils/http';
|
||||
import { sha512 } from '@/utils/sha512';
|
||||
import { toaster, toasterAPIError } from '@/components/ui/toaster';
|
||||
import { useSessionService } from '@/service/session';
|
||||
import { UserResource } from '@/back-api';
|
||||
|
||||
export const useLogin = () => {
|
||||
const [isConnectionLoading, setIsConnectionLoading] =
|
||||
|
@ -5,9 +5,7 @@ export const HelpPage = () => {
|
||||
return (
|
||||
<>
|
||||
<TopBar title="Help" />
|
||||
<PageLayout>
|
||||
No help available right now
|
||||
</PageLayout>
|
||||
<PageLayout>No help available right now</PageLayout>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,14 +1,11 @@
|
||||
import { PageLayout } from '@/components/Layout/PageLayout';
|
||||
import { TopBar } from '@/components/TopBar/TopBar';
|
||||
|
||||
|
||||
export const SettingsPage = () => {
|
||||
return (
|
||||
<>
|
||||
<TopBar title="Help" />
|
||||
<PageLayout>
|
||||
No settings available right now
|
||||
</PageLayout>
|
||||
<PageLayout>No settings available right now</PageLayout>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,11 +1,15 @@
|
||||
import { ApplicationToken, ApplicationTokenResource, CreateTokenRequestWrite, Integer, Long, RestErrorResponse } from '@/back-api';
|
||||
import {
|
||||
ApplicationToken,
|
||||
ApplicationTokenResource,
|
||||
CreateTokenRequestWrite,
|
||||
Integer,
|
||||
Long,
|
||||
RestErrorResponse,
|
||||
} from '@/back-api';
|
||||
import { useSessionService } from '@/service/session';
|
||||
import { useQuery, useQueryCall, useQueryCallProps } from '@/utils/query';
|
||||
|
||||
|
||||
export namespace ApplicationTokenService {
|
||||
|
||||
|
||||
export const useApplicationTokens = (applicationId: Long) => {
|
||||
const { getRestConfig } = useSessionService();
|
||||
return useQuery({
|
||||
@ -13,7 +17,7 @@ export namespace ApplicationTokenService {
|
||||
return ApplicationTokenResource.gets({
|
||||
restConfig: getRestConfig(),
|
||||
params: {
|
||||
applicationId
|
||||
applicationId,
|
||||
},
|
||||
});
|
||||
},
|
||||
@ -22,10 +26,15 @@ export namespace ApplicationTokenService {
|
||||
|
||||
export const useApplicationTokenCreate = (
|
||||
applicationId: Long,
|
||||
config: { config?: Omit<useQueryCallProps<ApplicationToken, any>, 'queryFunction'> }
|
||||
config: {
|
||||
config?: Omit<useQueryCallProps<ApplicationToken, any>, 'queryFunction'>;
|
||||
}
|
||||
) => {
|
||||
const { getRestConfig } = useSessionService();
|
||||
const { call, ...rest } = useQueryCall<ApplicationToken, CreateTokenRequestWrite>({
|
||||
const { call, ...rest } = useQueryCall<
|
||||
ApplicationToken,
|
||||
CreateTokenRequestWrite
|
||||
>({
|
||||
queryFunction: (inputData) => {
|
||||
return ApplicationTokenResource.create({
|
||||
restConfig: getRestConfig(),
|
||||
@ -43,15 +52,18 @@ export namespace ApplicationTokenService {
|
||||
config: { config?: Omit<useQueryCallProps<void, any>, 'queryFunction'> }
|
||||
) => {
|
||||
const { getRestConfig } = useSessionService();
|
||||
const { call, ...rest } = useQueryCall<void, {
|
||||
tokenId: Integer,
|
||||
}>({
|
||||
const { call, ...rest } = useQueryCall<
|
||||
void,
|
||||
{
|
||||
tokenId: Integer;
|
||||
}
|
||||
>({
|
||||
queryFunction: (inputData) => {
|
||||
return ApplicationTokenResource.remove({
|
||||
restConfig: getRestConfig(),
|
||||
params: {
|
||||
applicationId,
|
||||
...inputData
|
||||
...inputData,
|
||||
},
|
||||
});
|
||||
},
|
||||
@ -59,5 +71,4 @@ export namespace ApplicationTokenService {
|
||||
});
|
||||
return { removeApplicationToken: call, ...rest };
|
||||
};
|
||||
|
||||
}
|
@ -11,8 +11,6 @@ export type ServiceContextType = {
|
||||
session: SessionServiceProps;
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const ServiceContext = createContext<ServiceContextType>({
|
||||
session: {
|
||||
isConnected: false,
|
||||
|
@ -22,7 +22,7 @@ export function getRestConfig(): RESTConfig {
|
||||
|
||||
export type SessionServiceProps = {
|
||||
token?: string;
|
||||
isConnected: boolean,
|
||||
isConnected: boolean;
|
||||
setToken: (token: string) => void;
|
||||
clearToken: () => void;
|
||||
login?: string;
|
||||
@ -59,7 +59,6 @@ export const useSessionServiceWrapped = (): SessionServiceProps => {
|
||||
localStorage.setItem(TOKEN_KEY, token);
|
||||
}
|
||||
}
|
||||
|
||||
}, [localStorage, parseToken, token]);
|
||||
|
||||
const setTokenLocal = useCallback(
|
||||
@ -71,7 +70,7 @@ export const useSessionServiceWrapped = (): SessionServiceProps => {
|
||||
);
|
||||
|
||||
const clearToken = useCallback(() => {
|
||||
console.log("Clear Token");
|
||||
console.log('Clear Token');
|
||||
setToken(undefined);
|
||||
updateRight();
|
||||
}, [updateRight, setToken]);
|
||||
@ -85,7 +84,9 @@ export const useSessionServiceWrapped = (): SessionServiceProps => {
|
||||
if (right === undefined) {
|
||||
return false;
|
||||
}
|
||||
return [PartRight.READ, PartRight.READ_WRITE].includes(right?.[group] ?? 0);
|
||||
return [PartRight.READ, PartRight.READ_WRITE].includes(
|
||||
right?.[group] ?? 0
|
||||
);
|
||||
},
|
||||
[config]
|
||||
);
|
||||
@ -99,7 +100,9 @@ export const useSessionServiceWrapped = (): SessionServiceProps => {
|
||||
if (right === undefined) {
|
||||
return false;
|
||||
}
|
||||
return [PartRight.READ, PartRight.READ_WRITE].includes(right?.[group] ?? 0);
|
||||
return [PartRight.READ, PartRight.READ_WRITE].includes(
|
||||
right?.[group] ?? 0
|
||||
);
|
||||
},
|
||||
[config]
|
||||
);
|
||||
|
@ -3,13 +3,17 @@
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @license PROPRIETARY (see license file)
|
||||
*/
|
||||
import {
|
||||
RESTConfig,
|
||||
UserAuthGet,
|
||||
UserCreateWrite,
|
||||
UserResource,
|
||||
} from '@/back-api';
|
||||
import { useQuery, useQueryCall, useQueryCallProps } from '@/utils/query';
|
||||
|
||||
import { RESTConfig, UserAuthGet, UserCreateWrite, UserResource } from "@/back-api";
|
||||
import { useQuery, useQueryCall, useQueryCallProps } from "@/utils/query";
|
||||
import { useSessionService } from "./session";
|
||||
import { useSessionService } from './session';
|
||||
|
||||
export namespace UserService {
|
||||
|
||||
// export const useGetData = <RETURN_TYPE>(queryFunction: (config: RESTConfig) => Promise<RETURN_TYPE>) => {
|
||||
// const { getRestConfig } = useSessionService();
|
||||
// return useQuery({ queryFunction: () => queryFunction(getRestConfig()) });
|
||||
@ -26,12 +30,16 @@ export namespace UserService {
|
||||
return useQuery({
|
||||
queryFunction: () => {
|
||||
return UserResource.gets({
|
||||
restConfig: getRestConfig()
|
||||
restConfig: getRestConfig(),
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
export const useCreate = ({ config }: { config?: Omit<useQueryCallProps<UserAuthGet, any>, 'queryFunction'> }) => {
|
||||
export const useCreate = ({
|
||||
config,
|
||||
}: {
|
||||
config?: Omit<useQueryCallProps<UserAuthGet, any>, 'queryFunction'>;
|
||||
}) => {
|
||||
const { getRestConfig } = useSessionService();
|
||||
return useQueryCall<UserAuthGet, UserCreateWrite>({
|
||||
queryFunction: (data) => {
|
||||
@ -40,8 +48,7 @@ export namespace UserService {
|
||||
data: { ...data },
|
||||
});
|
||||
},
|
||||
...config
|
||||
...config,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
type PandaColorModel = {
|
||||
value: string;
|
||||
}
|
||||
};
|
||||
type ThemeModel = {
|
||||
50: PandaColorModel;
|
||||
100: PandaColorModel;
|
||||
|
@ -1,5 +1,11 @@
|
||||
import { createSystem, defaultConfig, mergeConfigs, SystemConfig } from "@chakra-ui/react"
|
||||
import { colors } from "./colors"
|
||||
import {
|
||||
SystemConfig,
|
||||
createSystem,
|
||||
defaultConfig,
|
||||
mergeConfigs,
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
import { colors } from './colors';
|
||||
|
||||
const baseTheme: SystemConfig = {
|
||||
globalCss: {
|
||||
@ -8,25 +14,23 @@ const baseTheme: SystemConfig = {
|
||||
bg: { _light: 'back.50', _dark: 'back.700' },
|
||||
color: { _light: 'text.900', _dark: 'text.50' },
|
||||
fontFamily: 'Roboto, Helvetica, Arial, "sans-serif"',
|
||||
userSelect: 'none', /* Prevents text selection */
|
||||
userSelect: 'none' /* Prevents text selection */,
|
||||
},
|
||||
svg: {
|
||||
width: "32px",
|
||||
height: "32px",
|
||||
aspectRatio: "square",
|
||||
}
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
aspectRatio: 'square',
|
||||
},
|
||||
},
|
||||
theme: {
|
||||
slotRecipes: {
|
||||
dialog: {
|
||||
slots: [
|
||||
"header"
|
||||
],
|
||||
slots: ['header'],
|
||||
base: {
|
||||
header: {
|
||||
fontWeight: "bold",
|
||||
fontSize: "2xl",
|
||||
color: { _dark: "brand.400", _light: "brand.500" }
|
||||
fontWeight: 'bold',
|
||||
fontSize: '2xl',
|
||||
color: { _dark: 'brand.400', _light: 'brand.500' },
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -36,21 +40,27 @@ const baseTheme: SystemConfig = {
|
||||
base: {
|
||||
borderRadius: 0,
|
||||
_hover: {
|
||||
boxShadow: { _light: "0 8px 20px #000000e6", _dark: "0 8px 20px #000000e6" }
|
||||
boxShadow: {
|
||||
_light: '0 8px 20px #000000e6',
|
||||
_dark: '0 8px 20px #000000e6',
|
||||
},
|
||||
},
|
||||
transitionDuration: 'slower',
|
||||
},
|
||||
transitionDuration: "slower"
|
||||
}
|
||||
},
|
||||
input: {
|
||||
base: {
|
||||
borderRadius: 0,
|
||||
_hover: {
|
||||
boxShadow: { _light: "0 2px 5px #000000e6", _dark: "0 2px 5px #000000e6" }
|
||||
boxShadow: {
|
||||
_light: '0 2px 5px #000000e6',
|
||||
_dark: '0 2px 5px #000000e6',
|
||||
},
|
||||
},
|
||||
//borderColor: { _light: "gray.800", _dark: "gray.50" },
|
||||
backgroundColor: { _light: "gray.200", _dark: "gray.700" },
|
||||
transitionDuration: "slower"
|
||||
}
|
||||
backgroundColor: { _light: 'gray.200', _dark: 'gray.700' },
|
||||
transitionDuration: 'slower',
|
||||
},
|
||||
},
|
||||
},
|
||||
tokens: {
|
||||
@ -62,23 +72,23 @@ const baseTheme: SystemConfig = {
|
||||
},
|
||||
semanticTokens: {
|
||||
colors: {
|
||||
"@danger": {
|
||||
solid: { value: "{colors.danger.500}" },
|
||||
contrast: { value: "{colors.danger.100}" },
|
||||
fg: { value: "{colors.danger.900}" },
|
||||
muted: { value: "{colors.danger.100}" },
|
||||
subtle: { value: "{colors.danger.200}" },
|
||||
emphasized: { value: "{colors.danger.300}" },
|
||||
focusRing: { value: "{colors.danger.500}" },
|
||||
'@danger': {
|
||||
solid: { value: '{colors.danger.500}' },
|
||||
contrast: { value: '{colors.danger.100}' },
|
||||
fg: { value: '{colors.danger.900}' },
|
||||
muted: { value: '{colors.danger.100}' },
|
||||
subtle: { value: '{colors.danger.200}' },
|
||||
emphasized: { value: '{colors.danger.300}' },
|
||||
focusRing: { value: '{colors.danger.500}' },
|
||||
},
|
||||
"brand": {
|
||||
solid: { value: "{colors.brand.500}" },
|
||||
contrast: { value: "{colors.brand.100}" },
|
||||
fg: { value: "{colors.brand.900}" },
|
||||
muted: { value: "{colors.brand.100}" },
|
||||
subtle: { value: "{colors.brand.200}" },
|
||||
emphasized: { value: "{colors.brand.300}" },
|
||||
focusRing: { value: "{colors.brand.500}" },
|
||||
brand: {
|
||||
solid: { value: '{colors.brand.500}' },
|
||||
contrast: { value: '{colors.brand.100}' },
|
||||
fg: { value: '{colors.brand.900}' },
|
||||
muted: { value: '{colors.brand.100}' },
|
||||
subtle: { value: '{colors.brand.200}' },
|
||||
emphasized: { value: '{colors.brand.300}' },
|
||||
focusRing: { value: '{colors.brand.500}' },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1,11 +1,8 @@
|
||||
|
||||
|
||||
export function arrayUnique(array: any[]) {
|
||||
var a = array.concat();
|
||||
for (var i = 0; i < a.length; ++i) {
|
||||
for (var j = i + 1; j < a.length; ++j) {
|
||||
if (a[i] === a[j])
|
||||
a.splice(j--, 1);
|
||||
if (a[i] === a[j]) a.splice(j--, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
import { DependencyList, useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { RestErrorResponse } from '@/back-api';
|
||||
import { isNullOrUndefined } from '@/utils/validator';
|
||||
import { toasterAPIError } from '@/components/ui/toaster';
|
||||
import { isNullOrUndefined } from '@/utils/validator';
|
||||
|
||||
export type DataStoreType<TYPE> = {
|
||||
isLoading: boolean;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { JwtToken, RESTConfig } from '@/back-api';
|
||||
import { RESTConfig } from '@/back-api';
|
||||
import { getApiUrl } from '@/environment';
|
||||
import { getUserToken } from '@/service/session';
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
import { RestErrorResponse } from "@/back-api";
|
||||
import { toasterAPIError, toaster } from "@/components/ui/toaster";
|
||||
import { useSessionService } from "@/service/session";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { RestErrorResponse } from '@/back-api';
|
||||
import { toaster, toasterAPIError } from '@/components/ui/toaster';
|
||||
import { useSessionService } from '@/service/session';
|
||||
|
||||
export type useQueryProps<TYPE> = {
|
||||
queryFunction: () => Promise<TYPE>;
|
||||
onSuccess?: (data: TYPE) => Promise<TYPE>;
|
||||
onFail?: (error: RestErrorResponse) => void;
|
||||
}
|
||||
export const useQuery = <TYPE,>({
|
||||
};
|
||||
export const useQuery = <TYPE>({
|
||||
queryFunction,
|
||||
onSuccess,
|
||||
onFail,
|
||||
@ -18,13 +19,15 @@ export const useQuery = <TYPE,>({
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
const [error, setError] = useState<RestErrorResponse | undefined>(undefined);
|
||||
useEffect(() => {
|
||||
queryFunction().then((received) => {
|
||||
queryFunction()
|
||||
.then((received) => {
|
||||
setData(received);
|
||||
setIsLoading(false);
|
||||
if (onSuccess) {
|
||||
onSuccess(received);
|
||||
}
|
||||
}).catch((error) => {
|
||||
})
|
||||
.catch((error) => {
|
||||
setError(error);
|
||||
setIsLoading(false);
|
||||
if (onFail) {
|
||||
@ -35,19 +38,19 @@ export const useQuery = <TYPE,>({
|
||||
// Authentication error ==> auto_disconnect
|
||||
clearToken();
|
||||
toaster.create({
|
||||
title: "Disconnected by server",
|
||||
description: "Token is no more available",
|
||||
title: 'Disconnected by server',
|
||||
description: 'Token is no more available',
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [setError, setIsLoading, setData, toasterAPIError, clearToken, toaster])
|
||||
}, [setError, setIsLoading, setData, toasterAPIError, clearToken, toaster]);
|
||||
return { data, isLoading, error };
|
||||
}
|
||||
};
|
||||
export type useQueryCallProps<RETURN_TYPE, PARAMETER_TYPE> = {
|
||||
queryFunction: (params: PARAMETER_TYPE) => Promise<RETURN_TYPE>;
|
||||
onSuccess?: (data: RETURN_TYPE) => Promise<RETURN_TYPE>;
|
||||
onFail?: (error: RestErrorResponse) => void;
|
||||
}
|
||||
};
|
||||
export const useQueryCall = <TYPE, PARAMETERS>({
|
||||
queryFunction,
|
||||
onSuccess,
|
||||
@ -57,12 +60,14 @@ export const useQueryCall = <TYPE, PARAMETERS>({
|
||||
const [isCalling, setIsCalling] = useState<boolean>(true);
|
||||
const [error, setError] = useState<RestErrorResponse | undefined>(undefined);
|
||||
const call = (params: PARAMETERS) => {
|
||||
queryFunction(params).then((received) => {
|
||||
queryFunction(params)
|
||||
.then((received) => {
|
||||
setIsCalling(false);
|
||||
if (onSuccess) {
|
||||
onSuccess(received);
|
||||
}
|
||||
}).catch((error) => {
|
||||
})
|
||||
.catch((error) => {
|
||||
setIsCalling(false);
|
||||
if (onFail) {
|
||||
onFail(error);
|
||||
@ -73,11 +78,11 @@ export const useQueryCall = <TYPE, PARAMETERS>({
|
||||
// Authentication error ==> auto_disconnect
|
||||
clearToken();
|
||||
toaster.create({
|
||||
title: "Disconnected by server",
|
||||
description: "Token is no more available",
|
||||
title: 'Disconnected by server',
|
||||
description: 'Token is no more available',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
return { call, isCalling, error };
|
||||
}
|
||||
};
|
||||
|
@ -117,7 +117,8 @@ export function sha512(str) {
|
||||
let len = data.length * charsize;
|
||||
|
||||
for (let i = 0; i < len; i += charsize) {
|
||||
bin[i >> 5] |= (data.charCodeAt(i / charsize) & mask) << (32 - charsize - (i % 32));
|
||||
bin[i >> 5] |=
|
||||
(data.charCodeAt(i / charsize) & mask) << (32 - charsize - (i % 32));
|
||||
}
|
||||
|
||||
return bin;
|
||||
@ -131,7 +132,8 @@ export function sha512(str) {
|
||||
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8);
|
||||
data += hex_tab.charAt((srcByte >> 4) & 0xf) + hex_tab.charAt(srcByte & 0xf);
|
||||
data +=
|
||||
hex_tab.charAt((srcByte >> 4) & 0xf) + hex_tab.charAt(srcByte & 0xf);
|
||||
}
|
||||
|
||||
return data;
|
||||
@ -154,8 +156,17 @@ export function sha512(str) {
|
||||
function safe_add_4(a, b, c, d) {
|
||||
let lsw, msw, lowOrder, highOrder;
|
||||
|
||||
lsw = (a.lowOrder & 0xffff) + (b.lowOrder & 0xffff) + (c.lowOrder & 0xffff) + (d.lowOrder & 0xffff);
|
||||
msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (lsw >>> 16);
|
||||
lsw =
|
||||
(a.lowOrder & 0xffff) +
|
||||
(b.lowOrder & 0xffff) +
|
||||
(c.lowOrder & 0xffff) +
|
||||
(d.lowOrder & 0xffff);
|
||||
msw =
|
||||
(a.lowOrder >>> 16) +
|
||||
(b.lowOrder >>> 16) +
|
||||
(c.lowOrder >>> 16) +
|
||||
(d.lowOrder >>> 16) +
|
||||
(lsw >>> 16);
|
||||
lowOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
|
||||
|
||||
lsw =
|
||||
@ -164,7 +175,12 @@ export function sha512(str) {
|
||||
(c.highOrder & 0xffff) +
|
||||
(d.highOrder & 0xffff) +
|
||||
(msw >>> 16);
|
||||
msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + (c.highOrder >>> 16) + (d.highOrder >>> 16) + (lsw >>> 16);
|
||||
msw =
|
||||
(a.highOrder >>> 16) +
|
||||
(b.highOrder >>> 16) +
|
||||
(c.highOrder >>> 16) +
|
||||
(d.highOrder >>> 16) +
|
||||
(lsw >>> 16);
|
||||
highOrder = ((msw & 0xffff) << 16) | (lsw & 0xffff);
|
||||
|
||||
return new int64(highOrder, lowOrder);
|
||||
@ -209,8 +225,12 @@ export function sha512(str) {
|
||||
|
||||
function maj(x, y, z) {
|
||||
return new int64(
|
||||
(x.highOrder & y.highOrder) ^ (x.highOrder & z.highOrder) ^ (y.highOrder & z.highOrder),
|
||||
(x.lowOrder & y.lowOrder) ^ (x.lowOrder & z.lowOrder) ^ (y.lowOrder & z.lowOrder)
|
||||
(x.highOrder & y.highOrder) ^
|
||||
(x.highOrder & z.highOrder) ^
|
||||
(y.highOrder & z.highOrder),
|
||||
(x.lowOrder & y.lowOrder) ^
|
||||
(x.lowOrder & z.lowOrder) ^
|
||||
(y.lowOrder & z.lowOrder)
|
||||
);
|
||||
}
|
||||
|
||||
@ -281,7 +301,10 @@ export function sha512(str) {
|
||||
|
||||
function shr(x, n) {
|
||||
if (n <= 32) {
|
||||
return new int64(x.highOrder >>> n, (x.lowOrder >>> n) | (x.highOrder << (32 - n)));
|
||||
return new int64(
|
||||
x.highOrder >>> n,
|
||||
(x.lowOrder >>> n) | (x.highOrder << (32 - n))
|
||||
);
|
||||
} else {
|
||||
return new int64(0, x.highOrder << (32 - n));
|
||||
}
|
||||
@ -308,7 +331,12 @@ export function sha512(str) {
|
||||
if (j < 16) {
|
||||
W[j] = new int64(str[j * 2 + i], str[j * 2 + i + 1]);
|
||||
} else {
|
||||
W[j] = safe_add_4(gamma1(W[j - 2]), W[j - 7], gamma0(W[j - 15]), W[j - 16]);
|
||||
W[j] = safe_add_4(
|
||||
gamma1(W[j - 2]),
|
||||
W[j - 7],
|
||||
gamma0(W[j - 15]),
|
||||
W[j - 16]
|
||||
);
|
||||
}
|
||||
|
||||
T1 = safe_add_5(h, sigma1(e), ch(e, f, g), K[j], W[j]);
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
export function isNumeric(val: string): boolean {
|
||||
return !isNaN(Number(val));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user