diff --git a/.env.production b/.env.production
deleted file mode 100644
index 6baf3c2..0000000
--- a/.env.production
+++ /dev/null
@@ -1,24 +0,0 @@
-# Configuration de production pour BTP Xpress Frontend
-# Ce fichier est utilisé pour la production
-
-# API Backend - URL de production
-NEXT_PUBLIC_API_URL=https://api.lions.dev/btpxpress
-NEXT_PUBLIC_API_TIMEOUT=15000
-
-# Keycloak Configuration
-NEXT_PUBLIC_KEYCLOAK_URL=https://security.lions.dev
-NEXT_PUBLIC_KEYCLOAK_REALM=btpxpress
-NEXT_PUBLIC_KEYCLOAK_CLIENT_ID=btpxpress-frontend
-
-# Application
-NEXT_PUBLIC_APP_NAME=BTP Xpress
-NEXT_PUBLIC_APP_VERSION=1.0.0
-NEXT_PUBLIC_APP_DESCRIPTION=Plateforme de gestion BTP
-NEXT_PUBLIC_APP_ENV=production
-
-# Theme
-NEXT_PUBLIC_DEFAULT_THEME=blue
-NEXT_PUBLIC_DEFAULT_THEME_MODE=light
-
-# Debug
-NEXT_PUBLIC_DEBUG=false
diff --git a/.gitignore b/.gitignore
index 94d72a6..ae21684 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,8 +30,12 @@ yarn-error.log*
# Local env files
.env
.env*.local
+.env.local
+.env.development
.env.development.local
+.env.test
.env.test.local
+.env.production
.env.production.local
# Vercel
@@ -39,6 +43,7 @@ yarn-error.log*
# TypeScript
*.tsbuildinfo
+tsconfig.tsbuildinfo
next-env.d.ts
# IDE
diff --git a/Dockerfile b/Dockerfile
index 7990f78..45ed2f4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -45,5 +45,9 @@ EXPOSE 3000
ENV PORT 3000
ENV HOSTNAME "0.0.0.0"
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
+ CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
+
CMD ["node", "server.js"]
diff --git a/app/(main)/blocks/page.tsx b/app/(main)/blocks/page.tsx
deleted file mode 100644
index 9241b03..0000000
--- a/app/(main)/blocks/page.tsx
+++ /dev/null
@@ -1,839 +0,0 @@
-'use client';
-
-import { Button } from 'primereact/button';
-import { Checkbox } from 'primereact/checkbox';
-import { Chip } from 'primereact/chip';
-import { InputText } from 'primereact/inputtext';
-import React, { useState } from 'react';
-import BlockViewer from '../../../demo/components/BlockViewer';
-
-const BlocksDemo = () => {
- const [checked, setChecked] = useState(false);
-
- const block1 = `
-
-
-
- Create the screens
- your visitors deserve to see
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
-
-
-
-
-
-
-

-
-
- `;
-
- const block2 = `
-
-
- One Product,
- Many Solutions
-
-
Ac turpis egestas maecenas pharetra convallis posuere morbi leo urna.
-
-
-
-
-
-
Built for Developers
-
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
-
-
-
-
-
-
End-to-End Encryption
-
Risus nec feugiat in fermentum posuere urna nec. Posuere sollicitudin aliquam ultrices sagittis.
-
-
-
-
-
-
Easy to Use
-
Ornare suspendisse sed nisi lacus sed viverra tellus. Neque volutpat ac tincidunt vitae semper.
-
-
-
-
-
-
Fast & Global Support
-
Fermentum et sollicitudin ac orci phasellus egestas tellus rutrum tellus.
-
-
-
-
-
-
Open Source
-
Nec tincidunt praesent semper feugiat. Sed adipiscing diam donec adipiscing tristique risus nec feugiat.
-
-
-
-
-
-
Trusted Securitty
-
Mattis rhoncus urna neque viverra justo nec ultrices. Id cursus metus aliquam eleifend.
-
-
-
- `;
-
- const block3 = `
-
Pricing Plans
-
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit numquam eligendi quos.
-
-
-
-
-
-
Basic
-
Plan description
-
-
- $9
- per month
-
-
-
- -
-
- Arcu vitae elementum
-
- -
-
- Dui faucibus in ornare
-
- -
-
- Morbi tincidunt augue
-
-
-
-
-
-
-
-
-
-
-
-
Premium
-
Plan description
-
-
- $29
- per month
-
-
-
- -
-
- Arcu vitae elementum
-
- -
-
- Dui faucibus in ornare
-
- -
-
- Morbi tincidunt augue
-
- -
-
- Duis ultricies lacus sed
-
-
-
-
-
-
-
-
-
-
-
-
Enterprise
-
Plan description
-
-
- $49
- per month
-
-
-
- -
-
- Arcu vitae elementum
-
- -
-
- Dui faucibus in ornare
-
- -
-
- Morbi tincidunt augue
-
- -
-
- Duis ultricies lacus sed
-
- -
-
- Imperdiet proin
-
- -
-
- Nisi scelerisque
-
-
-
-
-
-
-
-
-
`;
-
- const block4 = `
-
-
POWERED BY DISCORD
-
Join Our Design Community
-
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit numquam eligendi quos.
-
-
- `;
-
- const block5 = `
-
-
🔥 Hot Deals!
-
- Libero voluptatum atque exercitationem praesentium provident odit.
-
-
- Learn More
-
-
-
-
-
- `;
-
- const block6 = `
-
-
-
-
-
Customers
-
-
-
- 332 Active Users
-
-
-
- 9402 Sessions
-
-
-
- 2.32m Avg. Duration
-
-
-
-
-
-
-
-
-
- `;
-
- const block7 = `
-
-
-
-
-
24 new
-
since last visit
-
-
-
-
-
-
%52+
-
since last week
-
-
-
-
-
-
520
-
newly registered
-
-
-
-
-
-
-
Comments
-
152 Unread
-
-
-
-
-
-
85
-
responded
-
-
-
- `;
-
- const block8 = `
-
-
-
-
-
-
-
-
-
-
-
-
-
- setChecked(e.checked)} checked={checked} className="mr-2" />
-
-
-
Forgot your password?
-
-
-
-
-
-
- `;
-
- const block9 = `
-
-
Movie Information
-
Morbi tristique blandit turpis. In viverra ligula id nulla hendrerit rutrum.
-
- -
-
Title
- Heat
-
-
-
-
- -
-
Genre
-
-
-
-
-
-
-
-
-
- -
-
Director
- Michael Mann
-
-
-
-
- -
-
Actors
- Robert De Niro, Al Pacino
-
-
-
-
- -
-
Plot
-
- A group of professional bank robbers start to feel the heat from police
- when they unknowingly leave a clue at their latest heist.
-
-
-
-
-
-
- `;
-
- const block10 = `
-
-
Card Title
-
Vivamus id nisl interdum, blandit augue sit amet, eleifend mi.
-
-
- `;
-
- return (
- <>
-
-
-
-
- Create the screens
- your visitors deserve to see
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
-
-
-
-
-
-
-

-
-
-
-
-
-
-
- One Product,
- Many Solutions
-
-
Ac turpis egestas maecenas pharetra convallis posuere morbi leo urna.
-
-
-
-
-
-
Built for Developers
-
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
-
-
-
-
-
-
End-to-End Encryption
-
Risus nec feugiat in fermentum posuere urna nec. Posuere sollicitudin aliquam ultrices sagittis.
-
-
-
-
-
-
Easy to Use
-
Ornare suspendisse sed nisi lacus sed viverra tellus. Neque volutpat ac tincidunt vitae semper.
-
-
-
-
-
-
Fast & Global Support
-
Fermentum et sollicitudin ac orci phasellus egestas tellus rutrum tellus.
-
-
-
-
-
-
Open Source
-
Nec tincidunt praesent semper feugiat. Sed adipiscing diam donec adipiscing tristique risus nec feugiat.
-
-
-
-
-
-
Trusted Securitty
-
Mattis rhoncus urna neque viverra justo nec ultrices. Id cursus metus aliquam eleifend.
-
-
-
-
-
-
-
-
Pricing Plans
-
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit numquam eligendi quos.
-
-
-
-
-
-
Basic
-
Plan description
-
-
- $9
- per month
-
-
-
- -
-
- Arcu vitae elementum
-
- -
-
- Dui faucibus in ornare
-
- -
-
- Morbi tincidunt augue
-
-
-
-
-
-
-
-
-
-
-
-
Premium
-
Plan description
-
-
- $29
- per month
-
-
-
- -
-
- Arcu vitae elementum
-
- -
-
- Dui faucibus in ornare
-
- -
-
- Morbi tincidunt augue
-
- -
-
- Duis ultricies lacus sed
-
-
-
-
-
-
-
-
-
-
-
-
Enterprise
-
Plan description
-
-
- $49
- per month
-
-
-
- -
-
- Arcu vitae elementum
-
- -
-
- Dui faucibus in ornare
-
- -
-
- Morbi tincidunt augue
-
- -
-
- Duis ultricies lacus sed
-
- -
-
- Imperdiet proin
-
- -
-
- Nisi scelerisque
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- POWERED BY DISCORD
-
-
Join Our Design Community
-
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit numquam eligendi quos.
-
-
-
-
-
-
-
🔥 Hot Deals!
-
- Libero voluptatum atque exercitationem praesentium provident odit.
-
-
- Learn More
-
-
-
-
-
-
-
- Application UI
-
-
-
-
-
-
Customers
-
-
-
- 332 Active Users
-
-
-
- 9402 Sessions
-
-
-
- 2.32m Avg. Duration
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
24 new
-
since last visit
-
-
-
-
-
-
%52+
-
since last week
-
-
-
-
-
-
520
-
newly registered
-
-
-
-
-
-
-
Comments
-
152 Unread
-
-
-
-
-
-
85
-
responded
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- setChecked(e.checked as boolean)} checked={checked} className="mr-2" />
-
-
-
Forgot your password?
-
-
-
-
-
-
-
-
-
-
-
Movie Information
-
Morbi tristique blandit turpis. In viverra ligula id nulla hendrerit rutrum.
-
- -
-
Title
- Heat
-
-
-
-
- -
-
Genre
-
-
-
-
-
-
-
-
-
- -
-
Director
- Michael Mann
-
-
-
-
- -
-
Actors
- Robert De Niro, Al Pacino
-
-
-
-
- -
-
Plot
- A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist.
-
-
-
-
-
-
-
-
-
-
-
Card Title
-
Vivamus id nisl interdum, blandit augue sit amet, eleifend mi.
-
-
-
- >
- );
-};
-
-export default BlocksDemo;
diff --git a/app/(main)/pages/crud/page.tsx b/app/(main)/pages/crud/page.tsx
deleted file mode 100644
index 235e58d..0000000
--- a/app/(main)/pages/crud/page.tsx
+++ /dev/null
@@ -1,429 +0,0 @@
-'use client';
-
-import { Button } from 'primereact/button';
-import { Column } from 'primereact/column';
-import { DataTable } from 'primereact/datatable';
-import { Dialog } from 'primereact/dialog';
-import { FileUpload } from 'primereact/fileupload';
-import { InputNumber } from 'primereact/inputnumber';
-import { InputText } from 'primereact/inputtext';
-import { InputTextarea } from 'primereact/inputtextarea';
-import { RadioButton } from 'primereact/radiobutton';
-import { Rating } from 'primereact/rating';
-import { Toast } from 'primereact/toast';
-import { Toolbar } from 'primereact/toolbar';
-import { classNames } from 'primereact/utils';
-import React, { useEffect, useRef, useState } from 'react';
-import { ProductService } from '../../../../demo/service/ProductService';
-import type { Demo } from '@/types';
-
-const Crud = () => {
- let emptyProduct: Demo.Product = {
- id: null,
- name: '',
- image: null,
- description: '',
- category: null,
- price: 0,
- quantity: 0,
- rating: 0,
- inventoryStatus: 'INSTOCK'
- };
-
- const [products, setProducts] = useState(null);
- const [productDialog, setProductDialog] = useState(false);
- const [deleteProductDialog, setDeleteProductDialog] = useState(false);
- const [deleteProductsDialog, setDeleteProductsDialog] = useState(false);
- const [product, setProduct] = useState(emptyProduct);
- const [selectedProducts, setSelectedProducts] = useState(null);
- const [submitted, setSubmitted] = useState(false);
- const [globalFilter, setGlobalFilter] = useState(null);
- const toast = useRef(null);
- const dt = useRef(null);
-
- useEffect(() => {
- ProductService.getProducts().then((data) => setProducts(data));
- }, []);
-
- const formatCurrency = (value) => {
- return value.toLocaleString('en-US', {
- style: 'currency',
- currency: 'USD'
- });
- };
-
- const openNew = () => {
- setProduct(emptyProduct);
- setSubmitted(false);
- setProductDialog(true);
- };
-
- const hideDialog = () => {
- setSubmitted(false);
- setProductDialog(false);
- };
-
- const hideDeleteProductDialog = () => {
- setDeleteProductDialog(false);
- };
-
- const hideDeleteProductsDialog = () => {
- setDeleteProductsDialog(false);
- };
-
- const saveProduct = () => {
- setSubmitted(true);
-
- if (product.name.trim()) {
- let _products = [...products];
- let _product = { ...product };
- if (product.id) {
- const index = findIndexById(product.id);
-
- _products[index] = _product;
- toast.current.show({
- severity: 'success',
- summary: 'Successful',
- detail: 'Product Updated',
- life: 3000
- });
- } else {
- _product.id = createId();
- _product.code = createId();
- _product.image = 'product-placeholder.svg';
- _products.push(_product);
- toast.current.show({
- severity: 'success',
- summary: 'Successful',
- detail: 'Product Created',
- life: 3000
- });
- }
-
- setProducts(_products);
- setProductDialog(false);
- setProduct(emptyProduct);
- }
- };
-
- const editProduct = (product) => {
- setProduct({ ...product });
- setProductDialog(true);
- };
-
- const confirmDeleteProduct = (product) => {
- setProduct(product);
- setDeleteProductDialog(true);
- };
-
- const deleteProduct = () => {
- let _products = products.filter((val) => val.id !== product.id);
- setProducts(_products);
- setDeleteProductDialog(false);
- setProduct(emptyProduct);
- toast.current.show({
- severity: 'success',
- summary: 'Successful',
- detail: 'Product Deleted',
- life: 3000
- });
- };
-
- const findIndexById = (id) => {
- let index = -1;
- for (let i = 0; i < products.length; i++) {
- if (products[i].id === id) {
- index = i;
- break;
- }
- }
-
- return index;
- };
-
- const createId = () => {
- let id = '';
- let chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
- for (let i = 0; i < 5; i++) {
- id += chars.charAt(Math.floor(Math.random() * chars.length));
- }
- return id;
- };
-
- const exportCSV = () => {
- dt.current.exportCSV();
- };
-
- const confirmDeleteSelected = () => {
- setDeleteProductsDialog(true);
- };
-
- const deleteSelectedProducts = () => {
- let _products = products.filter((val) => !selectedProducts.includes(val));
- setProducts(_products);
- setDeleteProductsDialog(false);
- setSelectedProducts(null);
- toast.current.show({
- severity: 'success',
- summary: 'Successful',
- detail: 'Products Deleted',
- life: 3000
- });
- };
-
- const onCategoryChange = (e) => {
- let _product = { ...product };
- _product['category'] = e.value;
- setProduct(_product);
- };
-
- const onInputChange = (e, name) => {
- const val = (e.target && e.target.value) || '';
- let _product = { ...product };
- _product[`${name}`] = val;
-
- setProduct(_product);
- };
-
- const onInputNumberChange = (e, name) => {
- const val = e.value || 0;
- let _product = { ...product };
- _product[`${name}`] = val;
-
- setProduct(_product);
- };
-
- const leftToolbarTemplate = () => {
- return (
-
-
-
-
-
-
- );
- };
-
- const rightToolbarTemplate = () => {
- return (
-
-
-
-
- );
- };
-
- const codeBodyTemplate = (rowData) => {
- return (
- <>
- Code
- {rowData.code}
- >
- );
- };
-
- const nameBodyTemplate = (rowData) => {
- return (
- <>
- Name
- {rowData.name}
- >
- );
- };
-
- const imageBodyTemplate = (rowData) => {
- return (
- <>
- Image
-
- >
- );
- };
-
- const priceBodyTemplate = (rowData) => {
- return (
- <>
- Price
- {formatCurrency(rowData.price)}
- >
- );
- };
-
- const categoryBodyTemplate = (rowData) => {
- return (
- <>
- Category
- {rowData.category}
- >
- );
- };
-
- const ratingBodyTemplate = (rowData) => {
- return (
- <>
- Reviews
-
- >
- );
- };
-
- const statusBodyTemplate = (rowData) => {
- return (
- <>
- Status
- {rowData.inventoryStatus}
- >
- );
- };
-
- const actionBodyTemplate = (rowData) => {
- return (
- <>
-