diff --git a/apps/backend/src/application/controllers/admin/csv-rates.controller.ts b/apps/backend/src/application/controllers/admin/csv-rates.controller.ts
index dc2c069..67bda15 100644
--- a/apps/backend/src/application/controllers/admin/csv-rates.controller.ts
+++ b/apps/backend/src/application/controllers/admin/csv-rates.controller.ts
@@ -348,4 +348,137 @@ export class CsvRatesAdminController {
this.logger.log(`Deleted CSV config for company: ${companyName}`);
}
+
+ /**
+ * List all CSV files (Frontend compatibility endpoint)
+ * Maps to GET /files for compatibility with frontend API client
+ */
+ @Get('files')
+ @HttpCode(HttpStatus.OK)
+ @ApiOperation({
+ summary: 'List all CSV files (ADMIN only)',
+ description: 'Returns list of all uploaded CSV files with metadata. Alias for /config endpoint.',
+ })
+ @ApiResponse({
+ status: HttpStatus.OK,
+ description: 'List of CSV files',
+ schema: {
+ type: 'object',
+ properties: {
+ files: {
+ type: 'array',
+ items: {
+ type: 'object',
+ properties: {
+ filename: { type: 'string', example: 'ssc-consolidation.csv' },
+ size: { type: 'number', example: 2048 },
+ uploadedAt: { type: 'string', format: 'date-time' },
+ rowCount: { type: 'number', example: 150 },
+ },
+ },
+ },
+ },
+ },
+ })
+ async listFiles(): Promise<{ files: any[] }> {
+ this.logger.log('Fetching all CSV files (frontend compatibility)');
+
+ const configs = await this.csvConfigRepository.findAll();
+ const fs = require('fs');
+ const path = require('path');
+
+ // Map configs to file info format expected by frontend
+ const files = configs.map((config) => {
+ const filePath = path.join(
+ process.cwd(),
+ 'apps/backend/src/infrastructure/storage/csv-storage/rates',
+ config.csvFilePath
+ );
+
+ let fileSize = 0;
+ try {
+ const stats = fs.statSync(filePath);
+ fileSize = stats.size;
+ } catch (error) {
+ this.logger.warn(`Could not get file size for ${config.csvFilePath}`);
+ }
+
+ return {
+ filename: config.csvFilePath,
+ size: fileSize,
+ uploadedAt: config.uploadedAt.toISOString(),
+ rowCount: config.rowCount,
+ };
+ });
+
+ return { files };
+ }
+
+ /**
+ * Delete CSV file (Frontend compatibility endpoint)
+ * Maps to DELETE /files/:filename
+ */
+ @Delete('files/:filename')
+ @HttpCode(HttpStatus.OK)
+ @ApiOperation({
+ summary: 'Delete CSV file by filename (ADMIN only)',
+ description: 'Deletes a CSV file and its configuration from the system.',
+ })
+ @ApiResponse({
+ status: HttpStatus.OK,
+ description: 'File deleted successfully',
+ schema: {
+ type: 'object',
+ properties: {
+ success: { type: 'boolean', example: true },
+ message: { type: 'string', example: 'File deleted successfully' },
+ },
+ },
+ })
+ @ApiResponse({
+ status: 404,
+ description: 'File not found',
+ })
+ async deleteFile(
+ @Param('filename') filename: string,
+ @CurrentUser() user: UserPayload
+ ): Promise<{ success: boolean; message: string }> {
+ this.logger.warn(`[Admin: ${user.email}] Deleting CSV file: ${filename}`);
+
+ // Find config by file path
+ const configs = await this.csvConfigRepository.findAll();
+ const config = configs.find((c) => c.csvFilePath === filename);
+
+ if (!config) {
+ throw new BadRequestException(`No configuration found for file: ${filename}`);
+ }
+
+ // Delete the file from filesystem
+ const fs = require('fs');
+ const path = require('path');
+ const filePath = path.join(
+ process.cwd(),
+ 'apps/backend/src/infrastructure/storage/csv-storage/rates',
+ filename
+ );
+
+ try {
+ if (fs.existsSync(filePath)) {
+ fs.unlinkSync(filePath);
+ this.logger.log(`Deleted file: ${filePath}`);
+ }
+ } catch (error: any) {
+ this.logger.error(`Failed to delete file ${filePath}: ${error.message}`);
+ }
+
+ // Delete the configuration
+ await this.csvConfigRepository.delete(config.companyName);
+
+ this.logger.log(`Deleted CSV config and file for: ${config.companyName}`);
+
+ return {
+ success: true,
+ message: `File ${filename} deleted successfully`,
+ };
+ }
}
diff --git a/apps/frontend/src/app/admin/csv-rates/page.tsx b/apps/frontend/app/dashboard/admin/csv-rates/page.tsx
similarity index 100%
rename from apps/frontend/src/app/admin/csv-rates/page.tsx
rename to apps/frontend/app/dashboard/admin/csv-rates/page.tsx
diff --git a/apps/frontend/app/dashboard/layout.tsx b/apps/frontend/app/dashboard/layout.tsx
index c1119e9..5c35561 100644
--- a/apps/frontend/app/dashboard/layout.tsx
+++ b/apps/frontend/app/dashboard/layout.tsx
@@ -25,6 +25,10 @@ export default function DashboardLayout({ children }: { children: React.ReactNod
{ name: 'My Profile', href: '/dashboard/profile', icon: '👤' },
{ name: 'Organization', href: '/dashboard/settings/organization', icon: '🏢' },
{ name: 'Users', href: '/dashboard/settings/users', icon: '👥' },
+ // ADMIN only navigation items
+ ...(user?.role === 'ADMIN' ? [
+ { name: 'CSV Rates', href: '/dashboard/admin/csv-rates', icon: '📄' },
+ ] : []),
];
const isActive = (href: string) => {
diff --git a/apps/frontend/src/components/admin/CsvUpload.tsx b/apps/frontend/src/components/admin/CsvUpload.tsx
index 662288d..6ef5c74 100644
--- a/apps/frontend/src/components/admin/CsvUpload.tsx
+++ b/apps/frontend/src/components/admin/CsvUpload.tsx
@@ -20,6 +20,7 @@ import { uploadCsvRates } from '@/lib/api/admin/csv-rates';
export function CsvUpload() {
const router = useRouter();
const [companyName, setCompanyName] = useState('');
+ const [companyEmail, setCompanyEmail] = useState('');
const [file, setFile] = useState
+ Email pour les demandes de réservation auprès de cette compagnie +
+