From 4983a2432588eee9476800968f24eec05fd046b5 Mon Sep 17 00:00:00 2001 From: Hyko Date: Sun, 12 Apr 2026 13:18:21 -0400 Subject: [PATCH] refactor: remove clients, invoice, and nuage module integrations Strips out built-in clients, invoice, and nuage modules from core handlers, module initializers, and action registries. This cleans up hardcoded module dependencies, leaving only the posts module as a reference implementation for the modular architecture. --- src/core/api/handlers/users.js | 31 +- src/modules/clients/.env.example | 4 - src/modules/clients/INSTALL.md | 37 - src/modules/clients/admin/ClientCreatePage.js | 76 -- src/modules/clients/admin/ClientEditPage.js | 139 --- src/modules/clients/admin/ClientForm.js | 245 ----- src/modules/clients/admin/ClientsListPage.js | 277 ------ src/modules/clients/admin/index.js | 8 - src/modules/clients/api.js | 148 --- src/modules/clients/crud.js | 269 ------ src/modules/clients/db.js | 114 --- src/modules/clients/index.js | 28 - src/modules/clients/module.config.js | 50 - src/modules/init.js | 8 +- src/modules/invoice/.env.example | 19 - src/modules/invoice/GUIDE-client-dashboard.md | 142 --- src/modules/invoice/README.md | 262 ------ src/modules/invoice/actions.js | 338 ------- .../invoice/admin/InvoiceCreatePage.js | 613 ------------ src/modules/invoice/admin/InvoiceEditPage.js | 788 ---------------- src/modules/invoice/admin/InvoicesListPage.js | 354 ------- src/modules/invoice/admin/index.js | 7 - src/modules/invoice/api.js | 882 ------------------ .../categories/admin/CategoriesListPage.js | 266 ------ .../categories/admin/CategoryCreatePage.js | 231 ----- .../categories/admin/CategoryEditPage.js | 288 ------ src/modules/invoice/categories/admin/index.js | 9 - src/modules/invoice/categories/crud.js | 317 ------- src/modules/invoice/categories/db.js | 78 -- src/modules/invoice/cron.config.js | 44 - src/modules/invoice/crud.js | 721 -------------- .../dashboard/ClientInvoicesSection.js | 258 ----- .../invoice/dashboard/InvoicesWidget.js | 46 - .../invoice/dashboard/RevenueWidget.js | 77 -- src/modules/invoice/dashboard/index.js | 14 - src/modules/invoice/dashboard/statsActions.js | 142 --- src/modules/invoice/db.js | 235 ----- .../email/AdminOverdueNotificationEmail.jsx | 121 --- .../invoice/email/InvoiceOverdueEmail.jsx | 110 --- .../email/InvoicePaymentConfirmationEmail.jsx | 116 --- .../invoice/email/InvoiceReceiptEmail.jsx | 100 -- .../invoice/email/InvoiceReminderEmail.jsx | 106 --- src/modules/invoice/email/index.js | 9 - src/modules/invoice/index.js | 173 ---- src/modules/invoice/interest.js | 278 ------ .../invoice/items/admin/ItemCreatePage.js | 255 ----- .../invoice/items/admin/ItemEditPage.js | 312 ------- .../invoice/items/admin/ItemsListPage.js | 267 ------ src/modules/invoice/items/admin/index.js | 9 - src/modules/invoice/items/crud.js | 248 ----- src/modules/invoice/items/db.js | 85 -- src/modules/invoice/metadata.js | 233 ----- src/modules/invoice/module.config.js | 112 --- .../invoice/pages/InvoicePDFViewerPage.js | 106 --- .../invoice/pages/InvoicePublicPages.js | 273 ------ src/modules/invoice/pages/PaymentPage.js | 410 -------- .../invoice/pages/ReceiptPDFViewerPage.js | 106 --- src/modules/invoice/pages/ThemeToggle.js | 46 - src/modules/invoice/pages/index.js | 10 - .../invoice/pdf/InvoicePDFTemplate.jsx | 334 ------- .../invoice/pdf/ReceiptPDFTemplate.jsx | 392 -------- src/modules/invoice/pdf/generatePDF.js | 102 -- .../recurrences/admin/RecurrenceCreatePage.js | 691 -------------- .../recurrences/admin/RecurrenceEditPage.js | 765 --------------- .../recurrences/admin/RecurrencesListPage.js | 360 ------- .../invoice/recurrences/admin/index.js | 9 - src/modules/invoice/recurrences/crud.js | 369 -------- src/modules/invoice/recurrences/db.js | 98 -- src/modules/invoice/recurrences/processor.js | 119 --- src/modules/invoice/reminders.js | 510 ---------- .../admin/TransactionCreatePage.js | 371 -------- .../admin/TransactionsListPage.js | 228 ----- .../invoice/transactions/admin/index.js | 8 - src/modules/invoice/transactions/crud.js | 377 -------- src/modules/invoice/transactions/db.js | 82 -- src/modules/modules.actions.js | 48 +- src/modules/modules.metadata.js | 9 +- src/modules/modules.pages.js | 6 - src/modules/modules.registry.js | 3 - src/modules/nuage/.env.example | 4 - src/modules/nuage/GUIDE-client-dashboard.md | 192 ---- src/modules/nuage/README.md | 154 --- src/modules/nuage/actions.js | 274 ------ src/modules/nuage/admin/ExplorerPage.js | 796 ---------------- src/modules/nuage/admin/SharesPage.js | 254 ----- src/modules/nuage/admin/index.js | 5 - src/modules/nuage/api.js | 679 -------------- .../nuage/components/FileViewerModal.js | 85 -- .../nuage/components/NuageFileTable.js | 219 ----- src/modules/nuage/components/SharePanel.js | 776 --------------- src/modules/nuage/crud.js | 461 --------- .../nuage/dashboard/ClientNuageSection.js | 424 --------- src/modules/nuage/dashboard/index.js | 10 - src/modules/nuage/db.js | 109 --- src/modules/nuage/email/NuageShareEmail.jsx | 105 --- src/modules/nuage/email/index.js | 4 - src/modules/nuage/metadata.js | 69 -- src/modules/nuage/module.config.js | 44 - src/modules/nuage/pages/NuagePublicPages.js | 427 --------- src/modules/nuage/pages/index.js | 4 - 100 files changed, 4 insertions(+), 21022 deletions(-) delete mode 100644 src/modules/clients/.env.example delete mode 100644 src/modules/clients/INSTALL.md delete mode 100644 src/modules/clients/admin/ClientCreatePage.js delete mode 100644 src/modules/clients/admin/ClientEditPage.js delete mode 100644 src/modules/clients/admin/ClientForm.js delete mode 100644 src/modules/clients/admin/ClientsListPage.js delete mode 100644 src/modules/clients/admin/index.js delete mode 100644 src/modules/clients/api.js delete mode 100644 src/modules/clients/crud.js delete mode 100644 src/modules/clients/db.js delete mode 100644 src/modules/clients/index.js delete mode 100644 src/modules/clients/module.config.js delete mode 100644 src/modules/invoice/.env.example delete mode 100644 src/modules/invoice/GUIDE-client-dashboard.md delete mode 100644 src/modules/invoice/README.md delete mode 100644 src/modules/invoice/actions.js delete mode 100644 src/modules/invoice/admin/InvoiceCreatePage.js delete mode 100644 src/modules/invoice/admin/InvoiceEditPage.js delete mode 100644 src/modules/invoice/admin/InvoicesListPage.js delete mode 100644 src/modules/invoice/admin/index.js delete mode 100644 src/modules/invoice/api.js delete mode 100644 src/modules/invoice/categories/admin/CategoriesListPage.js delete mode 100644 src/modules/invoice/categories/admin/CategoryCreatePage.js delete mode 100644 src/modules/invoice/categories/admin/CategoryEditPage.js delete mode 100644 src/modules/invoice/categories/admin/index.js delete mode 100644 src/modules/invoice/categories/crud.js delete mode 100644 src/modules/invoice/categories/db.js delete mode 100644 src/modules/invoice/cron.config.js delete mode 100644 src/modules/invoice/crud.js delete mode 100644 src/modules/invoice/dashboard/ClientInvoicesSection.js delete mode 100644 src/modules/invoice/dashboard/InvoicesWidget.js delete mode 100644 src/modules/invoice/dashboard/RevenueWidget.js delete mode 100644 src/modules/invoice/dashboard/index.js delete mode 100644 src/modules/invoice/dashboard/statsActions.js delete mode 100644 src/modules/invoice/db.js delete mode 100644 src/modules/invoice/email/AdminOverdueNotificationEmail.jsx delete mode 100644 src/modules/invoice/email/InvoiceOverdueEmail.jsx delete mode 100644 src/modules/invoice/email/InvoicePaymentConfirmationEmail.jsx delete mode 100644 src/modules/invoice/email/InvoiceReceiptEmail.jsx delete mode 100644 src/modules/invoice/email/InvoiceReminderEmail.jsx delete mode 100644 src/modules/invoice/email/index.js delete mode 100644 src/modules/invoice/index.js delete mode 100644 src/modules/invoice/interest.js delete mode 100644 src/modules/invoice/items/admin/ItemCreatePage.js delete mode 100644 src/modules/invoice/items/admin/ItemEditPage.js delete mode 100644 src/modules/invoice/items/admin/ItemsListPage.js delete mode 100644 src/modules/invoice/items/admin/index.js delete mode 100644 src/modules/invoice/items/crud.js delete mode 100644 src/modules/invoice/items/db.js delete mode 100644 src/modules/invoice/metadata.js delete mode 100644 src/modules/invoice/module.config.js delete mode 100644 src/modules/invoice/pages/InvoicePDFViewerPage.js delete mode 100644 src/modules/invoice/pages/InvoicePublicPages.js delete mode 100644 src/modules/invoice/pages/PaymentPage.js delete mode 100644 src/modules/invoice/pages/ReceiptPDFViewerPage.js delete mode 100644 src/modules/invoice/pages/ThemeToggle.js delete mode 100644 src/modules/invoice/pages/index.js delete mode 100644 src/modules/invoice/pdf/InvoicePDFTemplate.jsx delete mode 100644 src/modules/invoice/pdf/ReceiptPDFTemplate.jsx delete mode 100644 src/modules/invoice/pdf/generatePDF.js delete mode 100644 src/modules/invoice/recurrences/admin/RecurrenceCreatePage.js delete mode 100644 src/modules/invoice/recurrences/admin/RecurrenceEditPage.js delete mode 100644 src/modules/invoice/recurrences/admin/RecurrencesListPage.js delete mode 100644 src/modules/invoice/recurrences/admin/index.js delete mode 100644 src/modules/invoice/recurrences/crud.js delete mode 100644 src/modules/invoice/recurrences/db.js delete mode 100644 src/modules/invoice/recurrences/processor.js delete mode 100644 src/modules/invoice/reminders.js delete mode 100644 src/modules/invoice/transactions/admin/TransactionCreatePage.js delete mode 100644 src/modules/invoice/transactions/admin/TransactionsListPage.js delete mode 100644 src/modules/invoice/transactions/admin/index.js delete mode 100644 src/modules/invoice/transactions/crud.js delete mode 100644 src/modules/invoice/transactions/db.js delete mode 100644 src/modules/nuage/.env.example delete mode 100644 src/modules/nuage/GUIDE-client-dashboard.md delete mode 100644 src/modules/nuage/README.md delete mode 100644 src/modules/nuage/actions.js delete mode 100644 src/modules/nuage/admin/ExplorerPage.js delete mode 100644 src/modules/nuage/admin/SharesPage.js delete mode 100644 src/modules/nuage/admin/index.js delete mode 100644 src/modules/nuage/api.js delete mode 100644 src/modules/nuage/components/FileViewerModal.js delete mode 100644 src/modules/nuage/components/NuageFileTable.js delete mode 100644 src/modules/nuage/components/SharePanel.js delete mode 100644 src/modules/nuage/crud.js delete mode 100644 src/modules/nuage/dashboard/ClientNuageSection.js delete mode 100644 src/modules/nuage/dashboard/index.js delete mode 100644 src/modules/nuage/db.js delete mode 100644 src/modules/nuage/email/NuageShareEmail.jsx delete mode 100644 src/modules/nuage/email/index.js delete mode 100644 src/modules/nuage/metadata.js delete mode 100644 src/modules/nuage/module.config.js delete mode 100644 src/modules/nuage/pages/NuagePublicPages.js delete mode 100644 src/modules/nuage/pages/index.js diff --git a/src/core/api/handlers/users.js b/src/core/api/handlers/users.js index d78ebbd..1045613 100644 --- a/src/core/api/handlers/users.js +++ b/src/core/api/handlers/users.js @@ -6,7 +6,7 @@ import { validateSession } from '../../../features/auth/lib/session.js'; import { cookies } from 'next/headers'; import { query, updateById } from '@hykocx/zen/database'; -import { getSessionCookieName, getModulesConfig } from '../../../shared/lib/appConfig.js'; +import { getSessionCookieName } from '../../../shared/lib/appConfig.js'; import { updateUser } from '../../../features/auth/lib/auth.js'; import { uploadImage, deleteFile, generateUniqueFilename, generateUserFilePath, FILE_TYPE_PRESETS, FILE_SIZE_LIMITS, validateUpload } from '@hykocx/zen/storage'; @@ -100,17 +100,6 @@ export async function handleGetUserById(request, userId) { const response = { user: result.rows[0] }; - // When clients module is active, include the client linked to this user (if any) - const modules = getModulesConfig(); - if (modules.clients) { - const clientResult = await query( - `SELECT id, client_number, company_name, first_name, last_name, email - FROM zen_clients WHERE user_id = $1 LIMIT 1`, - [userId] - ); - response.linkedClient = clientResult.rows[0] || null; - } - return response; } @@ -158,24 +147,6 @@ export async function handleUpdateUserById(request, userId) { return { success: false, error: 'Not Found', message: 'User not found' }; } - // When clients module is active, update client association (one user = one client) - const modules = getModulesConfig(); - if (modules.clients && body.client_id !== undefined) { - const clientId = body.client_id === null || body.client_id === '' ? null : parseInt(body.client_id, 10); - // Unlink all clients currently linked to this user - await query( - 'UPDATE zen_clients SET user_id = NULL, updated_at = CURRENT_TIMESTAMP WHERE user_id = $1', - [userId] - ); - // Link the selected client to this user if provided - if (clientId != null && !Number.isNaN(clientId)) { - await query( - 'UPDATE zen_clients SET user_id = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2', - [userId, clientId] - ); - } - } - const result = await query( 'SELECT id, email, name, role, image, email_verified, created_at FROM zen_auth_users WHERE id = $1', [userId] diff --git a/src/modules/clients/.env.example b/src/modules/clients/.env.example deleted file mode 100644 index a42bafa..0000000 --- a/src/modules/clients/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -################################# -# MODULE CLIENTS -ZEN_MODULE_CLIENTS=false -################################# \ No newline at end of file diff --git a/src/modules/clients/INSTALL.md b/src/modules/clients/INSTALL.md deleted file mode 100644 index d73b609..0000000 --- a/src/modules/clients/INSTALL.md +++ /dev/null @@ -1,37 +0,0 @@ -# Clients Module Installation - -## 1. Configure Environment Variables - -Copy all variables from [`.env.example`](.env.example) and add them to your `.env` file. - -## 2. Activate the Module - -In your `.env` file, set: - -```env -ZEN_MODULE_CLIENTS=true -``` - -## 3. Database Setup - -Run the database initialization to create the required tables: - -```bash -npx zen-db init -``` - -This will create the following table: -- `zen_clients` - Stores client information - -## 4. Features - -### Client Management -- Create, edit, and delete clients -- Store contact information (name, email, phone, address) -- Link clients to user accounts (optional) -- Unique client numbers (auto-generated) - -### Used By Other Modules -The clients module is a dependency for: -- **Quote Module**: Assign quotes to clients -- **Invoice Module**: Assign invoices to clients diff --git a/src/modules/clients/admin/ClientCreatePage.js b/src/modules/clients/admin/ClientCreatePage.js deleted file mode 100644 index 92b97c1..0000000 --- a/src/modules/clients/admin/ClientCreatePage.js +++ /dev/null @@ -1,76 +0,0 @@ -'use client'; - -import React, { useState } from 'react'; -import { useRouter } from 'next/navigation'; -import { Button } from '../../../shared/components'; -import ClientForm from './ClientForm.js'; -import { useToast } from '@hykocx/zen/toast'; - -/** - * Client Create Page Component - * Page for creating a new client - */ -const ClientCreatePage = ({ user }) => { - const router = useRouter(); - const toast = useToast(); - const [saving, setSaving] = useState(false); - - const handleSubmit = async (formData) => { - try { - setSaving(true); - - const response = await fetch('/zen/api/admin/clients', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - credentials: 'include', - body: JSON.stringify({ client: formData }) - }); - - const data = await response.json(); - - if (data.success) { - toast.success('Client créé avec succès'); - router.push('/admin/clients/list'); - } else { - toast.error(data.message || 'Échec de la création du client'); - } - } catch (error) { - console.error('Error creating client:', error); - toast.error('Échec de la création du client'); - } finally { - setSaving(false); - } - }; - - return ( -
- {/* Header */} -
-
-

Créer un client

-

Remplissez les détails pour créer un nouveau client

-
- -
- - {/* Form */} - router.push('/admin/clients/list')} - isEdit={false} - saving={saving} - users={[]} - /> -
- ); -}; - -export default ClientCreatePage; diff --git a/src/modules/clients/admin/ClientEditPage.js b/src/modules/clients/admin/ClientEditPage.js deleted file mode 100644 index 694b948..0000000 --- a/src/modules/clients/admin/ClientEditPage.js +++ /dev/null @@ -1,139 +0,0 @@ -'use client'; - -import React, { useState, useEffect } from 'react'; -import { useRouter } from 'next/navigation'; -import { Button, Card, Loading } from '../../../shared/components'; -import ClientForm from './ClientForm.js'; -import { useToast } from '@hykocx/zen/toast'; - -/** - * Client Edit Page Component - * Page for editing an existing client - */ -const ClientEditPage = ({ clientId, user }) => { - const router = useRouter(); - const toast = useToast(); - const [client, setClient] = useState(null); - const [loading, setLoading] = useState(true); - const [saving, setSaving] = useState(false); - - useEffect(() => { - loadClient(); - }, [clientId]); - - const loadClient = async () => { - try { - setLoading(true); - - const response = await fetch(`/zen/api/admin/clients?id=${clientId}`, { - credentials: 'include' - }); - const data = await response.json(); - - if (data.success) { - setClient(data.client); - } else { - toast.error(data.error || 'Échec du chargement du client'); - } - } catch (error) { - console.error('Error loading client:', error); - toast.error('Échec du chargement du client'); - } finally { - setLoading(false); - } - }; - - const handleSubmit = async (formData) => { - try { - setSaving(true); - - const response = await fetch(`/zen/api/admin/clients`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - credentials: 'include', - body: JSON.stringify({ id: clientId, client: formData }) - }); - - const data = await response.json(); - - if (data.success) { - toast.success('Client mis à jour avec succès'); - router.push('/admin/clients/list'); - } else { - toast.error(data.message || 'Échec de la mise à jour du client'); - } - } catch (error) { - console.error('Error updating client:', error); - toast.error('Échec de la mise à jour du client'); - } finally { - setSaving(false); - } - }; - - if (loading) { - return ( -
- -
- ); - } - - if (!client) { - return ( -
-
-
-

Modifier le client

-

Client non trouvé

-
- -
- -
-

Client non trouvé

-

Le client que vous recherchez n'existe pas ou a été supprimé.

-
-
-
- ); - } - - return ( -
- {/* Header */} -
-
-

Modifier le client

-

Client : {client.first_name} {client.last_name}

-
- -
- - {/* Form */} - router.push('/admin/clients/list')} - isEdit={true} - saving={saving} - users={[]} - /> -
- ); -}; - -export default ClientEditPage; diff --git a/src/modules/clients/admin/ClientForm.js b/src/modules/clients/admin/ClientForm.js deleted file mode 100644 index 1871f7e..0000000 --- a/src/modules/clients/admin/ClientForm.js +++ /dev/null @@ -1,245 +0,0 @@ -'use client'; - -import React, { useState } from 'react'; -import { Button, Card, Input, Select, Textarea } from '../../../shared/components'; - -/** - * Client Form Component - * Form for creating and editing clients - */ -const ClientForm = ({ - initialData = null, - users = [], - onSubmit, - onCancel, - isEdit = false, - saving = false -}) => { - const [formData, setFormData] = useState({ - user_id: initialData?.user_id || '', - company_name: initialData?.company_name || '', - first_name: initialData?.first_name || '', - last_name: initialData?.last_name || '', - email: initialData?.email || '', - phone: initialData?.phone || '', - address: initialData?.address || '', - city: initialData?.city || '', - province: initialData?.province || '', - postal_code: initialData?.postal_code || '', - country: initialData?.country || 'Canada', - notes: initialData?.notes || '', - }); - - const [errors, setErrors] = useState({}); - - const handleInputChange = (field, value) => { - setFormData(prev => ({ - ...prev, - [field]: value - })); - - if (errors[field]) { - setErrors(prev => ({ - ...prev, - [field]: null - })); - } - }; - - const validateForm = () => { - const newErrors = {}; - - if (!formData.first_name.trim()) { - newErrors.first_name = "Le prénom est requis"; - } - - if (!formData.last_name.trim()) { - newErrors.last_name = "Le nom de famille est requis"; - } - - if (!formData.email.trim()) { - newErrors.email = "L'email est requis"; - } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) { - newErrors.email = "Format d'email invalide"; - } - - setErrors(newErrors); - return Object.keys(newErrors).length === 0; - }; - - const handleSubmit = (e) => { - e.preventDefault(); - - if (!validateForm()) { - return; - } - - if (onSubmit) { - onSubmit(formData); - } - }; - - return ( -
- {/* Basic Information */} - -
-

Informations de base

- -
-
- handleInputChange('company_name', value)} - placeholder="Entrez le nom de la société..." - /> -
- - handleInputChange('first_name', value)} - placeholder="Entrez le prénom..." - error={errors.first_name} - /> - - handleInputChange('last_name', value)} - placeholder="Entrez le nom de famille..." - error={errors.last_name} - /> - - handleInputChange('email', value)} - placeholder="Entrez le courriel..." - error={errors.email} - /> - - handleInputChange('phone', value)} - placeholder="Entrez le numéro de téléphone..." - /> -
-
-
- - {/* Address */} - -
-

Adresse

- -
-
- handleInputChange('address', value)} - placeholder="Entrez l'adresse..." - /> -
- - handleInputChange('city', value)} - placeholder="Entrez la ville..." - /> - - handleInputChange('province', value)} - placeholder="Entrez la province ou l'état..." - /> - - handleInputChange('postal_code', value)} - placeholder="Entrez le code postal..." - /> - - handleInputChange('country', value)} - placeholder="Entrez le pays..." - /> -
-
-
- - {/* User Link */} - {users.length > 0 && ( - -
-

Lien compte utilisateur

-

- Vous pouvez associer ce client à un compte utilisateur sur la plateforme -

- -