Compare commits
4 Commits
a6f18f294c
...
28b1e5bf99
| Author | SHA1 | Date | |
|---|---|---|---|
| 28b1e5bf99 | |||
| 98ba95dc01 | |||
| 3e1cf17b2d | |||
| a4970ac2cd |
@ -26,7 +26,7 @@ export default function Dashboard({ children }: { children: ReactNode }) {
|
||||
<Sidebar />
|
||||
<main className="flex-grow-1 min-w-0 pt-md-1 pt-sm-5">
|
||||
<Header/>
|
||||
<div className="p-4">
|
||||
<div className="main px-[44px] py-[64px] ">
|
||||
{children}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
164
src/app/admin/organizations/[id]/page.tsx
Normal file
164
src/app/admin/organizations/[id]/page.tsx
Normal file
@ -0,0 +1,164 @@
|
||||
"use client"
|
||||
import { icons } from "#/assets/icons"
|
||||
import Image from "next/image"
|
||||
import axios from "axios";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Company, CompanyById, Owner } from "#/types";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
|
||||
export default function Profile() {
|
||||
|
||||
const pathname = usePathname();
|
||||
|
||||
const segments = pathname.split("/");
|
||||
const uid = segments[segments.length - 1];
|
||||
|
||||
|
||||
const { data: session, status } = useSession();
|
||||
|
||||
const { data: companyInfos, isLoading } = useQuery({
|
||||
enabled: status === 'authenticated',
|
||||
queryKey: ["companyStats", session?.user.access_token],
|
||||
queryFn: async () => {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`https://private-docs-api.intside.co/companies/${uid}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${session?.user.access_token}`
|
||||
},
|
||||
params: {
|
||||
details: true
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (response.data) {
|
||||
return response.data as CompanyById;
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
const adminId = companyInfos?.owner;
|
||||
console.log('will run the admin request');
|
||||
|
||||
const { data: adminInfos } = useQuery({
|
||||
enabled: !!adminId && status === 'authenticated', // Only run when adminId is available
|
||||
queryKey: ["admin", adminId], // Ensure adminId is used in the query key
|
||||
queryFn: async () => {
|
||||
console.log('running the admin request');
|
||||
//console.log('url :', `https://private-docs-api.intside.co/users/${adminId}`);
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`https://private-docs-api.intside.co/users/${adminId}`, { // Use adminId instead of companyInfos
|
||||
headers: {
|
||||
'Authorization': `Bearer ${session?.user.access_token}`
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (response.data) {
|
||||
return response.data as Owner;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
*/
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* {companyInfos[0]?.id} */}
|
||||
<div className="p-container ">
|
||||
<div className="r-flex-column">
|
||||
<div className="r-flex-between items-center bg-bluegray p-[24px] m-0 ">
|
||||
<div className=""></div>
|
||||
<h2 className="admin-name text-[20px]" >{companyInfos?.name || "Pentatonic"}</h2>
|
||||
<Link href={`http://localhost:3000/admin/organizations/${uid}/update`} type="Link" className="update-profile-name cta">
|
||||
Modifier
|
||||
</Link>
|
||||
</div>
|
||||
<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>
|
||||
<div className="r-flex flex-wrap r-r-gap-12 gap-[12px]">
|
||||
<div className="r-flex-between items-center w-max">
|
||||
<div className="icon-rounded">
|
||||
<Image src={icons.mailIcon} alt="E-mail" />
|
||||
</div>
|
||||
<div className="r-flex-column p-[14px] admin-card r-gap-2">
|
||||
<h4 className="email-label font-semibold">Adresse e-mail</h4>
|
||||
<p className="email">{companyInfos?.owner?.email || "email"}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="r-flex-between items-center w-max">
|
||||
<div className="icon-rounded">
|
||||
<Image src={icons.personalCard} alt="E-mail" />
|
||||
</div>
|
||||
<div className="r-flex gap-[12px] admin-card">
|
||||
<div className="r-flex-column p-[14px] r-gap-2">
|
||||
<h4 className="surname-label font-semibold">Prénom</h4>
|
||||
<p className="surname">{companyInfos?.owner?.first_name || "nom"}</p>
|
||||
</div>
|
||||
<div className="r-flex-column p-[14px] r-gap-2">
|
||||
<h4 className="name-label font-semibold">Nom</h4>
|
||||
<p className="name">{companyInfos?.owner?.last_name || "nom"}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div className="r-flex p-[32px] r-gap-24">
|
||||
<div className="admin-infos r-flex flex-wrap justifyc-center lg:justifyc-start ">
|
||||
<div className="r-flex-between items-center w-max">
|
||||
<div className="icon-rounded">
|
||||
<Image src={icons.userGroupBlue} alt="Documents" />
|
||||
</div>
|
||||
<div className="r-flex-column p-[14px] admin-card r-gap-2">
|
||||
<h4 className="users-label font-semibold">Documents</h4>
|
||||
<p className="r-secondary users">{companyInfos?.total_documents || "0"}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="r-flex-between items-center w-max">
|
||||
<div className="icon-rounded">
|
||||
<Image src={icons.userGroupBlue} alt="Documents" />
|
||||
</div>
|
||||
<div className="r-flex-column p-[14px] admin-card r-gap-2">
|
||||
<h4 className="users-label font-semibold">Utilisateurs</h4>
|
||||
<p className="r-secondary users">{companyInfos?.total_users || "0"}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="r-flex-between items-center w-max">
|
||||
<div className="icon-rounded">
|
||||
<Image src={icons.maximizeIcon} alt="Fichiers" />
|
||||
</div>
|
||||
<div className="r-flex-column p-[14px] admin-card r-gap-2">
|
||||
<h4 className="files-size-label font-semibold">Taille des fichiers</h4>
|
||||
<p className="r-secondary files-size">{companyInfos?.total_documents_sizes + " "}GB</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="r-flex-between items-center w-max">
|
||||
<div className="icon-rounded">
|
||||
<Image src={icons.timerIcon} alt="Horlorge" />
|
||||
</div>
|
||||
<div className="r-flex-column p-[14px] admin-card r-gap-2">
|
||||
<h4 className="last-connexion-label font-semibold">Dernière utilisation</h4>
|
||||
<p className="r-secondary last-connexion">{companyInfos?.last_use || "-"}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
147
src/app/admin/organizations/[id]/update/page.tsx
Normal file
147
src/app/admin/organizations/[id]/update/page.tsx
Normal file
@ -0,0 +1,147 @@
|
||||
"use client"
|
||||
import { icons } from "#/assets/icons"
|
||||
import Image from "next/image"
|
||||
import axios from "axios";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { Company, CompanyById } from "#/types";
|
||||
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() {
|
||||
|
||||
const pathname = usePathname();
|
||||
|
||||
const segments = pathname.split("/");
|
||||
const uid = segments[segments.length - 2];
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
|
||||
const { data: session, status } = useSession();
|
||||
|
||||
const { data: companyInfos, refetch, isLoading } = useQuery({
|
||||
enabled: status === 'authenticated',
|
||||
queryKey: ["companyStats", session?.user.access_token],
|
||||
queryFn: async () => {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`https://private-docs-api.intside.co/users/${uid}`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${session?.user.access_token}`
|
||||
},
|
||||
params: {
|
||||
details: true
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (response.data) {
|
||||
return response.data as CompanyById;
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const { mutate, isPending } = useMutation({
|
||||
mutationFn: async (id: string) => {
|
||||
try {
|
||||
const response = await axios.delete(
|
||||
`https://private-docs-api.intside.co/companies/${id}/`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${session?.user.access_token}`
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
if (response.status === 200 || response.status === 201) {
|
||||
console.log('Suppresion réussie !')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["companies"] })
|
||||
|
||||
refetch()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* { 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="r-flex-column">
|
||||
<div className="r-flex-between items-center bg-bluegray p-[24px] m-0 ">
|
||||
<div className=""></div>
|
||||
<h2 className="admin-name text-[20px]" >{companyInfos?.name || "Pentatonic"}</h2>
|
||||
<Link href={`http://localhost:3000/admin/organizations/${uid}/`} type="Link" className="cta cancel">
|
||||
Annuler
|
||||
</Link>
|
||||
</div>
|
||||
<div className="r-flex-column p-[32px] r-gap-24">
|
||||
<div className="labels-container ">
|
||||
<div className="label-container">
|
||||
<FloatingLabelInput label="Nom de l’organisation" name="org-name" type="text" placeholder="Intside" defaultValue={companyInfos?.name} />
|
||||
</div>
|
||||
<div className="label-container">
|
||||
<FloatingLabelInput label="Adresse e-mail de l’admin" name="email" type="text" placeholder="contact@intside.com" defaultValue={companyInfos?.owner.email} />
|
||||
</div>
|
||||
<div className="label-container">
|
||||
<FloatingLabelInput label="Nom de l’admin" name="admin-name" type="text" placeholder="Company" defaultValue={companyInfos?.owner.last_name} />
|
||||
</div>
|
||||
<div className="label-container">
|
||||
<FloatingLabelInput label="Prénom de l’admin" name="admin-surname" type="text" placeholder="Intside" defaultValue={companyInfos?.owner.last_name} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="ctas flex gap-12 ">
|
||||
<button type="button" className="cta">Modifier</button>
|
||||
<button type="button" className="cta info">Mot de passe</button>
|
||||
<button type="button" className="cta danger">Bloquer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -14,6 +14,8 @@
|
||||
--secondary: #9FA8BC;
|
||||
--danger: #F33F19;
|
||||
--cinder: #E7E5E4;
|
||||
--bluegray: #E9F0FF;
|
||||
--gray: #E7EBF3;
|
||||
}
|
||||
|
||||
[ data-theme="dark"] {
|
||||
@ -98,6 +100,72 @@ body {
|
||||
transition: width 0.2s, height 0.2s;
|
||||
}
|
||||
|
||||
.cta{
|
||||
padding: 10px 24px;
|
||||
color: white;
|
||||
background-color: var(--primary);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
border: 1px solid var(--primary);
|
||||
border-radius: 100px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cta.cancel{
|
||||
color: var(--secondary);
|
||||
border: 1px solid var(--gray);
|
||||
background-color: var(--gray);
|
||||
}
|
||||
|
||||
.cta.info{
|
||||
color: var(--primary);
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
.cta.danger{
|
||||
border: 1px solid var(--danger);
|
||||
background-color: var(--danger);
|
||||
}
|
||||
|
||||
|
||||
.bg-bluegray{
|
||||
background-color: var(--bluegray);
|
||||
}
|
||||
.bg-gray{
|
||||
background-color: var(--gray);
|
||||
}
|
||||
hr{
|
||||
color: var(--gray);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Scroll Bar */
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--primary);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track:hover {
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--primary);
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.responsive-icon {
|
||||
width: 20px;
|
||||
|
||||
@ -1,53 +1,108 @@
|
||||
.sidebar{
|
||||
/* Sidebar */
|
||||
|
||||
.sidebar {
|
||||
border-right: 1px solid var(--cinder);
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.nav-item .nav-home{
|
||||
.nav-item .nav-home {
|
||||
margin-bottom: -10px;
|
||||
}
|
||||
|
||||
.nav-item{
|
||||
.nav-item {
|
||||
width: 100%;
|
||||
height: max-content;
|
||||
}
|
||||
|
||||
.nav-item.active{
|
||||
.nav-item.active {
|
||||
border-right: 2px solid var(--primary);
|
||||
}
|
||||
|
||||
.nav-item svg{
|
||||
color: var(--primary)!important;
|
||||
background-color: var(--primary)!important;
|
||||
fill: var(--primary)!important;
|
||||
stroke: var(--primary)!important
|
||||
.nav-item svg {
|
||||
color: var(--primary) !important;
|
||||
background-color: var(--primary) !important;
|
||||
fill: var(--primary) !important;
|
||||
stroke: var(--primary) !important
|
||||
}
|
||||
|
||||
.nav-home{
|
||||
.nav-home {
|
||||
margin-top: -11px;
|
||||
margin-bottom: -11px;
|
||||
}
|
||||
|
||||
.icon-border{
|
||||
/* Border */
|
||||
.icon-border {
|
||||
border: 1px solid var(--cinder);
|
||||
padding: 8px;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dropdown-menu{
|
||||
.dropdown-menu {
|
||||
width: max-content;
|
||||
background-color: var(--background);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 24px #0000001A;
|
||||
}
|
||||
.dropdown-item{
|
||||
|
||||
}
|
||||
.dropdown-item a{
|
||||
|
||||
.dropdown-item a {
|
||||
width: max-content;
|
||||
padding: 10px 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* Main */
|
||||
|
||||
.p-container {
|
||||
height: 100vh;
|
||||
border: 1px solid var(--gray);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icon-rounded {
|
||||
width: max-content;
|
||||
height: max-content;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--bluegray);
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
.labels-container {
|
||||
min-width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.labels-container .label-container {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.labels-container .floating-label div.relative {
|
||||
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{
|
||||
gap: 70px;
|
||||
}
|
||||
.r-r-gap-12{
|
||||
row-gap: 12px;
|
||||
}
|
||||
/* Small (SM) */
|
||||
@media (min-width: 640px) {
|
||||
/* Styles for small devices and up */
|
||||
|
||||
@ -40,6 +40,8 @@ import arrowUp from "./Vector.svg"
|
||||
import sunIcon from "./sun.svg"
|
||||
import moonIcon from "./moon.svg"
|
||||
import trash from "./trash.svg"
|
||||
import mailIcon from "./sms.svg"
|
||||
import personalCard from "./personalcard.svg"
|
||||
|
||||
|
||||
export const icons = {
|
||||
@ -83,8 +85,10 @@ export const icons = {
|
||||
starIcon,
|
||||
arrowUp,
|
||||
sunIcon,
|
||||
moonIcon ,
|
||||
trash
|
||||
moonIcon,
|
||||
trash,
|
||||
mailIcon,
|
||||
personalCard
|
||||
}
|
||||
|
||||
|
||||
|
||||
8
src/assets/icons/personalcard.svg
Normal file
8
src/assets/icons/personalcard.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17 21H7C3 21 2 20 2 16V8C2 4 3 3 7 3H17C21 3 22 4 22 8V16C22 20 21 21 17 21Z" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M14 8H19" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M15 12H19" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M17 16H19" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M8.49994 11.2899C9.49958 11.2899 10.3099 10.4796 10.3099 9.47992C10.3099 8.48029 9.49958 7.66992 8.49994 7.66992C7.50031 7.66992 6.68994 8.48029 6.68994 9.47992C6.68994 10.4796 7.50031 11.2899 8.49994 11.2899Z" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 16.33C11.86 14.88 10.71 13.74 9.26 13.61C8.76 13.56 8.25 13.56 7.74 13.61C6.29 13.75 5.14 14.88 5 16.33" stroke="#246BFD" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
4
src/assets/icons/sms.svg
Normal file
4
src/assets/icons/sms.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17 20.5H7C4 20.5 2 19 2 15.5V8.5C2 5 4 3.5 7 3.5H17C20 3.5 22 5 22 8.5V15.5C22 19 20 20.5 17 20.5Z" stroke="#246BFD" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M17 9L13.87 11.5C12.84 12.32 11.15 12.32 10.12 11.5L7 9" stroke="#246BFD" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 495 B |
@ -14,7 +14,7 @@ export default function AdminHeader() {
|
||||
return (
|
||||
<>
|
||||
<nav className="header r-flex-between px-[44px] py-[20px] ">
|
||||
<p className="name text-[26px]">Bienvenue, <span>Ken B.</span> </p>
|
||||
<h1 className="name text-[26px]">Bienvenue, <span>Ken B.</span> </h1>
|
||||
<div className="r-flex-between justify-center items-center r-gap-12">
|
||||
<Theme />
|
||||
{/* <ProfilePicture /> */}
|
||||
|
||||
@ -8,23 +8,25 @@ import Link from "next/link";
|
||||
|
||||
export default function Sidebar() {
|
||||
|
||||
const pathname = usePathname();
|
||||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="sidebar r-m-0 d-flex flex-column pt-[25px] max-w-[90px] h-[100vh] relative ">
|
||||
<div className="logo r-flex-center px-[20px] ">
|
||||
<Image src={icons.logo} alt="Logo" className="scale-95" />
|
||||
</div>
|
||||
<div className="nav-menu r-column-center h-max pt-[160px] r-gap-40 ">
|
||||
<NavItem link="/admin/home" iconSrc={icons.homeIcon} label="Home" isNavHome={true} isActive={(pathname === "/admin/") || (pathname === "/admin/home")} />
|
||||
<NavItem link="/admin/organizations" iconSrc={icons.companiesIcon} label="Organizations" isActive={pathname.startsWith("/admin/organizations")} />
|
||||
<NavItem link="/admin/admins" iconSrc={icons.userGroup} label="Admins" isActive={pathname.startsWith("/admin/admins")} />
|
||||
</div>
|
||||
<div className="logout absolute bottom-[40px] left-[28px]">
|
||||
<Link href="#" className="cursor-pointer">
|
||||
<Image src={icons.logout} alt="Logout" />
|
||||
</Link>
|
||||
<div className="sidebar-holder min-w-[78px] max-w-[90px] h-[100vh] ">
|
||||
<div className="sidebar r-m-0 d-flex flex-column pt-[25px] max-w-[90px] h-[100vh] ">
|
||||
<div className="logo r-flex-center px-[19px] ">
|
||||
<Image src={icons.logo} alt="Logo" className="scale-95" />
|
||||
</div>
|
||||
<div className="nav-menu r-column-center h-max pt-[160px] r-gap-40 ">
|
||||
<NavItem link="/admin/home" iconSrc={icons.homeIcon} label="Home" isNavHome={true} isActive={(pathname === "/admin/") || (pathname === "/admin/home")} />
|
||||
<NavItem link="/admin/organizations" iconSrc={icons.companiesIcon} label="Organizations" isActive={pathname.startsWith("/admin/organizations")} />
|
||||
<NavItem link="/admin/admins" iconSrc={icons.userGroup} label="Admins" isActive={pathname.startsWith("/admin/admins")} />
|
||||
</div>
|
||||
<div className="logout absolute bottom-[40px] left-[28px]">
|
||||
<Link href="/login" className="cursor-pointer">
|
||||
<Image src={icons.logout} alt="Logout" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
14
src/schema/loginSchema.ts
Normal file
14
src/schema/loginSchema.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const loginSchema = z.object({
|
||||
email: z.string().email("Email invalide"),
|
||||
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(),
|
||||
});
|
||||
@ -65,4 +65,15 @@ export interface Admin {
|
||||
first_name: string
|
||||
last_name: string
|
||||
profile: string
|
||||
}
|
||||
export interface CompanyById {
|
||||
id: string
|
||||
name: string
|
||||
is_premium: boolean
|
||||
status: string
|
||||
owner: Owner
|
||||
total_users: number
|
||||
total_documents: number
|
||||
total_documents_sizes: number
|
||||
last_use: any
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user