This commit is contained in:
Maxime Lalo 2024-04-30 10:13:36 +02:00 committed by GitHub
commit 3096f2ce21
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 110 additions and 73 deletions

36
package-lock.json generated
View File

@ -23,7 +23,7 @@
"eslint-config-next": "13.2.4",
"form-data": "^4.0.0",
"jwt-decode": "^3.1.2",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.134",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.136",
"next": "13.2.4",
"prettier": "^2.8.7",
"react": "18.2.0",
@ -1418,9 +1418,9 @@
"optional": true
},
"node_modules/bare-path": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.1.tgz",
"integrity": "sha512-OHM+iwRDRMDBsSW7kl3dO62JyHdBKO3B25FB9vNQBPcGHMo4+eA8Yj41Lfbk3pS/seDY+siNge0LdRTulAau/A==",
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.2.tgz",
"integrity": "sha512-o7KSt4prEphWUHa3QUwCxUI00R86VdjiuxmJK0iNVDHYPGo+HsDaVCnqCmPbf/MiW1ok8F4p3m8RTHlWk8K2ig==",
"optional": true,
"dependencies": {
"bare-os": "^2.1.0"
@ -2061,13 +2061,13 @@
}
},
"node_modules/es-iterator-helpers": {
"version": "1.0.18",
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz",
"integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==",
"version": "1.0.19",
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz",
"integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==",
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.23.0",
"es-abstract": "^1.23.3",
"es-errors": "^1.3.0",
"es-set-tostringtag": "^2.0.3",
"function-bind": "^1.1.2",
@ -2408,9 +2408,9 @@
}
},
"node_modules/eslint-plugin-react-hooks": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
"integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.1.tgz",
"integrity": "sha512-Ck77j8hF7l9N4S/rzSLOWEKpn994YH6iwUK8fr9mXIaQvGpQYmOnQLbiue1u5kI5T1y+gdgqosnEAO9NCz0DBg==",
"engines": {
"node": ">=10"
},
@ -3523,7 +3523,7 @@
}
},
"node_modules/le-coffre-resources": {
"resolved": "git+ssh://git@github.com/smart-chain-fr/leCoffre-resources.git#fb09b1ebbdfbc80d43f8ae2e4b64e15575d0b69d",
"resolved": "git+ssh://git@github.com/smart-chain-fr/leCoffre-resources.git#14df7a44f4e8f339725ce6b0eb931372a95e1650",
"license": "MIT",
"dependencies": {
"class-transformer": "^0.5.1",
@ -4244,9 +4244,9 @@
"integrity": "sha512-8gyj4TTxeP7eEyc2QKawEuQoAZdjKvMY4pgWfycGmqGByhs17fR+zEBs0JUDq4US/l+vbTl+6zvUIx27iDo/Vw=="
},
"node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
"version": "18.3.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.0.tgz",
"integrity": "sha512-wRiUsea88TjKDc4FBEn+sLvIDesp6brMbGWnJGjew2waAc9evdhja/2LvePc898HJbHw0L+MTWy7NhpnELAvLQ=="
},
"node_modules/react-select": {
"version": "5.8.0",
@ -4520,9 +4520,9 @@
}
},
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
"integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.1.tgz",
"integrity": "sha512-5GKS5JGfiah1O38Vfa9srZE4s3wdHbwjlCrvIookrg2FO9aIwKLOJXuJQFlEfNcVSOXuaL2hzDeY20uVXcUtrw==",
"dependencies": {
"loose-envify": "^1.1.0"
}

View File

@ -25,7 +25,7 @@
"eslint-config-next": "13.2.4",
"form-data": "^4.0.0",
"jwt-decode": "^3.1.2",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.134",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.136",
"next": "13.2.4",
"prettier": "^2.8.7",
"react": "18.2.0",

View File

@ -340,11 +340,11 @@ export default class DepositDocument extends React.Component<IProps, IState> {
private async addFile(file: File) {
const fileAccepted = filesAccepted[file.type];
if (!fileAccepted) {
alert("Ce type de fichier n'est pas accepté");
alert("Le fichier déposé doit être au format .jpg .pdf .jpeg ou .png");
return false;
}
if (file.size > fileAccepted.size) {
alert("Ce fichier est trop volumineux");
alert("Le fichier est trop volumineux et ne doit pas dépasser 32mo");
return false;
}
this.setState({

View File

@ -159,7 +159,9 @@ export default class BurgerModal extends React.Component<IProps, IState> {
/>
<div className={classes["separator"]} />
<NavigationLink path={Module.getInstance().get().modules.pages.MyAccount.props.path} text="Mon compte" />
<NavigationLink target="_blank" path="/CGU_LeCoffre_io.pdf" text="CGU" />
<NavigationLink target="blank" path="https://tally.so/r/mBGaNY" text="Support" />
<NavigationLink target="blank" path="/CGU_LeCoffre_io.pdf" text="CGU" />
<LogOutButton />
</div>
</>

View File

@ -53,6 +53,10 @@
> :first-child {
margin-right: 32px;
}
@media (max-width: $screen-s) {
display: none;
}
}
}

View File

@ -34,6 +34,7 @@ type IState = {
validatedPercentage: number;
document: Document | null;
fileBlob: Blob | null;
isLoading: boolean;
};
class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
@ -49,6 +50,7 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
validatedPercentage: this.getRandomPercentageForOcr(),
document: null,
fileBlob: null,
isLoading: true,
};
this.closeModals = this.closeModals.bind(this);
@ -68,7 +70,7 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
public override render(): JSX.Element | null {
return (
<DefaultNotaryDashboard title={"Demander des documents"} hasBackArrow mobileBackText="Retour aux documents">
{this.state.document && this.state.document.files && this.state.selectedFile && (
{this.state.document && this.state.document.files && this.state.selectedFile && !this.state.isLoading && (
<div className={classes["root"]}>
<Typography typo={ITypo.H1} color={ITypoColor.BLACK} className={classes["title"]}>
{this.state.document.folder?.name}
@ -156,7 +158,7 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
</Confirm>
</div>
)}
{(!this.state.selectedFile || !this.state.document) && (
{(!this.state.selectedFile || !this.state.document) && !this.state.isLoading && (
<div className={classes["root"]}>
<Typography typo={ITypo.P_16} color={ITypoColor.BLACK} className={classes["refuse-text"]}>
Document non trouvé
@ -182,12 +184,16 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
document,
selectedFileIndex: 0,
selectedFile: document.files![0]!,
isLoading: false,
},
() => {
this.getFilePreview();
},
);
} catch (e) {
this.setState({
isLoading: false,
});
console.error(e);
}
}

View File

@ -17,7 +17,7 @@ export default function LoginHome() {
<div className={classes["content"]}>
<div className={classes["section"]}>
<Typography typo={ITypo.P_18} color={ITypoColor.BLACK}>
Je suis un notaire
Je suis un notaire / collaborateur
</Typography>
<Link href={Module.getInstance().get().modules.pages.Login.props.path}>
<Button>Se connecter</Button>

View File

@ -5,6 +5,16 @@
margin-top: 24px;
}
.loader-container {
display: flex;
justify-content: center;
margin-top: 150px;
.loader {
width: 32px;
height: 32px;
}
}
.title {
margin-top: 24px;
}

View File

@ -8,6 +8,7 @@ import { useRouter } from "next/router";
import OfficeRib from "@Front/Api/LeCoffreApi/Notary/OfficeRib/OfficeRib";
import DepositRib from "@Front/Components/DesignSystem/DepositRib";
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
import Loader from "@Front/Components/DesignSystem/Loader";
export default function Rib() {
const [documentList, setDocumentList] = useState<File[]>([]);
@ -18,13 +19,12 @@ export default function Rib() {
const [key, setKey] = useState<string>("");
const [isRibModalOpen, setIsRibModalOpen] = useState<boolean>(false);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(true);
//Put fetch data in a useCallback
const fetchData = useCallback(async () => {
try {
const blob = await OfficeRib.getInstance().getRibStream();
setFileBlob(blob.blob);
setKey(key);
setFileName(blob.fileName);
@ -33,6 +33,7 @@ export default function Rib() {
setFileName("");
setKey("");
}
setIsLoading(false);
}, [key]);
useEffect(() => {
@ -96,8 +97,15 @@ export default function Rib() {
<Typography typo={ITypo.H1} color={ITypoColor.BLACK} className={classes["title"]}>
RIB de l'office
</Typography>
{!fileBlob && (
{isLoading && (
<div className={classes["loader-container"]}>
<div className={classes["loader"]}>
<Loader />
</div>
</div>
)}
{!isLoading && !fileBlob && (
<>
<div className={classes["document-container"]}>
<div>
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
@ -105,24 +113,21 @@ export default function Rib() {
</Typography>
</div>
</div>
)}
{!fileBlob && (
<div className={classes["footer"]}>
<div className={classes["buttons-container"]}>
<Button onClick={openRibModal}>Déposer un RIB</Button>
</div>
</div>
</>
)}
{fileBlob && (
{!isLoading && fileBlob && (
<>
<div className={classes["document-container"]}>
<div className={classes["file-container"]}>
{fileBlob && <FilePreview href={fileBlob ? URL.createObjectURL(fileBlob) : ""} fileName={fileName} />}
</div>
</div>
)}
{fileBlob && (
<div className={classes["footer"]}>
<div className={classes["buttons-container"]}>
<Button onClick={openDeleteModal} variant={EButtonVariant.SECONDARY}>
@ -134,6 +139,7 @@ export default function Rib() {
<Button onClick={downloadFile}>Télécharger</Button>
</div>
</div>
</>
)}
<Confirm

View File

@ -48,6 +48,7 @@ export default function SubscribeIllimityComponent({ hasNavTab = true }: IProps)
} catch (error) {}
};
let multiplierToUse = paymentFrequency === EPaymentFrequency.yearly ? multiplier - 1 : multiplier;
return (
<>
<DefaultTemplate title="Nouvelle souscription" hasBackArrow>
@ -129,7 +130,7 @@ export default function SubscribeIllimityComponent({ hasNavTab = true }: IProps)
Total TTC
</Typography>
<Typography typo={ITypo.P_SB_18} color={ITypoColor.BLACK}>
{formatFloat(forfeitsPrices[EForfeitType.unlimited] * 1.2 * multiplier)}
{formatFloat(forfeitsPrices[EForfeitType.unlimited] * 1.2 * multiplierToUse)}
&nbsp;
</Typography>
</div>

View File

@ -39,6 +39,8 @@ export default function SubscribeStandardComponent({ hasNavTab = true }: IProps)
setPaymentFrequency(parseInt(e.target.value) as EPaymentFrequency);
};
let multiplierToUse = paymentFrequency === EPaymentFrequency.yearly ? multiplier - 1 : multiplier;
return (
<>
<DefaultTemplate title="Nouvelle souscription" hasBackArrow>
@ -120,7 +122,9 @@ export default function SubscribeStandardComponent({ hasNavTab = true }: IProps)
</Typography>
<Typography typo={ITypo.P_SB_18} color={ITypoColor.BLACK}>
{formatFloat(
(forfeitsPrices[EForfeitType.standard] + collaboratorPrice * numberOfCollaborators) * 1.2 * multiplier,
(forfeitsPrices[EForfeitType.standard] * multiplierToUse +
collaboratorPrice * numberOfCollaborators * multiplier) *
1.2,
)}
&nbsp;
</Typography>

View File

@ -6,7 +6,7 @@ import CheckBox from "@Front/Components/DesignSystem/CheckBox";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import React, { useCallback, useEffect, useState } from "react";
import User, { Subscription } from "le-coffre-resources/dist/Admin";
import JwtService from "@Front/Services/JwtService/JwtService";
import JwtService, { IUserJwtPayload } from "@Front/Services/JwtService/JwtService";
import Subscriptions from "@Front/Api/LeCoffreApi/Admin/Subscriptions/Subscriptions";
import Users from "@Front/Api/LeCoffreApi/Admin/Users/Users";
import { useRouter } from "next/router";
@ -17,9 +17,10 @@ export default function SubscriptionManageCollaborators() {
const [subscription, setSubscription] = useState<Subscription | null>(null);
const [availableCollaborators, _setAvailableCollaborators] = useState<User[]>([]);
const [selectedCollaborators, setSelectedCollaborators] = useState<string[]>([]);
const [jwt, setJwt] = useState<IUserJwtPayload | undefined>(undefined);
const loadSubscription = useCallback(async () => {
const jwt = JwtService.getInstance().decodeJwt();
setJwt(jwt);
const subscription = await Subscriptions.getInstance().get({
where: { office: { uid: jwt?.office_Id } },
include: { seats: { include: { user: true } } },
@ -80,7 +81,7 @@ export default function SubscriptionManageCollaborators() {
return (
<DefaultTemplate title="Nouvelle souscription" hasBackArrow>
{subscription && (
{subscription && jwt && (
<div className={classes["root"]}>
<Typography typo={ITypo.H2} color={ITypoColor.BLACK}>
Choisissez les collaborateurs pour votre abonnement
@ -100,8 +101,9 @@ export default function SubscriptionManageCollaborators() {
checked={selectedCollaborators.includes(collaborator.uid!)}
onChange={handleChange}
disabled={
selectedCollaborators.length >= subscription.nb_seats! &&
!selectedCollaborators.includes(collaborator.uid!)
(selectedCollaborators.length >= subscription.nb_seats! &&
!selectedCollaborators.includes(collaborator.uid!)) ||
jwt.userId === collaborator.uid
}
name="collaborators"
/>

View File

@ -8,12 +8,12 @@ import { useCallback, useEffect, useState } from "react";
import { Subscription } from "le-coffre-resources/dist/Admin";
import JwtService from "@Front/Services/JwtService/JwtService";
import Subscriptions from "@Front/Api/LeCoffreApi/Admin/Subscriptions/Subscriptions";
import SubscribeCheckoutTicket, { EPaymentFrequencyFront as EPaymentFrequency } from "../Components/SubscribeCheckoutTicket";
import { EForfeitType } from "../SubscriptionFacturation";
import Stripe from "@Front/Api/LeCoffreApi/Admin/Stripe/Stripe";
import Link from "next/link";
import Module from "@Front/Config/Module";
export default function SubscriptionError() {
const [subscription, setSubscription] = useState<Subscription | null>(null);
const [_subscription, setSubscription] = useState<Subscription | null>(null);
const [customer, setCustomer] = useState<any | null>(null);
const loadSubscription = useCallback(async () => {
@ -25,7 +25,7 @@ export default function SubscriptionError() {
setCustomer(customer);
}, []);
const getFrequency = useCallback(() => {
/* const getFrequency = useCallback(() => {
if (!subscription) return;
const start = new Date(subscription.start_date);
const end = new Date(subscription.end_date);
@ -33,7 +33,7 @@ export default function SubscriptionError() {
const diffTime = Math.abs(end.getTime() - start.getTime());
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
return diffDays >= 365 ? EPaymentFrequency.yearly : EPaymentFrequency.monthly;
}, [subscription]);
}, [subscription]); */
useEffect(() => {
loadSubscription();
@ -41,7 +41,7 @@ export default function SubscriptionError() {
return (
<DefaultTemplate title="Erreur à la souscription">
{subscription && customer && (
{customer && (
<div className={classes["root"]}>
<div className={classes["left"]}>
<div className={classes["title"]}>
@ -63,16 +63,18 @@ export default function SubscriptionError() {
<SubscriptionClientInfos customer={customer} />
</div>
<div className={classes["separator"]} />
<Button>Réessayer le paiement</Button>
<Link href={Module.getInstance().get().modules.pages.Subscription.pages.New.props.path}>
<Button>Réessayer</Button>
</Link>
</div>
<div className={classes["right"]}>
{/* <div className={classes["right"]}>
<SubscribeCheckoutTicket
forfeitType={subscription.type === "STANDARD" ? EForfeitType.standard : EForfeitType.unlimited}
numberOfCollaborators={subscription.nb_seats ?? 0}
disableInputs
defaultFrequency={getFrequency()}
/>
</div>
</div> */}
</div>
)}
</DefaultTemplate>