From f2cc7a69b5771f44a1284a388464ccf8b7d83e5f Mon Sep 17 00:00:00 2001 From: Berkay Date: Wed, 30 Apr 2025 00:44:13 +0300 Subject: [PATCH] components stablized --- .../management-frontend/package-lock.json | 1 + .../management-frontend/setup-shadcn.sh | 1 + .../(DashboardLayout)/application/page.tsx | 2 +- .../app/(DashboardLayout)/dashboard/page.tsx | 2 +- .../src/app/api/applications/route.ts | 125 +++--- .../src/app/card-example/page.tsx | 289 +++++++------ .../src/app/example/page.tsx | 2 +- .../application/ActionButtonsComponent.tsx | 26 -- .../application/DataDisplayComponent.tsx | 85 ---- .../Pages/application/FormComponent.tsx | 359 ---------------- .../application/PaginationToolsComponent.tsx | 187 --------- .../Pages/application/SearchComponent.tsx | 156 ------- .../src/components/Pages/application/hooks.ts | 168 -------- .../components/Pages/application/language.ts | 42 -- .../src/components/Pages/application/page.tsx | 151 ------- .../components/Pages/application/schema.ts | 194 --------- .../src/components/Pages/application/types.ts | 63 --- .../src/components/Pages/index.ts | 15 - .../ActionButtonsDisplay/CreateButton.tsx | 25 ++ .../CustomButtonComponent.tsx | 31 ++ .../common/ActionButtonsDisplay/index.ts | 3 + .../common/ActionButtonsDisplay/types.ts | 17 + .../CardDisplay/CardDisplay.tsx | 0 .../CardDisplay/CardItem.tsx | 22 +- .../CardDisplay/CardSkeleton.tsx | 0 .../{commons => common}/CardDisplay/index.tsx | 0 .../{commons => common}/CardDisplay/schema.ts | 0 .../{commons => common}/CardDisplay/utils.ts | 0 .../common/FormDisplay/CreateComponent.tsx | 279 +++++++++++++ .../common/FormDisplay/FormDisplay.tsx | 117 ++++++ .../common/FormDisplay/UpdateComponent.tsx | 312 ++++++++++++++ .../common/FormDisplay/ViewComponent.tsx | 262 ++++++++++++ .../components/common/FormDisplay/index.ts | 5 + .../components/common/FormDisplay/types.ts | 37 ++ .../GridSelectionComponent.tsx | 42 ++ .../LanguageSelectionComponent.tsx | 37 ++ .../PaginationModifiers/PageNavigation.tsx | 116 ++++++ .../PaginationModifiers/PageSizeSelector.tsx | 52 +++ .../PaginationModifiers/PaginationStats.tsx | 36 ++ .../PaginationToolsComponent.tsx | 43 ++ .../common/PaginationModifiers/index.ts | 5 + .../common/PaginationModifiers/types.ts | 19 + .../QueryModifiers/SelectQueryModifier.tsx | 67 +++ .../QueryModifiers/TextQueryModifier.tsx | 80 ++++ .../QueryModifiers/TypeQueryModifier.tsx | 51 +++ .../components/common/QueryModifiers/index.ts | 4 + .../components/common/QueryModifiers/types.ts | 35 ++ .../src/components/common/ReadMe.md | 128 ++++++ .../Screenshot from 2025-04-29 19-36-45.png | Bin .../SortingComponent}/SortingComponent.tsx | 26 +- .../common/SortingComponent/index.ts | 2 + .../common/SortingComponent/types.ts | 13 + .../{commons => common}/hooks/useApiData.ts | 44 +- .../hooks/useDataFetching.ts | 0 .../src/components/common/index.ts | 26 ++ .../src/components/common/schemas.ts | 37 ++ .../commons/ActionButtonsComponent.tsx | 49 --- .../src/components/commons/FormDisplay.tsx | 39 -- .../commons/PaginationToolsComponent.tsx | 199 --------- .../components/commons/SearchComponent.tsx | 221 ---------- .../src/components/commons/index.ts | 9 - .../componentGroups/CardDisplay/ReadMe.md | 86 ---- .../src/components/menu/menu.tsx | 2 +- .../src/components/ui/alert.tsx | 66 +++ .../src/components/ui/badge.tsx | 46 +++ .../src/components/ui/textarea.tsx | 18 + .../Pages => eventRouters}/Readme.md | 0 .../appenderEvent/page.tsx | 2 +- .../appendersService/page.tsx | 2 +- .../src/eventRouters/application/language.ts | 174 ++++++++ .../src/eventRouters/application/page.tsx | 296 +++++++++++++ .../src/eventRouters/application/schema.ts | 391 ++++++++++++++++++ .../Pages => eventRouters}/dashboard/page.tsx | 2 +- .../Pages => eventRouters}/employee/page.tsx | 2 +- .../src/eventRouters/index.tsx | 9 + .../Pages => eventRouters}/ocuppant/page.tsx | 2 +- .../Pages => eventRouters}/pageRetriever.tsx | 2 +- .../unauthorizedpage.tsx | 0 .../validations/list/paginations.ts | 0 .../validations/menu/menu.tsx | 0 .../validations/translations/translation.tsx | 0 81 files changed, 3159 insertions(+), 2299 deletions(-) delete mode 100644 WebServices/management-frontend/src/components/Pages/application/ActionButtonsComponent.tsx delete mode 100644 WebServices/management-frontend/src/components/Pages/application/DataDisplayComponent.tsx delete mode 100644 WebServices/management-frontend/src/components/Pages/application/FormComponent.tsx delete mode 100644 WebServices/management-frontend/src/components/Pages/application/PaginationToolsComponent.tsx delete mode 100644 WebServices/management-frontend/src/components/Pages/application/SearchComponent.tsx delete mode 100644 WebServices/management-frontend/src/components/Pages/application/hooks.ts delete mode 100644 WebServices/management-frontend/src/components/Pages/application/language.ts delete mode 100644 WebServices/management-frontend/src/components/Pages/application/page.tsx delete mode 100644 WebServices/management-frontend/src/components/Pages/application/schema.ts delete mode 100644 WebServices/management-frontend/src/components/Pages/application/types.ts delete mode 100644 WebServices/management-frontend/src/components/Pages/index.ts create mode 100644 WebServices/management-frontend/src/components/common/ActionButtonsDisplay/CreateButton.tsx create mode 100644 WebServices/management-frontend/src/components/common/ActionButtonsDisplay/CustomButtonComponent.tsx create mode 100644 WebServices/management-frontend/src/components/common/ActionButtonsDisplay/index.ts create mode 100644 WebServices/management-frontend/src/components/common/ActionButtonsDisplay/types.ts rename WebServices/management-frontend/src/components/{commons => common}/CardDisplay/CardDisplay.tsx (100%) rename WebServices/management-frontend/src/components/{commons => common}/CardDisplay/CardItem.tsx (91%) rename WebServices/management-frontend/src/components/{commons => common}/CardDisplay/CardSkeleton.tsx (100%) rename WebServices/management-frontend/src/components/{commons => common}/CardDisplay/index.tsx (100%) rename WebServices/management-frontend/src/components/{commons => common}/CardDisplay/schema.ts (100%) rename WebServices/management-frontend/src/components/{commons => common}/CardDisplay/utils.ts (100%) create mode 100644 WebServices/management-frontend/src/components/common/FormDisplay/CreateComponent.tsx create mode 100644 WebServices/management-frontend/src/components/common/FormDisplay/FormDisplay.tsx create mode 100644 WebServices/management-frontend/src/components/common/FormDisplay/UpdateComponent.tsx create mode 100644 WebServices/management-frontend/src/components/common/FormDisplay/ViewComponent.tsx create mode 100644 WebServices/management-frontend/src/components/common/FormDisplay/index.ts create mode 100644 WebServices/management-frontend/src/components/common/FormDisplay/types.ts create mode 100644 WebServices/management-frontend/src/components/common/HeaderSelections/GridSelectionComponent.tsx create mode 100644 WebServices/management-frontend/src/components/common/HeaderSelections/LanguageSelectionComponent.tsx create mode 100644 WebServices/management-frontend/src/components/common/PaginationModifiers/PageNavigation.tsx create mode 100644 WebServices/management-frontend/src/components/common/PaginationModifiers/PageSizeSelector.tsx create mode 100644 WebServices/management-frontend/src/components/common/PaginationModifiers/PaginationStats.tsx create mode 100644 WebServices/management-frontend/src/components/common/PaginationModifiers/PaginationToolsComponent.tsx create mode 100644 WebServices/management-frontend/src/components/common/PaginationModifiers/index.ts create mode 100644 WebServices/management-frontend/src/components/common/PaginationModifiers/types.ts create mode 100644 WebServices/management-frontend/src/components/common/QueryModifiers/SelectQueryModifier.tsx create mode 100644 WebServices/management-frontend/src/components/common/QueryModifiers/TextQueryModifier.tsx create mode 100644 WebServices/management-frontend/src/components/common/QueryModifiers/TypeQueryModifier.tsx create mode 100644 WebServices/management-frontend/src/components/common/QueryModifiers/index.ts create mode 100644 WebServices/management-frontend/src/components/common/QueryModifiers/types.ts create mode 100644 WebServices/management-frontend/src/components/common/ReadMe.md rename WebServices/management-frontend/src/components/{componentGroups/CardDisplay => common}/Screenshot from 2025-04-29 19-36-45.png (100%) rename WebServices/management-frontend/src/components/{Pages/application => common/SortingComponent}/SortingComponent.tsx (68%) create mode 100644 WebServices/management-frontend/src/components/common/SortingComponent/index.ts create mode 100644 WebServices/management-frontend/src/components/common/SortingComponent/types.ts rename WebServices/management-frontend/src/components/{commons => common}/hooks/useApiData.ts (58%) rename WebServices/management-frontend/src/components/{commons => common}/hooks/useDataFetching.ts (100%) create mode 100644 WebServices/management-frontend/src/components/common/index.ts create mode 100644 WebServices/management-frontend/src/components/common/schemas.ts delete mode 100644 WebServices/management-frontend/src/components/commons/ActionButtonsComponent.tsx delete mode 100644 WebServices/management-frontend/src/components/commons/FormDisplay.tsx delete mode 100644 WebServices/management-frontend/src/components/commons/PaginationToolsComponent.tsx delete mode 100644 WebServices/management-frontend/src/components/commons/SearchComponent.tsx delete mode 100644 WebServices/management-frontend/src/components/commons/index.ts delete mode 100644 WebServices/management-frontend/src/components/componentGroups/CardDisplay/ReadMe.md create mode 100644 WebServices/management-frontend/src/components/ui/alert.tsx create mode 100644 WebServices/management-frontend/src/components/ui/badge.tsx create mode 100644 WebServices/management-frontend/src/components/ui/textarea.tsx rename WebServices/management-frontend/src/{components/Pages => eventRouters}/Readme.md (100%) rename WebServices/management-frontend/src/{components/Pages => eventRouters}/appenderEvent/page.tsx (66%) rename WebServices/management-frontend/src/{components/Pages => eventRouters}/appendersService/page.tsx (68%) create mode 100644 WebServices/management-frontend/src/eventRouters/application/language.ts create mode 100644 WebServices/management-frontend/src/eventRouters/application/page.tsx create mode 100644 WebServices/management-frontend/src/eventRouters/application/schema.ts rename WebServices/management-frontend/src/{components/Pages => eventRouters}/dashboard/page.tsx (65%) rename WebServices/management-frontend/src/{components/Pages => eventRouters}/employee/page.tsx (64%) create mode 100644 WebServices/management-frontend/src/eventRouters/index.tsx rename WebServices/management-frontend/src/{components/Pages => eventRouters}/ocuppant/page.tsx (64%) rename WebServices/management-frontend/src/{components/Pages => eventRouters}/pageRetriever.tsx (90%) rename WebServices/management-frontend/src/{components/Pages => eventRouters}/unauthorizedpage.tsx (100%) rename WebServices/management-frontend/src/{components => }/validations/list/paginations.ts (100%) rename WebServices/management-frontend/src/{components => }/validations/menu/menu.tsx (100%) rename WebServices/management-frontend/src/{components => }/validations/translations/translation.tsx (100%) diff --git a/WebServices/management-frontend/package-lock.json b/WebServices/management-frontend/package-lock.json index 5745e4f..fffab93 100644 --- a/WebServices/management-frontend/package-lock.json +++ b/WebServices/management-frontend/package-lock.json @@ -1022,6 +1022,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", "integrity": "sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, diff --git a/WebServices/management-frontend/setup-shadcn.sh b/WebServices/management-frontend/setup-shadcn.sh index 7897184..685b073 100755 --- a/WebServices/management-frontend/setup-shadcn.sh +++ b/WebServices/management-frontend/setup-shadcn.sh @@ -34,6 +34,7 @@ npx shadcn@latest add calendar -y npx shadcn@latest add date-picker -y npx shadcn@latest add skeleton -y npx shadcn@latest add table -y +npx shadcn@latest add textarea -y # Update any dependencies with legacy peer deps echo "🔄 Updating dependencies..." diff --git a/WebServices/management-frontend/src/app/(DashboardLayout)/application/page.tsx b/WebServices/management-frontend/src/app/(DashboardLayout)/application/page.tsx index 0bfb5f7..4482481 100644 --- a/WebServices/management-frontend/src/app/(DashboardLayout)/application/page.tsx +++ b/WebServices/management-frontend/src/app/(DashboardLayout)/application/page.tsx @@ -1,7 +1,7 @@ import React from "react"; import Header from "@/components/header/Header"; import ClientMenu from "@/components/menu/menu"; -import { retrievePageByUrl } from "@/components/Pages/pageRetriever"; +import { retrievePageByUrl } from "@/eventRouters/pageRetriever"; async function DashboardPage({ searchParams, diff --git a/WebServices/management-frontend/src/app/(DashboardLayout)/dashboard/page.tsx b/WebServices/management-frontend/src/app/(DashboardLayout)/dashboard/page.tsx index d4bc63f..d672533 100644 --- a/WebServices/management-frontend/src/app/(DashboardLayout)/dashboard/page.tsx +++ b/WebServices/management-frontend/src/app/(DashboardLayout)/dashboard/page.tsx @@ -1,7 +1,7 @@ import React from "react"; import Header from "@/components/header/Header"; import ClientMenu from "@/components/menu/menu"; -import { retrievePageByUrl } from "@/components/Pages/pageRetriever"; +import { retrievePageByUrl } from "@/eventRouters/pageRetriever"; async function PageDashboard({ searchParams, diff --git a/WebServices/management-frontend/src/app/api/applications/route.ts b/WebServices/management-frontend/src/app/api/applications/route.ts index 3a06901..e21a25f 100644 --- a/WebServices/management-frontend/src/app/api/applications/route.ts +++ b/WebServices/management-frontend/src/app/api/applications/route.ts @@ -1,81 +1,76 @@ import { NextRequest, NextResponse } from "next/server"; import { listApplications } from "@/apicalls/application/application"; -export async function GET(request: NextRequest) { +export async function POST(request: NextRequest) { try { - // Get query parameters - const searchParams = request.nextUrl.searchParams; + const requestBody = await request.json(); - // Extract pagination parameters - const page = parseInt(searchParams.get("page") || "1"); - const size = parseInt(searchParams.get("size") || "10"); - - // Extract sorting parameters - const orderField = searchParams.getAll("orderField") || ["name"]; - const orderType = searchParams.getAll("orderType") || ["asc"]; - - // Extract query filters - const query: Record = {}; - for (const [key, value] of searchParams.entries()) { - if (!["page", "size", "orderField", "orderType"].includes(key)) { - query[key] = value; - } - } + // Check if this is a list request or a create request + // If action is 'list' or if pagination parameters are present, treat as a list request + if (requestBody.action === 'list' || requestBody.page !== undefined) { + // Extract pagination parameters with defaults + const page = requestBody.page || 1; + const size = requestBody.size || 10; + + // Extract sorting parameters with defaults + const orderField = requestBody.orderField || ["name"]; + const orderType = requestBody.orderType || ["asc"]; + + // Extract query filters + const query = requestBody.query || {}; - // Call the actual API function - const response = await listApplications({ - page, - size, - orderField, - orderType, - query, - }); - - // Return the response - return NextResponse.json({ - data: response.data || [], - pagination: response.pagination || { + // Call the actual API function for listing + const response = await listApplications({ page, size, - totalCount: 0, - totalItems: 0, - totalPages: 0, - pageCount: 0, orderField, orderType, query, - next: false, - back: false, - }, - }); - } catch (error) { - console.error("API error:", error); - return NextResponse.json( - { error: "Internal Server Error" }, - { status: 500 } - ); - } -} + }); -export async function POST(request: NextRequest) { - try { - const body = await request.json(); - - // Here you would call your actual API function to create a new application - // For example: const result = await createApplication(body); - - // For now, we'll return a mock response - return NextResponse.json( - { - success: true, - data: { - id: Math.floor(Math.random() * 1000), - ...body, - createdAt: new Date().toISOString(), + // Return the list response + return NextResponse.json({ + data: response.data || [], + pagination: response.pagination || { + page, + size, + totalCount: 0, + totalItems: 0, + totalPages: 0, + pageCount: 0, + orderField, + orderType, + query, + next: false, + back: false, }, - }, - { status: 201 } - ); + }); + } + // If action is 'create' or no action is specified (assuming it's a create request) + else if (requestBody.action === 'create' || !requestBody.action) { + // Here you would call your actual API function to create a new application + // For example: const result = await createApplication(requestBody.data); + + // For now, we'll return a mock response + return NextResponse.json( + { + success: true, + data: { + id: Math.floor(Math.random() * 1000), + ...requestBody.data, + createdAt: new Date().toISOString(), + }, + }, + { status: 201 } + ); + } + // If the action is not recognized + else { + return NextResponse.json( + { error: "Invalid action specified" }, + { status: 400 } + ); + } } catch (error) { console.error("API error:", error); return NextResponse.json( diff --git a/WebServices/management-frontend/src/app/card-example/page.tsx b/WebServices/management-frontend/src/app/card-example/page.tsx index ed1988a..ccd2c57 100644 --- a/WebServices/management-frontend/src/app/card-example/page.tsx +++ b/WebServices/management-frontend/src/app/card-example/page.tsx @@ -1,11 +1,18 @@ "use client"; import React, { useState } from "react"; -import { CardDisplay } from "@/components/commons/CardDisplay"; -import { SearchComponent } from "@/components/commons/SearchComponent"; -import { ActionButtonsComponent } from "@/components/commons/ActionButtonsComponent"; -import { PaginationToolsComponent } from "@/components/commons/PaginationToolsComponent"; -import { useApiData } from "@/components/commons/hooks/useApiData"; +import { CardDisplay } from "@/components/common/CardDisplay"; +import { TextQueryModifier, SelectQueryModifier, TypeQueryModifier } from "@/components/common/QueryModifiers"; +import { Card, CardContent } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Filter } from "lucide-react"; +import { CreateButton } from "@/components/common/ActionButtonsDisplay/CreateButton"; +import { PaginationToolsComponent } from "@/components/common/PaginationModifiers/PaginationToolsComponent"; +import { useApiData } from "@/components/common/hooks/useApiData"; import { User, Building } from "lucide-react"; +import { GridSelectionComponent, GridSize } from "@/components/common/HeaderSelections/GridSelectionComponent"; +import { LanguageSelectionComponent, Language } from "@/components/common/HeaderSelections/LanguageSelectionComponent"; +import { FormDisplay } from "@/components/common/FormDisplay/FormDisplay"; +import type { FormMode } from "@/components/common/FormDisplay/types"; // Example translations const translations = { @@ -18,6 +25,7 @@ const translations = { typeSelection: "Type Selection", filterSelection: "Filter Selection", siteUrl: "Site URL", + resetAll: "Reset All", employee: "Employee", occupant: "Occupant", showing: "Showing", @@ -50,6 +58,7 @@ const translations = { typeSelection: "Tür Seçimi", filterSelection: "Filtre Seçimi", siteUrl: "Site URL", + resetAll: "Tümünü Sıfırla", employee: "Çalışan", occupant: "Sakin", showing: "Gösteriliyor", @@ -86,64 +95,27 @@ interface ApplicationData { application_type: string; } -// Form component for create/update -const FormComponent: React.FC<{ - initialData?: ApplicationData; - mode: "create" | "update"; - refetch?: () => void; - setMode: React.Dispatch>; - setSelectedItem: React.Dispatch>; - onCancel: () => void; - lang: string; -}> = ({ initialData, mode, refetch, setMode, onCancel, lang }) => { - // In a real application, you would implement form fields and submission logic here - return ( -
-

- {mode === "create" ? translations[lang as "en" | "tr"].create : translations[lang as "en" | "tr"].update} -

-

This is a placeholder for the {mode} form.

-
- - -
-
- ); -}; +// We're now using the modular FormDisplay component instead of an inline FormComponent export default function CardExamplePage() { - const [lang, setLang] = useState<"en" | "tr">("en"); - const [mode, setMode] = useState<"list" | "create" | "update">("list"); + const [lang, setLang] = useState("en"); + const [mode, setMode] = useState("list"); const [selectedItem, setSelectedItem] = useState(null); - const [gridCols, setGridCols] = useState<1 | 2 | 3 | 4 | 5 | 6>(3); - + const [gridCols, setGridCols] = useState(3); + // Use the API data hook - const { - data, - pagination, - loading, - error, - updatePagination, - refetch + const { + data, + pagination, + loading, + error, + updatePagination, + refetch } = useApiData("/api/data"); - + // Fields to display in the cards const showFields = ["application_code", "site_url", "application_type"]; - + // Search options const searchOptions = { typeOptions: [ @@ -169,7 +141,7 @@ export default function CardExamplePage() { { name: "status", label: translations[lang as "en" | "tr"].status, - type: "select", + type: "select" as const, options: [ { value: "active", label: "Active" }, { value: "inactive", label: "Inactive" }, @@ -179,11 +151,32 @@ export default function CardExamplePage() { ] }; - // Handle search - const handleSearch = (query: Record) => { + // Handle query changes + const handleQueryChange = (key: string, value: string | null) => { + const newQuery = { ...pagination.query }; + + if (value === null) { + // Remove the key if value is null + delete newQuery[key]; + } else if (value.trim() === "") { + // Remove the key if value is empty string + delete newQuery[key]; + } else { + // Add/update the key with the value + newQuery[key] = value; + } + updatePagination({ page: 1, // Reset to first page on new search - query: query, + query: newQuery, + }); + }; + + // Reset all filters + const handleResetAllFilters = () => { + updatePagination({ + page: 1, + query: {}, }); }; @@ -191,14 +184,13 @@ export default function CardExamplePage() { const handleCardClick = (item: ApplicationData) => { console.log("Card clicked:", item); }; - + const handleViewClick = (item: ApplicationData) => { - console.log("View clicked:", item); - // Example: Open a modal to view details + setSelectedItem(item); + setMode("view"); }; - + const handleUpdateClick = (item: ApplicationData) => { - console.log("Update clicked:", item); setSelectedItem(item); setMode("update"); }; @@ -206,66 +198,135 @@ export default function CardExamplePage() { // Handle create button click const handleCreateClick = () => { setSelectedItem(null); - setMode("create"); + setMode("create" as FormMode); }; // Handle cancel const handleCancel = () => { - setMode("list"); + setMode("list" as FormMode); setSelectedItem(null); }; - + return (

Card Example Page

-
- Grid Size: - -
+
- +
- + {mode === "list" ? ( <> - {/* Search Component */} - + {/* Search Filters */} + + +
+ {/* Type selection - vertical on the left */} +
+ +
- {/* Action Buttons Component */} - + {/* Filters on the right */} +
0 ? 'md:w-1/2 md:pl-4' : ''} flex flex-col space-y-4`}> +
+
+ + {translations[lang].filterSelection || "Filter Selection"} +
+ +
+ + {/* Search input */} + + + {/* Site URL dropdown */} + {searchOptions.urlOptions.length > 0 && ( + ({ value: url, label: url }))} + onQueryChange={handleQueryChange} + translations={translations} + lang={lang} + /> + )} + + {/* Additional fields */} + {searchOptions.additionalFields.map(field => ( + + ))} +
+
+
+
+ + {/* Create Button */} + + + + + + + {/* Pagination Tools Component */} + + + + + {/* Card Display Component */}
@@ -285,20 +346,9 @@ export default function CardExamplePage() { onUpdateClick={handleUpdateClick} />
- - {/* Pagination Tools Component */} -
- -
) : ( - initialData={selectedItem || undefined} mode={mode} refetch={refetch} @@ -306,6 +356,7 @@ export default function CardExamplePage() { setSelectedItem={setSelectedItem} onCancel={handleCancel} lang={lang} + translations={translations} /> )}
diff --git a/WebServices/management-frontend/src/app/example/page.tsx b/WebServices/management-frontend/src/app/example/page.tsx index 5e74981..7d3f808 100644 --- a/WebServices/management-frontend/src/app/example/page.tsx +++ b/WebServices/management-frontend/src/app/example/page.tsx @@ -1,6 +1,6 @@ "use client"; import React, { useState } from "react"; -import { CardDisplay, useApiData } from "@/components/commons"; +import { CardDisplay, useApiData } from "@/components/common"; import { User, Building } from "lucide-react"; // Example translations diff --git a/WebServices/management-frontend/src/components/Pages/application/ActionButtonsComponent.tsx b/WebServices/management-frontend/src/components/Pages/application/ActionButtonsComponent.tsx deleted file mode 100644 index 9cee034..0000000 --- a/WebServices/management-frontend/src/components/Pages/application/ActionButtonsComponent.tsx +++ /dev/null @@ -1,26 +0,0 @@ -"use client"; -import React from "react"; -import { Button } from "@/components/ui/button"; -import { Plus } from "lucide-react"; -import { LanguageTranslation } from "@/components/validations/translations/translation"; - -interface ActionButtonsComponentProps { - onCreateClick: () => void; - translations: Record; - lang: string; -} - -export const ActionButtonsComponent: React.FC = ({ - onCreateClick, - translations, - lang, -}) => { - return ( -
- -
- ); -}; diff --git a/WebServices/management-frontend/src/components/Pages/application/DataDisplayComponent.tsx b/WebServices/management-frontend/src/components/Pages/application/DataDisplayComponent.tsx deleted file mode 100644 index 7457bc5..0000000 --- a/WebServices/management-frontend/src/components/Pages/application/DataDisplayComponent.tsx +++ /dev/null @@ -1,85 +0,0 @@ -"use client"; -import React from "react"; -import { Card, CardContent } from "@/components/ui/card"; -import { LanguageTranslation } from "@/components/validations/translations/translation"; -import { ApplicationData } from "./types"; - -interface DataDisplayComponentProps { - data: ApplicationData[]; - loading: boolean; - error: Error | null; - onUpdateClick: (item: ApplicationData) => void; - translations: Record; - lang: string; -} - -export const DataDisplayComponent: React.FC = ({ - data, - loading, - error, - onUpdateClick, - translations, - lang, -}) => { - if (loading) { - return ( -
Loading applications...
- ); - } - - if (error) { - return ( -
- Error loading applications: {error.message} -
- ); - } - - if (data.length === 0) { - return
No applications found
; - } - - return ( -
- {data.map((app, index) => ( -
onUpdateClick(app)} - > - - -
{app.name}
-
-
- - {translations.code && - translations.code[lang as keyof LanguageTranslation]} - : - - {app.application_code} -
-
- - {translations.url && - translations.url[lang as keyof LanguageTranslation]} - : - - {app.site_url} -
-
- - {translations.type && - translations.type[lang as keyof LanguageTranslation]} - : - - {app.application_type} -
-
-
-
-
- ))} -
- ); -}; diff --git a/WebServices/management-frontend/src/components/Pages/application/FormComponent.tsx b/WebServices/management-frontend/src/components/Pages/application/FormComponent.tsx deleted file mode 100644 index dc71a54..0000000 --- a/WebServices/management-frontend/src/components/Pages/application/FormComponent.tsx +++ /dev/null @@ -1,359 +0,0 @@ -"use client"; -import React, { useState } from "react"; -import { Button } from "@/components/ui/button"; -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; -import { Input } from "@/components/ui/input"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; -import { Checkbox } from "@/components/ui/checkbox"; -import { Label } from "@/components/ui/label"; -import { Save, ArrowLeft } from "lucide-react"; -import { ApplicationData } from "./types"; -import { - ApplicationFormData, - ApplicationSchema, - CreateApplicationSchema, - UpdateApplicationSchema, - fieldDefinitions, - fieldsByMode, - FieldDefinition, -} from "./schema"; -import { getTranslation, LanguageKey } from "./language"; - -interface FormComponentProps { - initialData?: ApplicationData; - mode: "create" | "update"; - refetch: () => void; - setMode: (mode: "list" | "create" | "update") => void; - setSelectedItem: (item: ApplicationData | null) => void; - onCancel: () => void; - lang: string; -} - -interface ValidationErrors { - [key: string]: string[]; -} - -export const FormComponent: React.FC = ({ - initialData, - mode, - refetch, - setMode, - setSelectedItem, - onCancel, - lang, -}) => { - const t = getTranslation(lang as LanguageKey); - - // Convert initialData to ApplicationFormData with proper defaults - const getInitialFormData = (): ApplicationFormData => { - if (initialData) { - return { - ...initialData, - // Ensure required fields have defaults - active: initialData.active ?? true, - deleted: initialData.deleted ?? false, - }; - } else { - return { - name: "", - application_code: "", - site_url: "", - application_type: "", - application_for: "EMP", - description: "", - active: true, - deleted: false, - }; - } - }; - - const [formData, setFormData] = useState( - getInitialFormData() - ); - - const [validationErrors, setValidationErrors] = useState( - {} - ); - const [isSubmitting, setIsSubmitting] = useState(false); - - // Get field definitions for current mode - const currentFields = fieldsByMode[mode]; - const fieldDefs = fieldDefinitions.getDefinitionsByMode(mode); - - // Handle form input changes - const handleInputChange = (name: string, value: any) => { - setFormData({ - ...formData, - [name]: value, - }); - - // Clear validation error for this field when it changes - if (validationErrors[name]) { - const newErrors = { ...validationErrors }; - delete newErrors[name]; - setValidationErrors(newErrors); - } - }; - - // Validate form data based on mode - const validateForm = (): boolean => { - try { - if (mode === "create") { - CreateApplicationSchema.parse(formData); - } else if (mode === "update") { - UpdateApplicationSchema.parse(formData); - } else { - ApplicationSchema.parse(formData); - } - setValidationErrors({}); - return true; - } catch (error: any) { - if (error.errors) { - const errors: ValidationErrors = {}; - error.errors.forEach((err: any) => { - const field = err.path[0]; - if (!errors[field]) { - errors[field] = []; - } - errors[field].push(err.message); - }); - setValidationErrors(errors); - } - return false; - } - }; - - // Handle form submission - const handleSubmit = async () => { - if (isSubmitting) return; - - setIsSubmitting(true); - - // Validate form data - if (!validateForm()) { - setIsSubmitting(false); - return; - } - - try { - // TODO: Implement API call to save the data - // For now, just go back to list mode after a delay to simulate API call - await new Promise((resolve) => setTimeout(resolve, 500)); - refetch(); - setMode("list"); - } catch (error) { - console.error("Error saving application:", error); - } finally { - setIsSubmitting(false); - } - }; - - // Handle cancel button click - const handleCancel = () => { - setSelectedItem(null); - setMode("list"); - onCancel(); - }; - - const title = - mode === "create" - ? "Create Application" - : mode === "update" - ? "Update Application" - : "View Application"; - - // Render a field based on its definition - const renderField = (fieldName: string) => { - const fieldDef = fieldDefs[ - fieldName as keyof typeof fieldDefs - ] as FieldDefinition; - if (!fieldDef) return null; - - const hasError = !!validationErrors[fieldName]; - const errorMessages = validationErrors[fieldName] || []; - - return ( -
- - - {fieldDef.type === "text" && !fieldDef.readOnly && ( - <> - handleInputChange(fieldName, e.target.value)} - className={hasError ? "border-red-500" : ""} - /> - - )} - {fieldDef.type === "text" && fieldDef.readOnly && ( -

- {(formData[fieldName as keyof ApplicationFormData] as string) || ""} -

- )} - - {fieldDef.type === "textarea" && !fieldDef.readOnly && ( -