feat: implemented organization profile
This commit is contained in:
parent
3e1cf17b2d
commit
98ba95dc01
@ -16,134 +16,143 @@ export default function Profile() {
|
|||||||
const segments = pathname.split("/");
|
const segments = pathname.split("/");
|
||||||
const uid = segments[segments.length - 1];
|
const uid = segments[segments.length - 1];
|
||||||
|
|
||||||
|
|
||||||
const { data: session, status } = useSession();
|
const { data: session, status } = useSession();
|
||||||
|
|
||||||
const { data: companyInfos, isLoading } = useQuery({
|
const { data: companyInfos, isLoading } = useQuery({
|
||||||
enabled: status === 'authenticated',
|
enabled: status === 'authenticated',
|
||||||
queryKey: ["stats", session?.user.access_token],
|
queryKey: ["companyStats", session?.user.access_token],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(
|
const response = await axios.get(
|
||||||
`https://private-docs-api.intside.co/companies/${uid}`, {
|
`https://private-docs-api.intside.co/companies/${uid}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${session?.user.access_token}`
|
'Authorization': `Bearer ${session?.user.access_token}`
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
details: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
|
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
return response.data as CompanyById
|
return response.data as CompanyById;
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error)
|
console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
const adminId = companyInfos?.owner
|
|
||||||
|
/*
|
||||||
|
const adminId = companyInfos?.owner;
|
||||||
|
console.log('will run the admin request');
|
||||||
|
|
||||||
const { data: adminInfos } = useQuery({
|
const { data: adminInfos } = useQuery({
|
||||||
enabled: status === 'authenticated',
|
enabled: !!adminId && status === 'authenticated', // Only run when adminId is available
|
||||||
queryKey: ["stats", session?.user.access_token],
|
queryKey: ["admin", adminId], // Ensure adminId is used in the query key
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
console.log('running the admin request');
|
||||||
|
//console.log('url :', `https://private-docs-api.intside.co/users/${adminId}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(
|
const response = await axios.get(
|
||||||
`https://private-docs-api.intside.co/users/${companyInfos}`, {
|
`https://private-docs-api.intside.co/users/${adminId}`, { // Use adminId instead of companyInfos
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${session?.user.access_token}`
|
'Authorization': `Bearer ${session?.user.access_token}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
|
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
return response.data.data as Owner
|
return response.data as Owner;
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
console.log(`https://private-docs-api.intside.co/users/${companyInfos}`);
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* {companyInfos[0]?.id} */}
|
{/* {companyInfos[0]?.id} */}
|
||||||
<div className="p-container ">
|
<div className="p-container ">
|
||||||
<div className="r-flex-column">
|
<div className="r-flex-column">
|
||||||
<div className="r-flex-between items-center bg-bluegray p-[24px] m-0 ">
|
<div className="r-flex-between items-center bg-bluegray p-[24px] m-0 ">
|
||||||
<div className=""></div>
|
<div className=""></div>
|
||||||
<h2 className="admin-name text-[20px]" >{companyInfos?.name || "Pentatonic"}</h2>
|
<h2 className="admin-name text-[20px]" >{companyInfos?.name || "Pentatonic"}</h2>
|
||||||
<button type="button" className="update-profile-name cta">
|
<Link href={`http://localhost:3000/admin/organizations/${uid}/update`} type="Link" className="update-profile-name cta">
|
||||||
Modifier
|
Modifier
|
||||||
</button>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-column p-[32px] r-gap-24">
|
<div className="r-flex-column p-[32px] r-gap-24 items-center lg:items-start ">
|
||||||
<h3 className="font-semibold">Détails de l'admin</h3>
|
<h3 className="font-semibold">Détails de l'admin</h3>
|
||||||
<div className="r-flex gap-[60px]">
|
<div className="r-flex flex-wrap r-r-gap-12 gap-[12px]">
|
||||||
<div className="r-flex-between items-center rr-gap-12 w-max">
|
<div className="r-flex-between items-center w-max">
|
||||||
<div className="icon-rounded">
|
<div className="icon-rounded">
|
||||||
<Image src={icons.mailIcon} alt="E-mail" />
|
<Image src={icons.mailIcon} alt="E-mail" />
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-column p-[14px] r-gap-2">
|
<div className="r-flex-column p-[14px] admin-card r-gap-2">
|
||||||
<h4 className="email-label font-semibold">Adresse e-mail</h4>
|
<h4 className="email-label font-semibold">Adresse e-mail</h4>
|
||||||
<p className="email">{adminInfos?.email || "email"}</p>
|
<p className="email">{companyInfos?.owner?.email || "email"}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-between items-center rr-gap-12 w-max">
|
<div className="r-flex-between items-center w-max">
|
||||||
<div className="icon-rounded">
|
<div className="icon-rounded">
|
||||||
<Image src={icons.personalCard} alt="E-mail" />
|
<Image src={icons.personalCard} alt="E-mail" />
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex gap-[60px]">
|
<div className="r-flex gap-[12px] admin-card">
|
||||||
<div className="r-flex-column p-[14px] r-gap-2">
|
<div className="r-flex-column p-[14px] r-gap-2">
|
||||||
<h4 className="surname-label font-semibold">Prénom</h4>
|
<h4 className="surname-label font-semibold">Prénom</h4>
|
||||||
<p className="surname">{adminInfos?.first_name || "nom"}</p>
|
<p className="surname">{companyInfos?.owner?.first_name || "nom"}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-column p-[14px] r-gap-2">
|
<div className="r-flex-column p-[14px] r-gap-2">
|
||||||
<h4 className="name-label font-semibold">Nom</h4>
|
<h4 className="name-label font-semibold">Nom</h4>
|
||||||
<p className="name">{adminInfos?.last_name || "nom"}</p>
|
<p className="name">{companyInfos?.owner?.last_name || "nom"}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<div className="r-flex-column p-[32px] r-gap-24">
|
<div className="r-flex p-[32px] r-gap-24">
|
||||||
<div className="r-flex-between gap-[84px]">
|
<div className="admin-infos r-flex flex-wrap justifyc-center lg:justifyc-start ">
|
||||||
<div className="r-flex-between items-center rr-gap-12 w-max">
|
<div className="r-flex-between items-center w-max">
|
||||||
<div className="icon-rounded">
|
<div className="icon-rounded">
|
||||||
<Image src={icons.userGroupBlue} alt="Documents" />
|
<Image src={icons.userGroupBlue} alt="Documents" />
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-column p-[14px] r-gap-2">
|
<div className="r-flex-column p-[14px] admin-card r-gap-2">
|
||||||
<h4 className="users-label font-semibold">Documents</h4>
|
<h4 className="users-label font-semibold">Documents</h4>
|
||||||
<p className="r-secondary users">123</p>
|
<p className="r-secondary users">{companyInfos?.total_documents || "0"}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-between items-center rr-gap-12 w-max">
|
<div className="r-flex-between items-center w-max">
|
||||||
<div className="icon-rounded">
|
<div className="icon-rounded">
|
||||||
<Image src={icons.userGroupBlue} alt="Documents" />
|
<Image src={icons.userGroupBlue} alt="Documents" />
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-column p-[14px] r-gap-2">
|
<div className="r-flex-column p-[14px] admin-card r-gap-2">
|
||||||
<h4 className="users-label font-semibold">Utilisateurs</h4>
|
<h4 className="users-label font-semibold">Utilisateurs</h4>
|
||||||
<p className="r-secondary users">24</p>
|
<p className="r-secondary users">{companyInfos?.total_users || "0"}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-between items-center rr-gap-12 w-max">
|
<div className="r-flex-between items-center w-max">
|
||||||
<div className="icon-rounded">
|
<div className="icon-rounded">
|
||||||
<Image src={icons.maximizeIcon} alt="Fichiers" />
|
<Image src={icons.maximizeIcon} alt="Fichiers" />
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-column p-[14px] r-gap-2">
|
<div className="r-flex-column p-[14px] admin-card r-gap-2">
|
||||||
<h4 className="files-size-label font-semibold">Taille des fichiers</h4>
|
<h4 className="files-size-label font-semibold">Taille des fichiers</h4>
|
||||||
<p className="r-secondary files-size">3.41GB</p>
|
<p className="r-secondary files-size">{companyInfos?.total_documents_sizes + " "}GB</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-between items-center rr-gap-12 w-max">
|
<div className="r-flex-between items-center w-max">
|
||||||
<div className="icon-rounded">
|
<div className="icon-rounded">
|
||||||
<Image src={icons.timerIcon} alt="Horlorge" />
|
<Image src={icons.timerIcon} alt="Horlorge" />
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-column p-[14px] r-gap-2">
|
<div className="r-flex-column p-[14px] admin-card r-gap-2">
|
||||||
<h4 className="last-connexion-label font-semibold">Dernière utilisation</h4>
|
<h4 className="last-connexion-label font-semibold">Dernière utilisation</h4>
|
||||||
<p className="r-secondary last-connexion">26 Jan 2024 - 14h15</p>
|
<p className="r-secondary last-connexion">{companyInfos?.last_use || "-"}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,57 +3,72 @@ import { icons } from "#/assets/icons"
|
|||||||
import Image from "next/image"
|
import Image from "next/image"
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { Company } from "#/types";
|
import { Company, CompanyById } from "#/types";
|
||||||
import FloatingLabelInput from "#/components/floatingLabelInput";
|
import FloatingLabelInput from "#/components/floatingLabelInput";
|
||||||
|
import { usePathname } from "next/navigation";
|
||||||
|
import Link from "next/link";
|
||||||
|
import Form from "#/components/form/form";
|
||||||
|
import { adminSchema } from "#/schema/loginSchema";
|
||||||
|
|
||||||
export default function Update() {
|
export default function Update() {
|
||||||
|
|
||||||
|
const pathname = usePathname();
|
||||||
|
|
||||||
|
const segments = pathname.split("/");
|
||||||
|
const uid = segments[segments.length - 2];
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const { data: session, status } = useSession();
|
const { data: session, status } = useSession();
|
||||||
|
|
||||||
const { data: company, isLoading } = useQuery({
|
const { data: companyInfos, refetch, isLoading } = useQuery({
|
||||||
enabled: status === 'authenticated',
|
enabled: status === 'authenticated',
|
||||||
queryKey: ["stats", session?.user.access_token],
|
queryKey: ["companyStats", session?.user.access_token],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(
|
const response = await axios.get(
|
||||||
'https://private-docs-api.intside.co/companies', {
|
`https://private-docs-api.intside.co/users/${uid}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${session?.user.access_token}`
|
'Authorization': `Bearer ${session?.user.access_token}`
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
details: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
|
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
return response.data.data as Company
|
return response.data as CompanyById;
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error)
|
console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
const { data: adminOrganization } = useQuery({
|
const { mutate, isPending } = useMutation({
|
||||||
enabled: status === 'authenticated',
|
mutationFn: async (id: string) => {
|
||||||
queryKey: ["stats", session?.user.access_token],
|
|
||||||
queryFn: async () => {
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(
|
const response = await axios.delete(
|
||||||
'https://private-docs-api.intside.co/users/me', {
|
`https://private-docs-api.intside.co/companies/${id}/`, {
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${session?.user.access_token}`
|
'Authorization': `Bearer ${session?.user.access_token}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (response.data) {
|
if (response.status === 200 || response.status === 201) {
|
||||||
return response.data as Company
|
console.log('Suppresion réussie !')
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["companies"] })
|
||||||
|
|
||||||
|
refetch()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -62,28 +77,61 @@ export default function Update() {
|
|||||||
<>
|
<>
|
||||||
{/* { company.map() } */}
|
{/* { company.map() } */}
|
||||||
|
|
||||||
|
|
||||||
|
{/* <Form
|
||||||
|
title="Connexion"
|
||||||
|
className="grid grid-cols-2"
|
||||||
|
fields={[
|
||||||
|
{
|
||||||
|
label: "Nom de l’organisation",
|
||||||
|
name: "company",
|
||||||
|
type: "text",
|
||||||
|
placeholder: "Nom de l'organisation",
|
||||||
|
defaultValue: companyInfos?.name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Nom de l’admin",
|
||||||
|
name: "last_name",
|
||||||
|
type: "text",
|
||||||
|
placeholder: "Nom de l'admin",
|
||||||
|
defaultValue: companyInfos?.owner.last_name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Prénom de l’admin",
|
||||||
|
name: "first_name",
|
||||||
|
type: "text",
|
||||||
|
placeholder: "Prénom de l'admin",
|
||||||
|
defaultValue: companyInfos?.owner.first_name
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
submit={mutate}
|
||||||
|
schema={adminSchema}
|
||||||
|
child={<button type="submit" className="btn-auth">Connexion</button>}
|
||||||
|
/> */}
|
||||||
|
|
||||||
|
|
||||||
<div className="p-container ">
|
<div className="p-container ">
|
||||||
<div className="r-flex-column">
|
<div className="r-flex-column">
|
||||||
<div className="r-flex-between items-center bg-bluegray p-[24px] m-0 ">
|
<div className="r-flex-between items-center bg-bluegray p-[24px] m-0 ">
|
||||||
<div className=""></div>
|
<div className=""></div>
|
||||||
<h2 className="admin-name text-[20px]" >Pentatonic</h2>
|
<h2 className="admin-name text-[20px]" >{companyInfos?.name || "Pentatonic"}</h2>
|
||||||
<button type="button" className="update-profile-name cta cancel">
|
<Link href={`http://localhost:3000/admin/organizations/${uid}/`} type="Link" className="cta cancel">
|
||||||
Annuler
|
Annuler
|
||||||
</button>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="r-flex-column p-[32px] r-gap-24">
|
<div className="r-flex-column p-[32px] r-gap-24">
|
||||||
<div className="labels-container ">
|
<div className="labels-container ">
|
||||||
<div className="label-container">
|
<div className="label-container">
|
||||||
<FloatingLabelInput label="Nom de l’organisation" name="org-name" type="text" placeholder="Intside" defaultValue="" />
|
<FloatingLabelInput label="Nom de l’organisation" name="org-name" type="text" placeholder="Intside" defaultValue={companyInfos?.name} />
|
||||||
</div>
|
</div>
|
||||||
<div className="label-container">
|
<div className="label-container">
|
||||||
<FloatingLabelInput label="Adresse e-mail de l’admin" name="email" type="text" placeholder="contact@intside.com" defaultValue={company?.owner.email} />
|
<FloatingLabelInput label="Adresse e-mail de l’admin" name="email" type="text" placeholder="contact@intside.com" defaultValue={companyInfos?.owner.email} />
|
||||||
</div>
|
</div>
|
||||||
<div className="label-container">
|
<div className="label-container">
|
||||||
<FloatingLabelInput label="Nom de l’admin" name="admin-name" type="text" placeholder="Company" defaultValue={company?.owner.last_name} />
|
<FloatingLabelInput label="Nom de l’admin" name="admin-name" type="text" placeholder="Company" defaultValue={companyInfos?.owner.last_name} />
|
||||||
</div>
|
</div>
|
||||||
<div className="label-container">
|
<div className="label-container">
|
||||||
<FloatingLabelInput label="Prénom de l’admin" name="admin-surname" type="text" placeholder="Intside" defaultValue={company?.owner.last_name} />
|
<FloatingLabelInput label="Prénom de l’admin" name="admin-surname" type="text" placeholder="Intside" defaultValue={companyInfos?.owner.last_name} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="ctas flex gap-12 ">
|
<div className="ctas flex gap-12 ">
|
||||||
|
|||||||
@ -1,51 +1,51 @@
|
|||||||
/* Sidebar */
|
/* Sidebar */
|
||||||
|
|
||||||
.sidebar{
|
.sidebar {
|
||||||
border-right: 1px solid var(--cinder);
|
border-right: 1px solid var(--cinder);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item .nav-home{
|
.nav-item .nav-home {
|
||||||
margin-bottom: -10px;
|
margin-bottom: -10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item{
|
.nav-item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: max-content;
|
height: max-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item.active{
|
.nav-item.active {
|
||||||
border-right: 2px solid var(--primary);
|
border-right: 2px solid var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item svg{
|
.nav-item svg {
|
||||||
color: var(--primary)!important;
|
color: var(--primary) !important;
|
||||||
background-color: var(--primary)!important;
|
background-color: var(--primary) !important;
|
||||||
fill: var(--primary)!important;
|
fill: var(--primary) !important;
|
||||||
stroke: var(--primary)!important
|
stroke: var(--primary) !important
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-home{
|
.nav-home {
|
||||||
margin-top: -11px;
|
margin-top: -11px;
|
||||||
margin-bottom: -11px;
|
margin-bottom: -11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Border */
|
/* Border */
|
||||||
.icon-border{
|
.icon-border {
|
||||||
border: 1px solid var(--cinder);
|
border: 1px solid var(--cinder);
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu{
|
.dropdown-menu {
|
||||||
width: max-content;
|
width: max-content;
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 0 24px #0000001A;
|
box-shadow: 0 0 24px #0000001A;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item a{
|
.dropdown-item a {
|
||||||
width: max-content;
|
width: max-content;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -62,7 +62,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-rounded{
|
.icon-rounded {
|
||||||
width: max-content;
|
width: max-content;
|
||||||
height: max-content;
|
height: max-content;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
@ -72,15 +72,37 @@
|
|||||||
background-color: var(--bluegray);
|
background-color: var(--bluegray);
|
||||||
border-radius: 100px;
|
border-radius: 100px;
|
||||||
}
|
}
|
||||||
.labels-container{
|
|
||||||
|
.labels-container {
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
}
|
}
|
||||||
.labels-container .label-container{
|
|
||||||
|
.labels-container .label-container {
|
||||||
width: 40%;
|
width: 40%;
|
||||||
}
|
}
|
||||||
.labels-container .floating-label div.relative{
|
|
||||||
|
.labels-container .floating-label div.relative {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-infos {
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.admin-card {
|
||||||
|
width: 284px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.admin-infos {
|
||||||
|
/* justify-content: space-between; */
|
||||||
|
/* gap: 30px; */
|
||||||
|
}
|
||||||
|
.admin-card {
|
||||||
|
/* max-width: 100%; */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -119,6 +119,9 @@
|
|||||||
.r-gap-70{
|
.r-gap-70{
|
||||||
gap: 70px;
|
gap: 70px;
|
||||||
}
|
}
|
||||||
|
.r-r-gap-12{
|
||||||
|
row-gap: 12px;
|
||||||
|
}
|
||||||
/* Small (SM) */
|
/* Small (SM) */
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
/* Styles for small devices and up */
|
/* Styles for small devices and up */
|
||||||
|
|||||||
@ -5,71 +5,71 @@ import { FormProps } from "#/types"
|
|||||||
import { FormEvent, useState } from "react"
|
import { FormEvent, useState } from "react"
|
||||||
|
|
||||||
export default function Form({
|
export default function Form({
|
||||||
fields,
|
fields,
|
||||||
submit,
|
submit,
|
||||||
className,
|
className,
|
||||||
child,
|
child,
|
||||||
title,
|
title,
|
||||||
schema
|
schema
|
||||||
} : FormProps) {
|
}: FormProps) {
|
||||||
const [errors, setErrors] = useState<Record<string, string>>({});
|
const [errors, setErrors] = useState<Record<string, string>>({});
|
||||||
|
|
||||||
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
|
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
const formData = new FormData(e.currentTarget)
|
const formData = new FormData(e.currentTarget)
|
||||||
const data = Object.fromEntries(formData)
|
const data = Object.fromEntries(formData)
|
||||||
|
|
||||||
console.log("FORM DATA = ", data)
|
console.log("FORM DATA = ", data)
|
||||||
const result = schema.safeParse(data);
|
const result = schema.safeParse(data);
|
||||||
console.log("ZOD = ", result.error?.format())
|
console.log("ZOD = ", result.error?.format())
|
||||||
|
|
||||||
if(!result.success) {
|
if (!result.success) {
|
||||||
const formatedErrors = result.error.format() as Record<string, { _errors?: string[] }>;
|
const formatedErrors = result.error.format() as Record<string, { _errors?: string[] }>;
|
||||||
|
|
||||||
const newErrors: Record<string, string> = {};
|
const newErrors: Record<string, string> = {};
|
||||||
Object.keys(formatedErrors).forEach((field) => {
|
Object.keys(formatedErrors).forEach((field) => {
|
||||||
if (field !== "_errors" && formatedErrors[field]._errors?.length) {
|
if (field !== "_errors" && formatedErrors[field]._errors?.length) {
|
||||||
newErrors[field] = formatedErrors[field]._errors[0];
|
newErrors[field] = formatedErrors[field]._errors[0];
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setErrors(newErrors)
|
|
||||||
} else {
|
|
||||||
setErrors({})
|
|
||||||
submit(result.data)
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setErrors(newErrors)
|
||||||
|
} else {
|
||||||
|
setErrors({})
|
||||||
|
submit(result.data)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className={className} onSubmit={handleSubmit}>
|
<form className={className} onSubmit={handleSubmit}>
|
||||||
<div className="flex justify-center text-black">
|
<div className="flex justify-center text-black">
|
||||||
<p className="text-3xl font-bold">{title}</p>
|
<p className="text-3xl font-bold">{title}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-8 mt-2">
|
||||||
|
|
||||||
|
{
|
||||||
|
fields.map((item, index) => (
|
||||||
|
<div key={index}>
|
||||||
|
<FloatingLabelInput
|
||||||
|
label={item.label}
|
||||||
|
name={item.name}
|
||||||
|
type={item.type}
|
||||||
|
button={item.button}
|
||||||
|
defaultValue={item.defaultValue}
|
||||||
|
options={item.options}
|
||||||
|
placeholder={item.placeholder}
|
||||||
|
showPasswordToggle={item.showPasswordToggle}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span className="text-red-500 text-xs mt-1">{errors[item.name]}</span>
|
||||||
</div>
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
{child}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
<div className="flex flex-col gap-8 mt-2">
|
)
|
||||||
|
|
||||||
{
|
|
||||||
fields.map((item, index) => (
|
|
||||||
<div key={index}>
|
|
||||||
<FloatingLabelInput
|
|
||||||
label={item.label}
|
|
||||||
name={item.name}
|
|
||||||
type={item.type}
|
|
||||||
button={item.button}
|
|
||||||
defaultValue={item.defaultValue}
|
|
||||||
options={item.options}
|
|
||||||
placeholder={item.placeholder}
|
|
||||||
showPasswordToggle={item.showPasswordToggle}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span className="text-red-500 text-xs mt-1">{errors[item.name]}</span>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
{child}
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
@ -3,4 +3,12 @@ import { z } from "zod";
|
|||||||
export const loginSchema = z.object({
|
export const loginSchema = z.object({
|
||||||
email: z.string().email("Email invalide"),
|
email: z.string().email("Email invalide"),
|
||||||
password: z.string().min(8, "Le mot de passe doit contenir au moins 8 caractères")
|
password: z.string().min(8, "Le mot de passe doit contenir au moins 8 caractères")
|
||||||
|
});
|
||||||
|
|
||||||
|
export const adminSchema = z.object({
|
||||||
|
id: z.string().optional(),
|
||||||
|
last_name: z.string(),
|
||||||
|
first_name: z.string(),
|
||||||
|
email: z.string().min(1, "L'email est requis").email("Email invalide"),
|
||||||
|
organization: z.string().optional(),
|
||||||
});
|
});
|
||||||
@ -51,11 +51,14 @@ export interface Owner {
|
|||||||
last_name: string
|
last_name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CompanyById {
|
export interface CompanyById {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
is_premium: boolean
|
is_premium: boolean
|
||||||
status: string
|
status: string
|
||||||
owner: string
|
owner: Owner
|
||||||
description: string
|
total_users: number
|
||||||
}
|
total_documents: number
|
||||||
|
total_documents_sizes: number
|
||||||
|
last_use: any
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user