Merge branch 'dev' into staging

This commit is contained in:
Max S 2024-07-26 10:43:49 +02:00
commit 4d28547d93
15 changed files with 274 additions and 20 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

5
public/favicon.svg Normal file
View File

@ -0,0 +1,5 @@
<svg width="256" height="256" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="256" height="256" rx="128" fill="white"/>
<path d="M185.067 93.7936C185.647 94.7771 186.831 95.2561 187.94 94.9282L206.362 89.4058C207.345 89.1284 208 88.2206 208 87.2372V52.4634C208 49.9922 206.009 48 203.539 48H51.7297C49.4869 48 48.126 49.5131 48.126 51.7069L48 131.341V203.537C48 206.008 49.9909 208 52.4606 208H204.27C206.513 208 207.874 206.487 207.874 204.268L208 124.659V124.407C208 121.456 207.572 119.414 203.565 120.548L196.332 122.692C195.173 123.045 194.417 124.129 194.467 125.314L194.593 127.987C194.593 159.685 178.087 182.43 148.955 191.357C101.3 205.957 57.8283 168.536 61.6841 122.213C64.3554 90.4145 89.909 64.5925 121.662 61.6674C148.526 59.1962 172.442 72.6872 185.042 93.7431L185.067 93.7936Z" fill="#005BCB"/>
<path d="M153.011 159.962C159.739 155.322 164.931 148.615 167.677 140.772C168.408 138.629 168.988 136.385 169.341 134.09C169.567 132.703 168.257 131.543 166.921 131.972L154.548 135.855C154.019 136.032 153.59 136.435 153.389 136.965C149.482 146.724 139.402 153.305 128.011 151.918C116.898 150.556 108.002 141.327 107.019 130.181C106.691 126.449 107.221 122.869 108.405 119.616C111.807 110.437 120.653 103.88 131.01 103.88C136.857 103.88 142.225 105.973 146.408 109.453C146.887 109.857 147.542 110.008 148.172 109.806L159.916 106.125C160.571 105.923 160.999 105.419 161.176 104.864C161.327 104.284 161.251 103.628 160.823 103.124C153.237 94.0206 141.544 88.4478 128.566 89.2295C128.415 89.2547 128.263 89.2799 128.112 89.2799L124.105 76.5202C123.601 74.8559 121.837 73.9228 120.174 74.4272L111.051 77.2767C109.388 77.8062 108.455 79.5714 108.985 81.2357L111.958 90.7425C112.488 92.4068 111.832 94.2224 110.371 95.1554C103.138 99.7448 97.4679 106.654 94.5194 114.824C93.3098 118.103 92.5538 121.582 92.3017 125.188C92.2261 126.525 92.2009 127.836 92.2513 129.122C92.3269 130.862 91.1929 132.426 89.5297 132.955L79.4997 136.183C77.8365 136.713 76.904 138.478 77.4081 140.142L80.2558 149.27C80.785 150.935 82.5491 151.842 84.2123 151.338L94.4186 148.035C96.0315 147.53 97.8207 148.11 98.7532 149.523C105.709 159.937 117.553 166.821 131.01 166.821C131.59 166.821 132.144 166.821 132.699 166.821C134.463 166.72 136.05 167.855 136.58 169.519L139.679 179.505C140.208 181.17 141.973 182.103 143.636 181.573L152.758 178.724C154.422 178.219 155.329 176.429 154.825 174.765L151.549 164.325C151.045 162.711 151.624 160.946 153.011 159.988V159.962Z" fill="#005BCB"/>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,15 +1,15 @@
{ {
"short_name": "lecoffre", "short_name": "lecoffre",
"name": "lecoffre", "name": "lecoffre",
"icons": [ "icons": [
{ {
"src": "/favicon.ico", "src": "/favicon.svg",
"sizes": "32x32 16x16", "sizes": "32x32 16x16",
"type": "image/x-icon" "type": "image/x-icon"
} }
], ],
"start_url": ".", "start_url": ".",
"display": "standalone", "display": "standalone",
"theme_color": "light", "theme_color": "light",
"background_color": "light" "background_color": "light"
} }

View File

@ -0,0 +1,21 @@
.root {
display: flex;
padding: var(--spacing-1, 8px) var(--spacing-2, 16px);
align-items: center;
gap: var(--spacing-sm, 8px);
justify-content: space-between;
border-radius: var(--dropdown-radius, 0px);
border: 1px solid var(--dropdown-border, rgba(0, 0, 0, 0));
background: var(--dropdown-option-background-default, #fff);
&:hover {
background-color: var(--dropdown-option-background-hovered);
}
&:focus,
&:active {
background-color: var(--dropdown-option-background-pressed);
}
}

View File

@ -0,0 +1,34 @@
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
import { CheckIcon } from "@heroicons/react/24/outline";
import { useCallback } from "react";
import classes from "./classes.module.scss";
import IconButton from "@Front/Components/DesignSystem/IconButton";
export type IOption = {
id: string;
label: string;
};
type IProps = {
option: IOption;
isActive: boolean;
onClick?: (option: IOption) => void;
};
export default function DropdownOption(props: IProps) {
const { option, onClick, isActive } = props;
const handleOnClick = useCallback(() => onClick && onClick(option), [onClick, option]);
return (
<div className={classes["root"]} onClick={handleOnClick}>
<Typography
typo={isActive ? ETypo.TEXT_MD_SEMIBOLD : ETypo.TEXT_MD_REGULAR}
color={isActive ? ETypoColor.DROPDOWN_CONTRAST_ACTIVE : ETypoColor.DROPDOWN_CONTRAST_DEFAULT}>
{option.label}
</Typography>
{isActive && <IconButton icon={<CheckIcon />} />}
</div>
);
}

View File

@ -0,0 +1,35 @@
.root {
position: relative;
overflow: hidden;
.content {
width: 100%;
display: flex;
flex-direction: column;
gap: 8px;
padding: var(--spacing-sm, 8px);
border-radius: var(--dropdown-radius, 0px);
background: var(--dropdown-menu-background, #fff);
border: 1px solid var(--dropdown-menu-border-primary, #005bcb);
max-height: 0;
opacity: 0;
transition: max-height 0.3s ease-in-out, opacity 0.3s ease-in-out;
position: absolute;
top: 100%;
left: 0;
transform: translateY(8px);
}
&.open {
overflow: visible;
.content {
max-height: 500px;
opacity: 1;
}
}
}

View File

@ -0,0 +1,44 @@
import classNames from "classnames";
import React, { useCallback } from "react";
import classes from "./classes.module.scss";
import DropdownOption, { IOption } from "./DropdownOption";
type IProps = {
options: IOption[];
selectedOption: IOption | null;
children: React.ReactNode;
openable: {
isOpen: boolean;
open: () => void;
close: () => void;
toggle: () => void;
};
onSelect?: (option: IOption) => void;
};
export default function DropdownMenu(props: IProps) {
const { children, options, onSelect, openable, selectedOption } = props;
const handleSelect = useCallback(
(option: IOption) => {
onSelect?.(option);
openable.close();
},
[onSelect, openable],
);
return (
<div className={classNames([classes["root"], openable.isOpen && classes["open"]])}>
{children}
<div className={classes["content"]}>
{options.map((option) => {
return <DropdownOption key={option.id} option={option} onClick={handleSelect} isActive={isActive(option)} />;
})}
</div>
</div>
);
function isActive(option: IOption): boolean {
return selectedOption?.id === option.id;
}
}

View File

@ -0,0 +1,45 @@
@import "@Themes/constants.scss";
.root {
cursor: pointer;
height: 56px;
display: flex;
align-items: center;
padding: var(--spacing-2, 16px) var(--spacing-sm, 8px);
gap: var(--spacing-2, 16px);
border-radius: var(--input-radius, 0px);
border: 1px solid var(--dropdown-input-border-default, #d7dce0);
background: var(--dropdown-input-background, #fff);
.content {
width: 100%;
display: flex;
padding: 0px var(--spacing-2, 16px);
align-items: center;
flex: 1 0 0;
}
&:hover {
border-color: var(--dropdown-input-border-hovered);
}
&.active {
border-color: var(--dropdown-input-border-filled);
}
&.open {
border-color: var(--dropdown-input-border-expanded);
svg {
transform: rotate(180deg);
}
}
&.disabled {
opacity: var(--opacity-disabled, 0.3);
pointer-events: none;
}
}

View File

@ -0,0 +1,44 @@
import useOpenable from "@Front/Hooks/useOpenable";
import classNames from "classnames";
import { useState } from "react";
import Typography, { ETypo, ETypoColor } from "../Typography";
import classes from "./classes.module.scss";
import DropdownMenu from "./DropdownMenu";
import { IOption } from "./DropdownMenu/DropdownOption";
import IconButton from "../IconButton";
import { ChevronDownIcon } from "@heroicons/react/24/outline";
type IProps = {
options: IOption[];
placeholder: string;
disabled?: boolean;
};
export default function Dropdown(props: IProps) {
const { options, placeholder, disabled } = props;
const [selectedOption, setSelectedOption] = useState<IOption | null>(null);
const openable = useOpenable({ defaultOpen: false });
return (
<DropdownMenu options={options} openable={openable} onSelect={setSelectedOption} selectedOption={selectedOption}>
<div
className={classNames([
classes["root"],
openable.isOpen && classes["open"],
disabled && classes["disabled"],
!!selectedOption && classes["active"],
])}
onClick={openable.toggle}>
<div className={classes["content"]}>
<Typography
typo={ETypo.TEXT_MD_REGULAR}
color={!!selectedOption ? ETypoColor.DROPDOWN_CONTRAST_ACTIVE : ETypoColor.DROPDOWN_CONTRAST_DEFAULT}>
{selectedOption?.label ?? placeholder}
</Typography>
</div>
<IconButton icon={<ChevronDownIcon />} />
</div>
</DropdownMenu>
);
}

View File

@ -176,6 +176,7 @@ const officeItems: IItem[] = [
icon: <BanknotesIcon />, icon: <BanknotesIcon />,
text: "RIB Office", text: "RIB Office",
link: Module.getInstance().get().modules.pages.OfficesRib.props.path, link: Module.getInstance().get().modules.pages.OfficesRib.props.path,
routesActive: [Module.getInstance().get().modules.pages.OfficesRib.props.path],
rules: [ rules: [
{ {
action: AppRuleActions.update, action: AppRuleActions.update,

View File

@ -54,7 +54,7 @@ export default function Header(props: IProps) {
<> <>
<div className={classes["root"]}> <div className={classes["root"]}>
<Head> <Head>
<link rel="shortcut icon" href={"/favicon.ico"} /> <link rel="shortcut icon" href={"/favicon.svg"} />
</Head> </Head>
<div className={classes["logo-container"]}> <div className={classes["logo-container"]}>
<Link href={isUserConnected ? Module.getInstance().get().modules.pages.Folder.props.path : "#"}> <Link href={isUserConnected ? Module.getInstance().get().modules.pages.Folder.props.path : "#"}>

View File

@ -156,6 +156,9 @@ export enum ETypoColor {
CONTRAST_ACTIVED = "--contrast-actived", CONTRAST_ACTIVED = "--contrast-actived",
NAVIGATION_BUTTON_CONTRAST_DEFAULT = "--navigation-button-contrast-default", NAVIGATION_BUTTON_CONTRAST_DEFAULT = "--navigation-button-contrast-default",
NAVIGATION_BUTTON_CONTRAST_ACTIVE = "--navigation-button-contrast-active", NAVIGATION_BUTTON_CONTRAST_ACTIVE = "--navigation-button-contrast-active",
DROPDOWN_CONTRAST_DEFAULT = "--dropdown-contrast-default",
DROPDOWN_CONTRAST_ACTIVE = "--dropdown-contrast-active",
} }
export default function Typography(props: IProps) { export default function Typography(props: IProps) {

View File

@ -8,7 +8,7 @@ export const DefaultLayout = ({ children }: DefaultLayoutProps) => {
<> <>
<Head> <Head>
<title>LEcoffre</title> <title>LEcoffre</title>
{/* <link rel="shortcut icon" href="/favicon.ico" /> */} {/* <link rel="shortcut icon" href="/favicon.svg" /> */}
</Head> </Head>
<main> <main>
{children} {children}

View File

@ -3,6 +3,7 @@
flex-direction: column; flex-direction: column;
gap: 32px; gap: 32px;
.components { .components {
max-width: 600px;
.inputs { .inputs {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -1,12 +1,17 @@
import Alert, { EAlertVariant } from "@Front/Components/DesignSystem/Alert"; import Alert, { EAlertVariant } from "@Front/Components/DesignSystem/Alert";
import Button, { EButtonSize, EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button"; import Button, { EButtonSize, EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
import CircleProgress from "@Front/Components/DesignSystem/CircleProgress"; import CircleProgress from "@Front/Components/DesignSystem/CircleProgress";
import Dropdown from "@Front/Components/DesignSystem/Dropdown";
import Footer from "@Front/Components/DesignSystem/Footer";
import Form from "@Front/Components/DesignSystem/Form"; import Form from "@Front/Components/DesignSystem/Form";
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField"; import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
import TextField from "@Front/Components/DesignSystem/Form/TextField"; import TextField from "@Front/Components/DesignSystem/Form/TextField";
import IconButton, { EIconButtonVariant } from "@Front/Components/DesignSystem/IconButton"; import IconButton, { EIconButtonVariant } from "@Front/Components/DesignSystem/IconButton";
import Menu from "@Front/Components/DesignSystem/Menu";
import Modal from "@Front/Components/DesignSystem/Modal"; import Modal from "@Front/Components/DesignSystem/Modal";
import Newsletter from "@Front/Components/DesignSystem/Newsletter"; import Newsletter from "@Front/Components/DesignSystem/Newsletter";
import SearchBlockList from "@Front/Components/DesignSystem/SearchBlockList";
import DropdownNavigation from "@Front/Components/DesignSystem/SearchBlockList/DropdownNavigation";
import Table from "@Front/Components/DesignSystem/Table"; import Table from "@Front/Components/DesignSystem/Table";
import Tag, { ETagColor, ETagVariant } from "@Front/Components/DesignSystem/Tag"; import Tag, { ETagColor, ETagVariant } from "@Front/Components/DesignSystem/Tag";
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography"; import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
@ -14,7 +19,6 @@ import NumberPicker from "@Front/Components/Elements/NumberPicker";
import Tabs from "@Front/Components/Elements/Tabs"; import Tabs from "@Front/Components/Elements/Tabs";
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate"; import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
import useOpenable from "@Front/Hooks/useOpenable"; import useOpenable from "@Front/Hooks/useOpenable";
import Footer from "@Front/Components/DesignSystem/Footer";
import { import {
ArchiveBoxIcon, ArchiveBoxIcon,
ArrowLongLeftIcon, ArrowLongLeftIcon,
@ -27,9 +31,6 @@ import {
import { useCallback, useMemo, useState } from "react"; import { useCallback, useMemo, useState } from "react";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import Menu from "@Front/Components/DesignSystem/Menu";
import DropdownNavigation from "@Front/Components/DesignSystem/SearchBlockList/DropdownNavigation";
import SearchBlockList from "@Front/Components/DesignSystem/SearchBlockList";
export default function DesignSystem() { export default function DesignSystem() {
const { isOpen, open, close } = useOpenable(); const { isOpen, open, close } = useOpenable();
@ -78,8 +79,28 @@ export default function DesignSystem() {
return ( return (
<DefaultTemplate title={"DesignSystem"}> <DefaultTemplate title={"DesignSystem"}>
<Typography typo={ETypo.DISPLAY_LARGE}>DesignSystem</Typography> <Typography typo={ETypo.DISPLAY_LARGE}>DesignSystem</Typography>
<Newsletter isOpen /> <Newsletter isOpen={false} />
<div className={classes["root"]}> <div className={classes["root"]}>
<div className={classes["components"]}>
<Typography typo={ETypo.TEXT_LG_BOLD}>Dropdown</Typography>
<Dropdown
options={[
{
id: "1",
label: "Option 1",
},
{
id: "2",
label: "Option 2",
},
{
id: "3",
label: "Option 3",
},
]}
placeholder="Placeholder"
/>
</div>
<div className={classes["components"]}> <div className={classes["components"]}>
<Typography typo={ETypo.TEXT_LG_BOLD}>Navigation latérale</Typography> <Typography typo={ETypo.TEXT_LG_BOLD}>Navigation latérale</Typography>
<SearchBlockList <SearchBlockList