Compare commits
5 Commits
c647d2bedd
...
80cf569f8b
| Author | SHA1 | Date | |
|---|---|---|---|
| 80cf569f8b | |||
| cb14a0c7cd | |||
| 701b4f2d05 | |||
| 562469349f | |||
| 9b4d8cf02f |
@ -9,7 +9,7 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-icons": "^1.3.2",
|
||||
"@radix-ui/react-dialog": "^1.1.6",
|
||||
"@tanstack/react-query": "^5.69.0",
|
||||
"@tanstack/react-table": "^8.21.2",
|
||||
"axios": "^1.8.4",
|
||||
|
||||
15
pnpm-lock.yaml
generated
15
pnpm-lock.yaml
generated
@ -8,9 +8,9 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@radix-ui/react-icons':
|
||||
specifier: ^1.3.2
|
||||
version: 1.3.2(react@19.0.0)
|
||||
'@radix-ui/react-dialog':
|
||||
specifier: ^1.1.6
|
||||
version: 1.1.6(@types/react-dom@19.0.4(@types/react@19.0.12))(@types/react@19.0.12)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.69.0
|
||||
version: 5.69.0(react@19.0.0)
|
||||
@ -1262,11 +1262,6 @@ packages:
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-icons@1.3.2':
|
||||
resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==}
|
||||
peerDependencies:
|
||||
react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc
|
||||
|
||||
'@radix-ui/react-id@1.1.0':
|
||||
resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==}
|
||||
peerDependencies:
|
||||
@ -4938,10 +4933,6 @@ snapshots:
|
||||
'@types/react': 19.0.12
|
||||
'@types/react-dom': 19.0.4(@types/react@19.0.12)
|
||||
|
||||
'@radix-ui/react-icons@1.3.2(react@19.0.0)':
|
||||
dependencies:
|
||||
react: 19.0.0
|
||||
|
||||
'@radix-ui/react-id@1.1.0(@types/react@19.0.12)(react@19.0.0)':
|
||||
dependencies:
|
||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.12)(react@19.0.0)
|
||||
|
||||
@ -9,12 +9,14 @@ import { ColumnDef } from "@tanstack/react-table"
|
||||
import axios from "axios"
|
||||
import { useSession } from "next-auth/react"
|
||||
import Image from "next/image"
|
||||
|
||||
import { Modal } from "#/components/modal"
|
||||
import { useState } from "react"
|
||||
|
||||
export default function HomePage () {
|
||||
|
||||
const {data: session, status} = useSession()
|
||||
const queryClient = useQueryClient()
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
console.log("Session = ", session)
|
||||
|
||||
@ -91,7 +93,31 @@ export default function HomePage () {
|
||||
},
|
||||
{
|
||||
accessorKey: "status",
|
||||
header: "Statut"
|
||||
header: "Statut",
|
||||
cell: ({ cell }) => {
|
||||
const status = String(cell.getValue())
|
||||
return (
|
||||
<p
|
||||
className={`rounded-full px-2 py-1 font-medium text-sm w-20 h-6 text-center
|
||||
${
|
||||
status === "active" ? "bg-[#ECF9E8] text-[#49C91E]" :
|
||||
status === "inactive" ? "bg-[#E7EBF3] text-[#9FA8BC]" :
|
||||
status === "pending" ? "bg-[#EAF7FC] text-[#30B2EA]" :
|
||||
status === "blocked" ? "bg-[#FDEBE8] text-[#F33F19]" :
|
||||
""
|
||||
}
|
||||
`}
|
||||
>
|
||||
{
|
||||
status === "active" ? "Actif" :
|
||||
status === "inactive" ? "Inactif" :
|
||||
status === "pending" ? "En attente" :
|
||||
status === "blocked" ? "Bloquée" :
|
||||
""
|
||||
}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "delete",
|
||||
@ -99,10 +125,43 @@ export default function HomePage () {
|
||||
const id = String(cell.row.original.id)
|
||||
return (
|
||||
<div className="relative p-2 cursor-pointer"
|
||||
onClick={() => { mutate(id) }}
|
||||
// onClick={() => { mutate(id) }}
|
||||
>
|
||||
<Image alt="" src={icons.trash} className="absolute right-2 top-[-50%] transform translate-middle-y hover:text-blue-500" />
|
||||
</div>
|
||||
<Modal
|
||||
open={open}
|
||||
trigger={
|
||||
<div onClick={() => setOpen(true)}>
|
||||
<Image alt="" src={icons.trash} className="absolute right-2 top-[-50%] transform translate-middle-y hover:text-blue-500" />
|
||||
</div>
|
||||
}
|
||||
title={
|
||||
<p className="font-bold text-3xl">Supprimer une organisation</p>
|
||||
}
|
||||
content={
|
||||
<div>
|
||||
<p>Voulez-vous vraiment supprimer cette organisation ?</p>
|
||||
|
||||
<div className="grid grid-cols-2 gap-3 mt-3">
|
||||
<button
|
||||
className="bg-blue-100 text-blue-600 py-2 px-4 text-lg rounded-full text-center hover:bg-blue-200"
|
||||
onClick={() => { setOpen(false) }}
|
||||
>
|
||||
Annuler
|
||||
</button>
|
||||
<button
|
||||
className="bg-red-500 text-white py-2 px-4 text-lg rounded-full text-center hover:bg-red-600"
|
||||
onClick={() => {
|
||||
mutate(id)
|
||||
setOpen(false)
|
||||
}}
|
||||
>
|
||||
Supprimer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -112,6 +171,8 @@ export default function HomePage () {
|
||||
<div className="space-y-10">
|
||||
<Statistics />
|
||||
|
||||
<p className="font-bold text-xl">Dernières organisations actives</p>
|
||||
|
||||
<Table
|
||||
columns={columns}
|
||||
data={companies || []}
|
||||
|
||||
@ -1,5 +1,12 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
@font-face {
|
||||
font-family: 'Urbanist'; /* Nom que vous donnerez à votre police */
|
||||
src: url('../assets/fonts/Urbanist.ttf') format('truetype'); /* Chemin vers votre fichier */
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
:root {
|
||||
--foreground: #04060F;
|
||||
--background: #ffffff;
|
||||
@ -24,7 +31,7 @@
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Inter, sans-serif;
|
||||
font-family: Urbanist, sans-serif;
|
||||
}
|
||||
|
||||
.input-form {
|
||||
|
||||
@ -25,7 +25,7 @@ export default function RootLayout({
|
||||
<link rel="icon" href="/favicon.svg" />
|
||||
<link rel="favicon.svg" href="/favicon.svg" />
|
||||
</head>
|
||||
<body className={inter.className}>
|
||||
<body>
|
||||
<AuthProvider>
|
||||
<QueryClientProvide>
|
||||
<NextTopLoader color="#246BFD" shadow="0" />
|
||||
|
||||
BIN
src/assets/fonts/Urbanist.ttf
Normal file
BIN
src/assets/fonts/Urbanist.ttf
Normal file
Binary file not shown.
@ -1,62 +1,63 @@
|
||||
import { GeneralHtmlAttr } from "#/lib/declarations";
|
||||
// import { GeneralHtmlAttr } from "#/lib/declarations";
|
||||
// import { SVGElementType } from "react";
|
||||
|
||||
const icons = {
|
||||
CalendarMark: "Calendar Mark.svg",
|
||||
Document: "Document.svg",
|
||||
Ellipse2: "Ellipse 2.svg",
|
||||
Group1: "Group (1).svg",
|
||||
Group: "Group.svg",
|
||||
Icons1: "Icons (1).svg",
|
||||
Icons: "Icons.svg",
|
||||
LineDuotone: "Line Duotone.svg",
|
||||
MenuDots: "Menu Dots.svg",
|
||||
NavItem: "NavItem.svg",
|
||||
Path1: "Path (1).svg",
|
||||
Path: "Path.svg",
|
||||
Rectangle: "Rectangle.svg",
|
||||
Search: "Search.svg",
|
||||
Vector: "Vector.svg",
|
||||
Add: "add.svg",
|
||||
Archives: "archives.svg",
|
||||
ArrowLeft: "arrowLeft.svg",
|
||||
ArrowRight: "arrowRight.svg",
|
||||
Buildings: "buildings.svg",
|
||||
Checked: "checked.svg",
|
||||
Cross: "cross.svg",
|
||||
DocumentText: "document-text.svg",
|
||||
Edit2: "edit-2.svg",
|
||||
Element3White: "element-3-white.svg",
|
||||
Element3: "element-3.svg",
|
||||
EyeSlash: "eye-slash.svg",
|
||||
Eye: "eye.svg",
|
||||
IconAdd: "icon-add.svg",
|
||||
Logo: "logo.svg",
|
||||
LogoutRed: "logout-red.svg",
|
||||
Logout: "logout.svg",
|
||||
Maximize3: "maximize-3.svg",
|
||||
Message: "message.svg",
|
||||
Notifications: "notifications.svg",
|
||||
PhFiles: "ph_files.svg",
|
||||
PrimeFilePdf: "prime_file-pdf.svg",
|
||||
PrimeFileWord: "prime_file-word.svg",
|
||||
Profile2UserBlue: "profile-2user-blue.svg",
|
||||
Profile2User: "profile-2user.svg",
|
||||
Profile: "profile.svg",
|
||||
Setting2: "setting-2.svg",
|
||||
Setting3: "setting-3.svg",
|
||||
Share: "share.svg",
|
||||
Star: "star.svg",
|
||||
Moon: "moon.svg",
|
||||
Sun: "sun.svg",
|
||||
};
|
||||
// const icons: SVGElementType[] = {
|
||||
// CalendarMark: "Calendar Mark.svg",
|
||||
// Document: "Document.svg",
|
||||
// Ellipse2: "Ellipse 2.svg",
|
||||
// Group1: "Group (1).svg",
|
||||
// Group: "Group.svg",
|
||||
// Icons1: "Icons (1).svg",
|
||||
// Icons: "Icons.svg",
|
||||
// LineDuotone: "Line Duotone.svg",
|
||||
// MenuDots: "Menu Dots.svg",
|
||||
// NavItem: "NavItem.svg",
|
||||
// Path1: "Path (1).svg",
|
||||
// Path: "Path.svg",
|
||||
// Rectangle: "Rectangle.svg",
|
||||
// Search: "Search.svg",
|
||||
// Vector: "Vector.svg",
|
||||
// Add: "add.svg",
|
||||
// Archives: "archives.svg",
|
||||
// ArrowLeft: "arrowLeft.svg",
|
||||
// ArrowRight: "arrowRight.svg",
|
||||
// Buildings: "buildings.svg",
|
||||
// Checked: "checked.svg",
|
||||
// Cross: "cross.svg",
|
||||
// DocumentText: "document-text.svg",
|
||||
// Edit2: "edit-2.svg",
|
||||
// Element3White: "element-3-white.svg",
|
||||
// Element3: "element-3.svg",
|
||||
// EyeSlash: "eye-slash.svg",
|
||||
// Eye: "eye.svg",
|
||||
// IconAdd: "icon-add.svg",
|
||||
// Logo: "logo.svg",
|
||||
// LogoutRed: "logout-red.svg",
|
||||
// Logout: "logout.svg",
|
||||
// Maximize3: "maximize-3.svg",
|
||||
// Message: "message.svg",
|
||||
// Notifications: "notifications.svg",
|
||||
// PhFiles: "ph_files.svg",
|
||||
// PrimeFilePdf: "prime_file-pdf.svg",
|
||||
// PrimeFileWord: "prime_file-word.svg",
|
||||
// Profile2UserBlue: "profile-2user-blue.svg",
|
||||
// Profile2User: "profile-2user.svg",
|
||||
// Profile: "profile.svg",
|
||||
// Setting2: "setting-2.svg",
|
||||
// Setting3: "setting-3.svg",
|
||||
// Share: "share.svg",
|
||||
// Star: "star.svg",
|
||||
// Moon: "moon.svg",
|
||||
// Sun: "sun.svg",
|
||||
// };
|
||||
|
||||
export const Icon = ({ name, ...props }: { name: keyof typeof icons } & GeneralHtmlAttr) => {
|
||||
const IconComponent = icons[name];
|
||||
if (!IconComponent) return null;
|
||||
// export const Icon = ({ name, ...props }: { name: keyof typeof icons } & GeneralHtmlAttr) => {
|
||||
// const IconComponent = icons[name];
|
||||
// if (!IconComponent) return null;
|
||||
|
||||
return (
|
||||
<div {...props}>
|
||||
<img src={`/icons/${IconComponent}`} alt={name} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
// return (
|
||||
// <div {...props}>
|
||||
// {}
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
39
src/components/modal.tsx
Normal file
39
src/components/modal.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import * as Dialog from "@radix-ui/react-dialog";
|
||||
import { ReactNode, useState } from "react";
|
||||
|
||||
export function Modal({
|
||||
trigger,
|
||||
title,
|
||||
content,
|
||||
open
|
||||
}: {
|
||||
trigger: ReactNode;
|
||||
title: string | ReactNode;
|
||||
content: ReactNode;
|
||||
open?: boolean;
|
||||
}) {
|
||||
const [toggle, setToggle] = useState(open);
|
||||
|
||||
return (
|
||||
<Dialog.Root open={toggle}>
|
||||
<Dialog.Trigger asChild>
|
||||
{trigger}
|
||||
</Dialog.Trigger>
|
||||
<Dialog.Portal>
|
||||
<Dialog.Overlay className="fixed inset-0 bg-black/25 z-40" />
|
||||
<Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-md bg-white rounded-lg shadow-xl z-50 p-6">
|
||||
<Dialog.Title className="text-xl font-bold text-center my-4">
|
||||
{title}
|
||||
</Dialog.Title>
|
||||
{content}
|
||||
|
||||
{/* <div className="absolute top-4 right-4 text-gray-500 hover:text-gray-700 cursor-pointer"
|
||||
onClick={() => {setToggle(false)}}
|
||||
>
|
||||
Fermer
|
||||
</div> */}
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
@ -64,8 +64,8 @@ export default function Table<TData, TValue>({
|
||||
|
||||
return(
|
||||
<div>
|
||||
<div className="rounded-lg border border-gray-200">
|
||||
<table className="w-full overflow-x-auto rounded-lg " style={{ borderTopLeftRadius: '10px', borderTopRightRadius: '10px', }}>
|
||||
<div className="rounded-lg border border-gray-200 w-auto">
|
||||
<table className="w-full overflow-x-auto rounded-lg">
|
||||
<thead className="h-10">
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<tr key={headerGroup.id} className="rounded-lg">
|
||||
@ -94,7 +94,7 @@ export default function Table<TData, TValue>({
|
||||
<tbody>
|
||||
{table.getRowModel().rows.length ? (
|
||||
table.getRowModel().rows.map((row) => (
|
||||
<tr key={row.id} className={clsx('hover:bg-gray-300 border-t border-gray-200', { 'bg-gray-300': row.getIsSelected()})}>
|
||||
<tr key={row.id} className={clsx('hover:bg-gray-100 border-t border-gray-200', { 'bg-gray-300': row.getIsSelected()})}>
|
||||
<td className="p-3 text-start">
|
||||
<input
|
||||
checked={row.getIsSelected()}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user