diff --git a/docs/supabase.md b/docs/supabase.md index 8a99eb2..ee286d2 100644 --- a/docs/supabase.md +++ b/docs/supabase.md @@ -29,3 +29,12 @@ yarn generate:seed ``` Each time + +## Types + +You can generate the types from the database with the command : +``` +yarn types:generate +``` + +This script use Supabase CLI to generate the types file from your local database. You just need to go remove the last line inside the file `src/shared/types/supabase.ts` after running the command. diff --git a/package.json b/package.json index f10baea..47f6bfc 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "check": "biome check .", "preview": "vite preview", "seed:sync": "npx @snaplet/seed sync", - "seed:generate": "npx --yes tsx supabase/seeds/seed.ts > supabase/seeds/default.sql" + "seed:generate": "npx --yes tsx supabase/seeds/seed.ts > supabase/seeds/default.sql", + "types:generate": "supabase gen types typescript --local > src/shared/types/supabase.ts" }, "dependencies": { "@ant-design/icons": "5.x", @@ -43,7 +44,7 @@ "@vitejs/plugin-react": "^4.5.2", "bcryptjs": "^3.0.2", "postgres": "^3.4.7", - "supabase": "^2.31.8", + "supabase": "^2.34.3", "typescript": "~5.8.3", "vite": "^7.0.0" }, diff --git a/public/locales/en.json b/public/locales/en.json index cf66186..a78e17f 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -193,11 +193,13 @@ "serial_number": "Serial Number", "warranty_end_date": "Warranty End Date", "purchase_value": "Purchase Value", - "purchase_date": "Purchase Date" + "purchase_date": "Purchase Date", + "quantity": "Quantity" }, "validation": { "name_required": "Equipment name is required.", - "system_required": "System is required." + "system_required": "System is required.", + "quantity_required": "Quantity is required (minimum 1)." } } }, diff --git a/public/locales/fr.json b/public/locales/fr.json index 1ffe8a9..46ce36a 100644 --- a/public/locales/fr.json +++ b/public/locales/fr.json @@ -193,11 +193,13 @@ "serial_number": "Numéro de série", "warranty_end_date": "Fin de garantie", "purchase_value": "Valeur d'achat", - "purchase_date": "Date d'achat" + "purchase_date": "Date d'achat", + "quantity": "Quantité" }, "validation": { "name_required": "Le nom de l'équipement est requis.", - "system_required": "Le système est requis." + "system_required": "Le système est requis.", + "quantity_required": "La quantité est requise (minimum 1)." } } }, diff --git a/src/equipments/components/equipment-form.tsx b/src/equipments/components/equipment-form.tsx index bab1b44..2c6d283 100644 --- a/src/equipments/components/equipment-form.tsx +++ b/src/equipments/components/equipment-form.tsx @@ -80,6 +80,20 @@ const EquipmentForm: FC = ({ > + + + ); }; diff --git a/src/equipments/pages/list.tsx b/src/equipments/pages/list.tsx index a59289a..9e9c04d 100644 --- a/src/equipments/pages/list.tsx +++ b/src/equipments/pages/list.tsx @@ -76,6 +76,9 @@ const EquipmentList = () => { + {equipment.quantity > 1 + ? `${equipment.quantity} x ` + : null} {equipment.name} } diff --git a/src/equipments/pages/show.tsx b/src/equipments/pages/show.tsx index 3eda91f..148a18d 100644 --- a/src/equipments/pages/show.tsx +++ b/src/equipments/pages/show.tsx @@ -31,6 +31,9 @@ const ShowEquipment = () => { {translate('equipments.form.labels.name')}: + {equipment?.data.quantity > 1 + ? `${equipment?.data.quantity} x ` + : null} {equipment?.data.name} @@ -66,10 +69,23 @@ const ShowEquipment = () => { {translate('equipments.form.labels.purchase_value')}:{' '} - {equipment.data.purchase_value.toLocaleString(undefined, { - style: 'currency', - currency: 'EUR', - })} + {equipment?.data.quantity > 1 + ? `${equipment.data.quantity} x ${equipment.data.purchase_value.toLocaleString( + undefined, + { + style: 'currency', + currency: 'EUR', + }, + )} = ${( + equipment.data.quantity * equipment.data.purchase_value + ).toLocaleString(undefined, { + style: 'currency', + currency: 'EUR', + })}` + : equipment.data.purchase_value.toLocaleString(undefined, { + style: 'currency', + currency: 'EUR', + })} ) : null} {equipment?.data.purchase_date ? ( diff --git a/src/shared/types/supabase.ts b/src/shared/types/supabase.ts index 7469c75..6fe95be 100644 --- a/src/shared/types/supabase.ts +++ b/src/shared/types/supabase.ts @@ -7,10 +7,30 @@ export type Json = | Json[]; export type Database = { - // Allows to automatically instanciate createClient with right options - // instead of createClient(URL, KEY) - __InternalSupabase: { - PostgrestVersion: '12.2.12 (cd3cf9e)'; + graphql_public: { + Tables: { + [_ in never]: never; + }; + Views: { + [_ in never]: never; + }; + Functions: { + graphql: { + Args: { + operationName?: string; + query?: string; + variables?: Json; + extensions?: Json; + }; + Returns: Json; + }; + }; + Enums: { + [_ in never]: never; + }; + CompositeTypes: { + [_ in never]: never; + }; }; public: { Tables: { @@ -75,6 +95,7 @@ export type Database = { file_path: string; file_type: string | null; id: string; + type: string; uploaded_at: string; }; Insert: { @@ -84,6 +105,7 @@ export type Database = { file_path: string; file_type?: string | null; id?: string; + type?: string; uploaded_at?: string; }; Update: { @@ -93,11 +115,12 @@ export type Database = { file_path?: string; file_type?: string | null; id?: string; + type?: string; uploaded_at?: string; }; Relationships: [ { - foreignKeyName: 'attachments_equipment_id_fkey'; + foreignKeyName: 'equipment_attachments_equipment_id_fkey'; columns: ['equipment_id']; isOneToOne: false; referencedRelation: 'equipments'; @@ -116,6 +139,7 @@ export type Database = { name: string; purchase_date: string | null; purchase_value: number | null; + quantity: number; serial_number: string | null; system_key: string; warranty_end_date: string | null; @@ -130,6 +154,7 @@ export type Database = { name: string; purchase_date?: string | null; purchase_value?: number | null; + quantity?: number; serial_number?: string | null; system_key: string; warranty_end_date?: string | null; @@ -144,6 +169,7 @@ export type Database = { name?: string; purchase_date?: string | null; purchase_value?: number | null; + quantity?: number; serial_number?: string | null; system_key?: string; warranty_end_date?: string | null; @@ -158,6 +184,47 @@ export type Database = { }, ]; }; + intervention_attachments: { + Row: { + description: string | null; + file_name: string; + file_path: string; + file_type: string | null; + id: string; + intervention_id: string; + type: string; + uploaded_at: string; + }; + Insert: { + description?: string | null; + file_name: string; + file_path: string; + file_type?: string | null; + id?: string; + intervention_id: string; + type?: string; + uploaded_at?: string; + }; + Update: { + description?: string | null; + file_name?: string; + file_path?: string; + file_type?: string | null; + id?: string; + intervention_id?: string; + type?: string; + uploaded_at?: string; + }; + Relationships: [ + { + foreignKeyName: 'intervention_attachments_intervention_id_fkey'; + columns: ['intervention_id']; + isOneToOne: false; + referencedRelation: 'interventions'; + referencedColumns: ['id']; + }, + ]; + }; interventions: { Row: { boat_id: string; @@ -165,7 +232,10 @@ export type Database = { date: string; description: string | null; id: string; + labor_cost: number | null; + supply_cost: number | null; title: string; + total_cost: number | null; }; Insert: { boat_id: string; @@ -173,7 +243,10 @@ export type Database = { date: string; description?: string | null; id?: string; + labor_cost?: number | null; + supply_cost?: number | null; title: string; + total_cost?: number | null; }; Update: { boat_id?: string; @@ -181,7 +254,10 @@ export type Database = { date?: string; description?: string | null; id?: string; + labor_cost?: number | null; + supply_cost?: number | null; title?: string; + total_cost?: number | null; }; Relationships: [ { @@ -202,6 +278,10 @@ export type Database = { Args: { equipment_id: string }; Returns: boolean; }; + check_intervention_access: { + Args: { intervention_id: string }; + Returns: boolean; + }; has_boat_access: { Args: { boat: string }; Returns: boolean; @@ -337,6 +417,9 @@ export type CompositeTypes< : never; export const Constants = { + graphql_public: { + Enums: {}, + }, public: { Enums: { access_role: ['owner', 'operator', 'viewer'], diff --git a/supabase/migrations/20250813063811_add_quantity_to_equipment_table.sql b/supabase/migrations/20250813063811_add_quantity_to_equipment_table.sql new file mode 100644 index 0000000..02ebf97 --- /dev/null +++ b/supabase/migrations/20250813063811_add_quantity_to_equipment_table.sql @@ -0,0 +1,3 @@ +alter table "public"."equipments" add column "quantity" integer not null default 1; + + diff --git a/supabase/schemas/equipments.sql b/supabase/schemas/equipments.sql index 5f463ef..19ab157 100644 --- a/supabase/schemas/equipments.sql +++ b/supabase/schemas/equipments.sql @@ -8,6 +8,7 @@ create table public.equipments ( warranty_end_date timestamp with time zone, purchase_value real, purchase_date timestamp with time zone, + quantity integer not null default 1, created_at timestamp with time zone not null default now(), boat_id uuid not null, system_key text not null, diff --git a/yarn.lock b/yarn.lock index 1a217db..fa75c01 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6112,10 +6112,10 @@ sunflower-antd@1.0.0-beta.3: resolved "https://registry.yarnpkg.com/sunflower-antd/-/sunflower-antd-1.0.0-beta.3.tgz#5e72feefc8f592f4eda6cbc7bd7f9421463c6980" integrity sha512-SAdjHgNemTFNxUF/QJ2KdC0x6wWpY1EsMJMo+F5KIHCDRsUUahjAIldoK+ejH00rPgUoCOhAHQ/ob/J7eyZ5qg== -supabase@^2.31.8: - version "2.31.8" - resolved "https://registry.yarnpkg.com/supabase/-/supabase-2.31.8.tgz#a5058a42eaf5975014ef9b08ef75826f9cf9a4b7" - integrity sha512-AsALbB9qKqUhu5A8gZK5VMR2SPo2DPP7W544MBk7JKfLo3Pi8YoAxGxx5skarfeqDtHkzEREU/seFIaYP/bl3A== +supabase@^2.34.3: + version "2.34.3" + resolved "https://registry.yarnpkg.com/supabase/-/supabase-2.34.3.tgz#42c8f68d99f578fc16756e3229cf1794036eccc6" + integrity sha512-nMO7MFkw3ze/ScRt8S7AssNuBDbFeEsu2MTF2hol5T8HoAz5WgoLhhwCL5NUh8G0Jigpg88QIaDEPhHdNvv9TQ== dependencies: bin-links "^5.0.0" https-proxy-agent "^7.0.2"