updated management service bind
This commit is contained in:
parent
c6b1a2b1e8
commit
ac8c3fe1c3
|
|
@ -47,7 +47,7 @@ export function CardDisplay<T>({
|
||||||
{(translations[lang] || {}).noData || "No data found"}
|
{(translations[lang] || {}).noData || "No data found"}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
data.map((item, index) => (
|
data.map((item: T, index: number) => (
|
||||||
<CardItem
|
<CardItem
|
||||||
key={index}
|
key={index}
|
||||||
item={item}
|
item={item}
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,12 @@ export function FormDisplay<T>({
|
||||||
}: FormDisplayProps<T>) {
|
}: FormDisplayProps<T>) {
|
||||||
const [enhancedFormProps, setEnhancedFormProps] = useState(formProps);
|
const [enhancedFormProps, setEnhancedFormProps] = useState(formProps);
|
||||||
|
|
||||||
// Update form props when language or mode changes
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const updateFormProps = async () => {
|
const updateFormProps = async () => {
|
||||||
try {
|
try {
|
||||||
// Check if schemaPath is provided in formProps
|
|
||||||
if (formProps.schemaPath) {
|
if (formProps.schemaPath) {
|
||||||
// Dynamic import of the schema module
|
|
||||||
const schemaModule = await import(formProps.schemaPath);
|
const schemaModule = await import(formProps.schemaPath);
|
||||||
|
|
||||||
// Get the appropriate field definitions based on mode
|
|
||||||
let fieldDefs;
|
let fieldDefs;
|
||||||
if (schemaModule.fieldDefinitions?.getDefinitionsByMode) {
|
if (schemaModule.fieldDefinitions?.getDefinitionsByMode) {
|
||||||
fieldDefs = schemaModule.fieldDefinitions.getDefinitionsByMode(mode);
|
fieldDefs = schemaModule.fieldDefinitions.getDefinitionsByMode(mode);
|
||||||
|
|
@ -40,13 +36,10 @@ export function FormDisplay<T>({
|
||||||
fieldDefs = schemaModule.viewFieldDefinitions;
|
fieldDefs = schemaModule.viewFieldDefinitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the appropriate validation schema based on mode and language
|
|
||||||
let validationSchema;
|
let validationSchema;
|
||||||
if (mode === "create" && schemaModule.getCreateApplicationSchema) {
|
if (mode === "create" && schemaModule.getCreateApplicationSchema) {
|
||||||
// Use language-aware schema factory function
|
|
||||||
validationSchema = schemaModule.getCreateApplicationSchema(lang as "en" | "tr");
|
validationSchema = schemaModule.getCreateApplicationSchema(lang as "en" | "tr");
|
||||||
} else if (mode === "update" && schemaModule.getUpdateApplicationSchema) {
|
} else if (mode === "update" && schemaModule.getUpdateApplicationSchema) {
|
||||||
// Use language-aware schema factory function
|
|
||||||
validationSchema = schemaModule.getUpdateApplicationSchema(lang as "en" | "tr");
|
validationSchema = schemaModule.getUpdateApplicationSchema(lang as "en" | "tr");
|
||||||
} else if (mode === "view" && schemaModule.ViewApplicationSchema) {
|
} else if (mode === "view" && schemaModule.ViewApplicationSchema) {
|
||||||
validationSchema = schemaModule.ViewApplicationSchema;
|
validationSchema = schemaModule.ViewApplicationSchema;
|
||||||
|
|
@ -54,23 +47,17 @@ export function FormDisplay<T>({
|
||||||
validationSchema = schemaModule.ApplicationSchema;
|
validationSchema = schemaModule.ApplicationSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the grouped field definitions structure if available
|
|
||||||
const groupedFieldDefs = schemaModule.baseFieldDefinitions || {};
|
const groupedFieldDefs = schemaModule.baseFieldDefinitions || {};
|
||||||
|
|
||||||
// Update form props with schema information and current language
|
|
||||||
setEnhancedFormProps({
|
setEnhancedFormProps({
|
||||||
...formProps,
|
...formProps,
|
||||||
fieldDefinitions: fieldDefs || {},
|
fieldDefinitions: fieldDefs || {},
|
||||||
validationSchema,
|
validationSchema,
|
||||||
fieldsByMode: schemaModule.fieldsByMode || {},
|
fieldsByMode: schemaModule.fieldsByMode || {},
|
||||||
groupedFieldDefinitions: groupedFieldDefs,
|
groupedFieldDefinitions: groupedFieldDefs,
|
||||||
// Add current language to force child components to recognize changes
|
|
||||||
currentLang: lang,
|
currentLang: lang,
|
||||||
// Add schema path for dynamic imports in child components
|
|
||||||
schemaPath: formProps.schemaPath
|
schemaPath: formProps.schemaPath
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// If no schema path, just update with current language
|
|
||||||
setEnhancedFormProps({
|
setEnhancedFormProps({
|
||||||
...formProps,
|
...formProps,
|
||||||
currentLang: lang
|
currentLang: lang
|
||||||
|
|
@ -78,7 +65,6 @@ export function FormDisplay<T>({
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error loading schema definitions:", error);
|
console.error("Error loading schema definitions:", error);
|
||||||
// Even on error, update the language
|
|
||||||
setEnhancedFormProps({
|
setEnhancedFormProps({
|
||||||
...formProps,
|
...formProps,
|
||||||
currentLang: lang
|
currentLang: lang
|
||||||
|
|
@ -87,17 +73,13 @@ export function FormDisplay<T>({
|
||||||
};
|
};
|
||||||
|
|
||||||
updateFormProps();
|
updateFormProps();
|
||||||
}, [formProps, mode, lang]); // Lang dependency ensures re-fetch when language changes
|
}, [formProps, mode, lang]);
|
||||||
|
|
||||||
// Debug the props received by FormDisplay
|
|
||||||
// FormDisplay component renders different form modes based on the mode prop
|
|
||||||
|
|
||||||
// Render the appropriate component based on the mode
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case "create":
|
case "create":
|
||||||
return (
|
return (
|
||||||
<CreateComponent<T>
|
<CreateComponent<T>
|
||||||
key={`create-${lang}`} // Add key with lang to force re-render on language change
|
key={`create-${lang}`}
|
||||||
refetch={refetch}
|
refetch={refetch}
|
||||||
setMode={setMode}
|
setMode={setMode}
|
||||||
setSelectedItem={setSelectedItem}
|
setSelectedItem={setSelectedItem}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
// Import field definitions type
|
|
||||||
export interface FieldDefinition {
|
export interface FieldDefinition {
|
||||||
type: string;
|
type: string;
|
||||||
group: string;
|
group: string;
|
||||||
|
|
@ -12,13 +11,13 @@ export interface FieldDefinition {
|
||||||
name?: string;
|
name?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the FormMode type to ensure consistency
|
|
||||||
export type FormMode = "list" | "create" | "update" | "view";
|
export type FormMode = "list" | "create" | "update" | "view";
|
||||||
|
export type FormModeView = "list" | "view";
|
||||||
|
|
||||||
export interface BaseFormProps<T> {
|
export interface BaseFormProps<T> {
|
||||||
initialData?: T;
|
initialData?: T;
|
||||||
refetch?: () => void;
|
refetch?: () => void;
|
||||||
setMode: React.Dispatch<React.SetStateAction<FormMode>>;
|
setMode: React.Dispatch<React.SetStateAction<FormMode | FormModeView>>;
|
||||||
setSelectedItem: React.Dispatch<React.SetStateAction<T | null>>;
|
setSelectedItem: React.Dispatch<React.SetStateAction<T | null>>;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
lang: string;
|
lang: string;
|
||||||
|
|
@ -30,19 +29,19 @@ export interface BaseFormProps<T> {
|
||||||
export interface CreateComponentProps<T> extends BaseFormProps<T> {}
|
export interface CreateComponentProps<T> extends BaseFormProps<T> {}
|
||||||
|
|
||||||
export interface UpdateComponentProps<T> extends BaseFormProps<T> {
|
export interface UpdateComponentProps<T> extends BaseFormProps<T> {
|
||||||
initialData: T; // Required for update
|
initialData: T;
|
||||||
apiUrl: string;
|
apiUrl: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ViewComponentProps<T> extends BaseFormProps<T> {
|
export interface ViewComponentProps<T> extends BaseFormProps<T> {
|
||||||
initialData: T; // Required for view
|
initialData: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormDisplayProps<T> {
|
export interface FormDisplayProps<T> {
|
||||||
mode: FormMode;
|
mode: FormMode | FormModeView;
|
||||||
initialData?: T;
|
initialData?: T;
|
||||||
refetch?: () => void;
|
refetch?: () => void;
|
||||||
setMode: React.Dispatch<React.SetStateAction<FormMode>>;
|
setMode: React.Dispatch<React.SetStateAction<FormModeView | FormMode>>;
|
||||||
setSelectedItem: React.Dispatch<React.SetStateAction<T | null>>;
|
setSelectedItem: React.Dispatch<React.SetStateAction<T | null>>;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
lang: string;
|
lang: string;
|
||||||
|
|
|
||||||
|
|
@ -10,26 +10,21 @@ export const TextQueryModifier: React.FC<TextQueryModifierProps> = ({
|
||||||
value,
|
value,
|
||||||
label,
|
label,
|
||||||
placeholder,
|
placeholder,
|
||||||
onQueryChange,
|
|
||||||
translations,
|
translations,
|
||||||
lang,
|
lang,
|
||||||
|
onQueryChange,
|
||||||
}) => {
|
}) => {
|
||||||
const t = translations[lang] || {};
|
const t = translations[lang] || {};
|
||||||
|
|
||||||
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const newValue = e.target.value;
|
const newValue = e.target.value; onQueryChange(fieldKey, newValue);
|
||||||
onQueryChange(fieldKey, newValue);
|
|
||||||
}, [fieldKey, onQueryChange]);
|
}, [fieldKey, onQueryChange]);
|
||||||
|
|
||||||
const handleClear = useCallback(() => {
|
const handleClear = useCallback(() => {
|
||||||
// Clear both the regular field and the ilike filter
|
onQueryChange(fieldKey, null); onQueryChange(`${fieldKey}__ilike`, null);
|
||||||
onQueryChange(fieldKey, null);
|
|
||||||
onQueryChange(`${fieldKey}__ilike`, null);
|
|
||||||
}, [fieldKey, onQueryChange]);
|
}, [fieldKey, onQueryChange]);
|
||||||
|
|
||||||
const handleKeyUp = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
|
const handleKeyUp = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
// Apply the search immediately on Enter
|
|
||||||
const formattedValue = value.trim() ? `%${value.trim()}%` : null;
|
const formattedValue = value.trim() ? `%${value.trim()}%` : null;
|
||||||
onQueryChange(`${fieldKey}__ilike`, formattedValue);
|
onQueryChange(`${fieldKey}__ilike`, formattedValue);
|
||||||
}
|
}
|
||||||
|
|
@ -42,9 +37,7 @@ export const TextQueryModifier: React.FC<TextQueryModifierProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<label className="block text-xs font-medium mb-1">
|
<label className="block text-xs font-medium mb-1">{label || t[fieldKey] || fieldKey}</label>
|
||||||
{label || t[fieldKey] || fieldKey}
|
|
||||||
</label>
|
|
||||||
<div className="relative w-full flex">
|
<div className="relative w-full flex">
|
||||||
<div className="relative w-full">
|
<div className="relative w-full">
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -61,19 +54,15 @@ export const TextQueryModifier: React.FC<TextQueryModifierProps> = ({
|
||||||
size="icon"
|
size="icon"
|
||||||
className="absolute right-1 top-1 h-8 w-8"
|
className="absolute right-1 top-1 h-8 w-8"
|
||||||
onClick={handleClear}
|
onClick={handleClear}
|
||||||
>
|
><X className="h-4 w-4" /></Button>
|
||||||
<X className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
variant="default"
|
variant="default"
|
||||||
size="sm"
|
size="lg"
|
||||||
className="ml-2"
|
className="ml-2"
|
||||||
onClick={handleSearch}
|
onClick={handleSearch}
|
||||||
>
|
><Search className="h-4 w-4" /></Button>
|
||||||
<Search className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,14 @@ export const dashboardLanguage = {
|
||||||
export const NavigationLanguage = {
|
export const NavigationLanguage = {
|
||||||
en: {
|
en: {
|
||||||
"/dashboard": "Dashboard",
|
"/dashboard": "Dashboard",
|
||||||
"/append/event": "Event Board",
|
"/append/application": "Application Bind Board",
|
||||||
"/append/service": "Service Board",
|
"/append/service": "Service Bind Board",
|
||||||
"/application": "Application Board",
|
"/application": "Application Board",
|
||||||
},
|
},
|
||||||
tr: {
|
tr: {
|
||||||
"/dashboard": "Kontrol Paneli",
|
"/dashboard": "Kontrol Paneli",
|
||||||
"/append/event": "Event Paneli",
|
"/append/application": "Uygulama Bağlama Paneli",
|
||||||
"/append/service": "Servis Paneli",
|
"/append/service": "Servis Bağlama Paneli",
|
||||||
"/application": "Uygulama Paneli",
|
"/application": "Uygulama Paneli",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ function SelectTrigger({
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
<SelectPrimitive.Icon asChild>
|
<SelectPrimitive.Icon asChild>
|
||||||
<ChevronDownIcon className="size-4 opacity-50" />
|
{/* <ChevronDownIcon className="size-4 opacity-50" /> */}
|
||||||
</SelectPrimitive.Icon>
|
</SelectPrimitive.Icon>
|
||||||
</SelectPrimitive.Trigger>
|
</SelectPrimitive.Trigger>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
import {
|
||||||
|
LanguageKey,
|
||||||
|
TranslationSet,
|
||||||
|
} from "@/validations/translations/translation";
|
||||||
|
import {
|
||||||
|
ApplicationBaseTranslationEn,
|
||||||
|
ApplicationBaseTranslationTr,
|
||||||
|
} from "./schemaList/schema";
|
||||||
|
|
||||||
|
// Define translations as a flat object structure to match the common components expectations
|
||||||
|
export const translations = {
|
||||||
|
en: {
|
||||||
|
...ApplicationBaseTranslationEn,
|
||||||
|
// Page title
|
||||||
|
mainTitle: "Services",
|
||||||
|
|
||||||
|
// Common actions
|
||||||
|
create: "Create",
|
||||||
|
update: "Update",
|
||||||
|
delete: "Delete",
|
||||||
|
view: "View",
|
||||||
|
save: "Save",
|
||||||
|
cancel: "Cancel",
|
||||||
|
|
||||||
|
// Search and filters
|
||||||
|
search: "Search",
|
||||||
|
typeSelection: "Type Selection",
|
||||||
|
filterSelection: "Filter Selection",
|
||||||
|
siteUrl: "Site URL",
|
||||||
|
resetAll: "Reset All",
|
||||||
|
|
||||||
|
// Type options
|
||||||
|
web: "Web",
|
||||||
|
mobile: "Mobile",
|
||||||
|
|
||||||
|
// Status options
|
||||||
|
status: "Status",
|
||||||
|
active: "Active",
|
||||||
|
inactive: "Inactive",
|
||||||
|
pending: "Pending",
|
||||||
|
|
||||||
|
// User types
|
||||||
|
employee: "Employee",
|
||||||
|
occupant: "Occupant",
|
||||||
|
|
||||||
|
// Pagination
|
||||||
|
showing: "Showing",
|
||||||
|
of: "of",
|
||||||
|
items: "items",
|
||||||
|
total: "Total",
|
||||||
|
filtered: "Filtered",
|
||||||
|
previous: "Previous",
|
||||||
|
next: "Next",
|
||||||
|
page: "Page",
|
||||||
|
itemsPerPage: "Items per page",
|
||||||
|
|
||||||
|
// Messages
|
||||||
|
noData: "No data found",
|
||||||
|
serviceSelectedTitle: "Selected Service",
|
||||||
|
serviceSelectedContent: "is selected to appende events",
|
||||||
|
|
||||||
|
// Other
|
||||||
|
applicationType: "Application Type",
|
||||||
|
availableApplications: "Available Applications",
|
||||||
|
code: "Code",
|
||||||
|
sortBy: "Sort by:",
|
||||||
|
formErrors: "Please correct the errors in the form",
|
||||||
|
|
||||||
|
// Form group titles
|
||||||
|
identificationInfo: "Identification Information",
|
||||||
|
applicationDetails: "Application Details",
|
||||||
|
statusInfo: "Status Information",
|
||||||
|
systemInfo: "System Information",
|
||||||
|
createDescription: "Create Application",
|
||||||
|
},
|
||||||
|
tr: {
|
||||||
|
// Page title
|
||||||
|
...ApplicationBaseTranslationTr,
|
||||||
|
mainTitle: "Servisler",
|
||||||
|
|
||||||
|
// Common actions
|
||||||
|
create: "Oluştur",
|
||||||
|
update: "Güncelle",
|
||||||
|
delete: "Sil",
|
||||||
|
view: "Görüntüle",
|
||||||
|
save: "Kaydet",
|
||||||
|
cancel: "İptal",
|
||||||
|
// Search and filters
|
||||||
|
search: "Ara",
|
||||||
|
typeSelection: "Tür Seçimi",
|
||||||
|
filterSelection: "Filtre Seçimi",
|
||||||
|
siteUrl: "Site URL",
|
||||||
|
resetAll: "Tümünü Sıfırla",
|
||||||
|
|
||||||
|
// Type options
|
||||||
|
web: "Web",
|
||||||
|
mobile: "Mobil",
|
||||||
|
|
||||||
|
// Status options
|
||||||
|
status: "Durum",
|
||||||
|
active: "Aktif",
|
||||||
|
inactive: "Pasif",
|
||||||
|
pending: "Beklemede",
|
||||||
|
|
||||||
|
// User types
|
||||||
|
employee: "Çalışan",
|
||||||
|
occupant: "Sakin",
|
||||||
|
|
||||||
|
// Pagination
|
||||||
|
showing: "Gösteriliyor",
|
||||||
|
of: "of",
|
||||||
|
items: "öğeler",
|
||||||
|
total: "Toplam",
|
||||||
|
filtered: "Filtreli",
|
||||||
|
previous: "Önceki",
|
||||||
|
next: "Sonraki",
|
||||||
|
page: "Sayfa",
|
||||||
|
itemsPerPage: "Sayfa başına öğeler",
|
||||||
|
|
||||||
|
// Messages
|
||||||
|
noData: "Veri bulunamadı",
|
||||||
|
serviceSelectedTitle: "Seçili Servis",
|
||||||
|
serviceSelectedContent: "is selected to appende events",
|
||||||
|
|
||||||
|
// Other
|
||||||
|
applicationType: "Uygulama Türü",
|
||||||
|
availableApplications: "Mevcut Uygulamalar",
|
||||||
|
code: "Kod",
|
||||||
|
sortBy: "Sırala:",
|
||||||
|
formErrors: "Lütfen formdaki hataları düzeltiniz",
|
||||||
|
|
||||||
|
// Form group titles
|
||||||
|
identificationInfo: "Kimlik Bilgileri",
|
||||||
|
applicationDetails: "Uygulama Detayları",
|
||||||
|
statusInfo: "Durum Bilgileri",
|
||||||
|
systemInfo: "Sistem Bilgileri",
|
||||||
|
createDescription: "Yeni bir uygulama oluşturun",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getTranslation(lang: LanguageKey): TranslationSet {
|
||||||
|
return translations[lang];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { translations } from './language';
|
||||||
|
import { Filter } from 'lucide-react';
|
||||||
|
|
||||||
|
import { Card, CardContent } from '@/components/ui/card';
|
||||||
|
import { TextQueryModifier } from '@/components/common/QueryModifiers/TextQueryModifier';
|
||||||
|
import { PaginationToolsComponent } from '@/components/common/PaginationModifiers/PaginationToolsComponent';
|
||||||
|
import { CardDisplay } from '@/components/common/CardDisplay/CardDisplay';
|
||||||
|
import { ListComponentProps } from './type';
|
||||||
|
|
||||||
|
const ListComponent: React.FC<ListComponentProps> = ({
|
||||||
|
lang,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
data,
|
||||||
|
pagination,
|
||||||
|
showFields,
|
||||||
|
gridCols,
|
||||||
|
handleQueryChange,
|
||||||
|
updatePagination,
|
||||||
|
handleCardClick,
|
||||||
|
handleViewClick,
|
||||||
|
}) => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* Search Filters */}
|
||||||
|
<Card>
|
||||||
|
<CardContent className="pt-6">
|
||||||
|
<div className="flex flex-col md:flex-row">
|
||||||
|
{/* Filters on the right */}
|
||||||
|
<div className={`w-full flex flex-col space-y-4`}>
|
||||||
|
<div className="font-medium text-sm mb-2 flex justify-between items-center">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Filter className="mr-2 h-4 w-4" />{translations[lang].filterSelection}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Search input */}
|
||||||
|
<TextQueryModifier
|
||||||
|
fieldKey="name"
|
||||||
|
value={pagination.query["name__ilike"] ? pagination.query["name__ilike"].replace(/%/g, "") : ""}
|
||||||
|
label={translations[lang].search}
|
||||||
|
onQueryChange={handleQueryChange}
|
||||||
|
translations={translations}
|
||||||
|
lang={lang}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* Pagination Tools Component */}
|
||||||
|
<Card className="my-4">
|
||||||
|
<CardContent className="pt-6">
|
||||||
|
<PaginationToolsComponent
|
||||||
|
pagination={pagination}
|
||||||
|
updatePagination={updatePagination}
|
||||||
|
loading={loading}
|
||||||
|
lang={lang}
|
||||||
|
translations={translations}
|
||||||
|
/>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* Card Display Component */}
|
||||||
|
<div className="mt-6">
|
||||||
|
<CardDisplay
|
||||||
|
showFields={showFields}
|
||||||
|
data={data}
|
||||||
|
lang={lang}
|
||||||
|
translations={translations}
|
||||||
|
error={error}
|
||||||
|
loading={loading}
|
||||||
|
titleField="name"
|
||||||
|
onCardClick={handleCardClick}
|
||||||
|
gridCols={gridCols}
|
||||||
|
showViewIcon={true}
|
||||||
|
showUpdateIcon={true}
|
||||||
|
onViewClick={handleViewClick}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ListComponent;
|
||||||
|
|
@ -1,9 +1,215 @@
|
||||||
"use client";
|
"use client";
|
||||||
import React from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { PageProps } from "@/validations/translations/translation";
|
import { z } from "zod";
|
||||||
|
|
||||||
const AppendersServicePage: React.FC<PageProps> = () => {
|
import * as schema from "./schemaList/schema";
|
||||||
return <div>AppendersServicePage</div>;
|
import ListComponent from "./listComponent";
|
||||||
|
import { translations } from "./language";
|
||||||
|
|
||||||
|
import { PageProps } from "@/validations/translations/translation";
|
||||||
|
import { FormModeView, FormMode } from "@/components/common/FormDisplay/types";
|
||||||
|
import { FormDisplay } from "@/components/common/FormDisplay/FormDisplay";
|
||||||
|
import { GridSelectionComponent, GridSize } from "@/components/common/HeaderSelections/GridSelectionComponent";
|
||||||
|
import { useApiData } from "@/components/common";
|
||||||
|
import { Language } from "@/components/common/schemas";
|
||||||
|
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
|
const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language }) => {
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: dataServices,
|
||||||
|
pagination: paginationServices,
|
||||||
|
loading: loadingServices,
|
||||||
|
error: errorServices,
|
||||||
|
updatePagination: updatePaginationServices,
|
||||||
|
refetch: refetchServices
|
||||||
|
} = useApiData<schema.ApplicationData>('/api/services');
|
||||||
|
const {
|
||||||
|
data: dataEvents,
|
||||||
|
pagination: paginationEvents,
|
||||||
|
loading: loadingEvents,
|
||||||
|
error: errorEvents,
|
||||||
|
updatePagination: updatePaginationEvents,
|
||||||
|
refetch: refetchEvents
|
||||||
|
} = useApiData<schema.ApplicationData>('/api/events');
|
||||||
|
const {
|
||||||
|
data: dataAppenders,
|
||||||
|
pagination: paginationAppenders,
|
||||||
|
loading: loadingAppenders,
|
||||||
|
error: errorAppenders,
|
||||||
|
updatePagination: updatePaginationAppenders,
|
||||||
|
refetch: refetchAppenders
|
||||||
|
} = useApiData<schema.ApplicationData>('/api/appenders');
|
||||||
|
|
||||||
|
const [mode, setMode] = useState<FormModeView | FormMode>("list");
|
||||||
|
const [selectedItemServices, setSelectedItemServices] = useState<schema.ApplicationData | null>(null);
|
||||||
|
const [selectedItemEvents, setSelectedItemEvents] = useState<schema.ApplicationData | null>(null);
|
||||||
|
const [selectedItemAppenders, setSelectedItemAppenders] = useState<schema.ApplicationData | null>(null);
|
||||||
|
const [gridCols, setGridCols] = useState<GridSize>(3);
|
||||||
|
|
||||||
|
const [fieldDefinitionsServices, setFieldDefinitionsServices] = useState<schema.FieldDefinitionsType | null>(null);
|
||||||
|
const [validationSchemaServices, setValidationSchemaServices] = useState<z.ZodSchema | null>(null);
|
||||||
|
const [fieldDefinitionsEvents, setFieldDefinitionsEvents] = useState<schema.FieldDefinitionsType | null>(null);
|
||||||
|
const [validationSchemaEvents, setValidationSchemaEvents] = useState<z.ZodSchema | null>(null);
|
||||||
|
const [fieldDefinitionsAppenders, setFieldDefinitionsAppenders] = useState<schema.FieldDefinitionsType | null>(null);
|
||||||
|
const [validationSchemaAppenders, setValidationSchemaAppenders] = useState<z.ZodSchema | null>(null);
|
||||||
|
|
||||||
|
const showFieldsServices = ["service_name", "service_code", "related_responsibility"];
|
||||||
|
const showFieldsEvents = ["description", "marketing_layer", "cost"];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setFieldDefinitionsServices(schema.viewFieldDefinitions); setValidationSchemaServices(schema.UpdateApplicationSchema);
|
||||||
|
setFieldDefinitionsEvents(schema.viewFieldDefinitions); setValidationSchemaEvents(schema.UpdateApplicationSchema);
|
||||||
|
setFieldDefinitionsAppenders(schema.viewFieldDefinitions); setValidationSchemaAppenders(schema.UpdateApplicationSchema);
|
||||||
|
}, [lang]);
|
||||||
|
|
||||||
|
const handleQueryChange = (key: string, value: string | null) => {
|
||||||
|
const newQuery = { ...paginationServices.query };
|
||||||
|
if (value === null) { delete newQuery[key]; } else if (value.trim() === "") { delete newQuery[key]; } else { newQuery[key] = value; }
|
||||||
|
updatePaginationServices({ page: 1, query: newQuery });
|
||||||
|
};
|
||||||
|
const handleServicesCardClick = (item: schema.ApplicationData) => { console.log("Services Card clicked:", item) };
|
||||||
|
const handleServicesViewClick = (item: schema.ApplicationData) => { setSelectedItemServices(item); setMode("view"); };
|
||||||
|
|
||||||
|
const handleEventsCardClick = (item: schema.ApplicationData) => { console.log("Events Card clicked:", item) };
|
||||||
|
const handleEventsViewClick = (item: schema.ApplicationData) => { setSelectedItemEvents(item); setMode("view"); };
|
||||||
|
|
||||||
|
const handleAppendersCardClick = (item: schema.ApplicationData) => { console.log("Appenders Card clicked:", item) };
|
||||||
|
const handleAppendersViewClick = (item: schema.ApplicationData) => { setSelectedItemAppenders(item); setMode("view"); };
|
||||||
|
|
||||||
|
const cancelAllSelections = () => {
|
||||||
|
setMode("list");
|
||||||
|
setSelectedItemServices(null);
|
||||||
|
setSelectedItemEvents(null);
|
||||||
|
setSelectedItemAppenders(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const seriveListProps = {
|
||||||
|
lang,
|
||||||
|
loading: loadingServices,
|
||||||
|
error: errorServices,
|
||||||
|
data: dataServices,
|
||||||
|
pagination: paginationServices,
|
||||||
|
showFields: showFieldsServices,
|
||||||
|
gridCols: gridCols,
|
||||||
|
handleQueryChange: handleQueryChange,
|
||||||
|
updatePagination: updatePaginationServices,
|
||||||
|
handleCardClick: handleServicesCardClick,
|
||||||
|
handleViewClick: handleServicesViewClick
|
||||||
|
};
|
||||||
|
|
||||||
|
const eventsListProps = {
|
||||||
|
lang,
|
||||||
|
loading: loadingEvents,
|
||||||
|
error: errorEvents,
|
||||||
|
data: dataEvents,
|
||||||
|
pagination: paginationEvents,
|
||||||
|
showFields: showFieldsEvents,
|
||||||
|
gridCols: gridCols,
|
||||||
|
handleQueryChange: handleQueryChange,
|
||||||
|
updatePagination: updatePaginationEvents,
|
||||||
|
handleCardClick: handleEventsCardClick,
|
||||||
|
handleViewClick: handleEventsViewClick
|
||||||
|
};
|
||||||
|
|
||||||
|
const appendersListProps = {
|
||||||
|
lang,
|
||||||
|
loading: loadingAppenders,
|
||||||
|
error: errorAppenders,
|
||||||
|
data: dataAppenders,
|
||||||
|
pagination: paginationAppenders,
|
||||||
|
showFields: showFieldsEvents,
|
||||||
|
gridCols: gridCols,
|
||||||
|
handleQueryChange: handleQueryChange,
|
||||||
|
updatePagination: updatePaginationAppenders,
|
||||||
|
handleCardClick: handleAppendersCardClick,
|
||||||
|
handleViewClick: handleAppendersViewClick
|
||||||
|
};
|
||||||
|
|
||||||
|
const serviceFormProps = {
|
||||||
|
initialData: selectedItemServices || undefined,
|
||||||
|
mode: mode,
|
||||||
|
refetch: refetchServices,
|
||||||
|
setMode: setMode,
|
||||||
|
setSelectedItem: setSelectedItemServices,
|
||||||
|
onCancel: cancelAllSelections,
|
||||||
|
lang: lang,
|
||||||
|
translations: translations,
|
||||||
|
apiUrl: '/api/services',
|
||||||
|
formProps: {
|
||||||
|
fieldDefinitions: fieldDefinitionsServices,
|
||||||
|
validationSchema: validationSchemaServices,
|
||||||
|
fieldsByMode: schema.fieldsByMode
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const eventsFormProps = {
|
||||||
|
initialData: selectedItemEvents || undefined,
|
||||||
|
mode: mode,
|
||||||
|
refetch: refetchEvents,
|
||||||
|
setMode: setMode,
|
||||||
|
setSelectedItem: setSelectedItemEvents,
|
||||||
|
onCancel: cancelAllSelections,
|
||||||
|
lang: lang,
|
||||||
|
translations: translations,
|
||||||
|
apiUrl: '/api/events',
|
||||||
|
formProps: {
|
||||||
|
fieldDefinitions: fieldDefinitionsEvents,
|
||||||
|
validationSchema: validationSchemaEvents,
|
||||||
|
fieldsByMode: schema.fieldsByMode
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const appendersFormProps = {
|
||||||
|
initialData: selectedItemAppenders || undefined,
|
||||||
|
mode: mode,
|
||||||
|
refetch: refetchAppenders,
|
||||||
|
setMode: setMode,
|
||||||
|
setSelectedItem: setSelectedItemAppenders,
|
||||||
|
onCancel: cancelAllSelections,
|
||||||
|
lang: lang,
|
||||||
|
translations: translations,
|
||||||
|
apiUrl: '/api/appenders',
|
||||||
|
formProps: {
|
||||||
|
fieldDefinitions: fieldDefinitionsAppenders,
|
||||||
|
validationSchema: validationSchemaAppenders,
|
||||||
|
fieldsByMode: schema.fieldsByMode
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container mx-auto p-4 overflow-y-auto" >
|
||||||
|
<div className="mb-4 flex justify-between items-center">
|
||||||
|
<h1 className="text-2xl font-bold">{translations[lang].mainTitle}</h1>
|
||||||
|
<div className="flex space-x-4"><GridSelectionComponent gridCols={gridCols} setGridCols={setGridCols} /></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{mode === "list" ? (
|
||||||
|
<div className="flex flex-col space-y-4">
|
||||||
|
{!selectedItemServices ? <div className="w-full h-1/2"><ListComponent {...seriveListProps} /></div> :
|
||||||
|
<div className="w-full h-1/2">
|
||||||
|
<Button onClick={cancelAllSelections}>{translations[lang].cancel}</Button>
|
||||||
|
<Card className="my-5">
|
||||||
|
<CardHeader>{translations[lang].serviceSelectedTitle}</CardHeader>
|
||||||
|
<CardContent>{selectedItemServices?.name}{" "}{translations[lang].serviceSelectedContent}</CardContent>
|
||||||
|
</Card>
|
||||||
|
<div className="flex flex-row space-x-4">
|
||||||
|
<div className="flex-1"><ListComponent {...eventsListProps} /></div>
|
||||||
|
<div className="flex-1"><ListComponent {...appendersListProps} /></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-col space-y-4">
|
||||||
|
{selectedItemServices && <FormDisplay<schema.ApplicationData> {...serviceFormProps} />}
|
||||||
|
{selectedItemEvents && <FormDisplay<schema.ApplicationData> {...eventsFormProps} />}
|
||||||
|
{selectedItemAppenders && <FormDisplay<schema.ApplicationData> {...appendersFormProps} />}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AppendersServicePage;
|
export default AppendersServicePage;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,476 @@
|
||||||
|
import { z } from "zod";
|
||||||
|
import { flattenFieldDefinitions } from "@/eventRouters/schemas/zodSchemas";
|
||||||
|
|
||||||
|
export interface ApplicationData {
|
||||||
|
id?: number;
|
||||||
|
name: string;
|
||||||
|
application_code: string;
|
||||||
|
site_url: string;
|
||||||
|
application_type: string;
|
||||||
|
application_for?: string;
|
||||||
|
description?: string;
|
||||||
|
active: boolean;
|
||||||
|
deleted?: boolean;
|
||||||
|
created_at?: string;
|
||||||
|
updated_at?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validation error messages by language
|
||||||
|
const errorMessages = {
|
||||||
|
en: {
|
||||||
|
nameRequired: "Name is required",
|
||||||
|
applicationCodeRequired: "Application code is required",
|
||||||
|
siteUrlRequired: "Site URL is required",
|
||||||
|
applicationTypeRequired: "Application type is required",
|
||||||
|
},
|
||||||
|
tr: {
|
||||||
|
nameRequired: "İsim gereklidir",
|
||||||
|
applicationCodeRequired: "Uygulama kodu gereklidir",
|
||||||
|
siteUrlRequired: "Site URL'si gereklidir",
|
||||||
|
applicationTypeRequired: "Uygulama tipi gereklidir",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to get schema with language-specific validation messages
|
||||||
|
const getApplicationBaseSchema = (lang: "en" | "tr" = "en") =>
|
||||||
|
z.object({
|
||||||
|
// Identification fields
|
||||||
|
uu_id: z.string().optional(),
|
||||||
|
name: z.string().min(1, errorMessages[lang].nameRequired),
|
||||||
|
application_code: z
|
||||||
|
.string()
|
||||||
|
.min(1, errorMessages[lang].applicationCodeRequired),
|
||||||
|
|
||||||
|
// Application details
|
||||||
|
site_url: z.string().min(1, errorMessages[lang].siteUrlRequired),
|
||||||
|
application_type: z
|
||||||
|
.string()
|
||||||
|
.min(1, errorMessages[lang].applicationTypeRequired),
|
||||||
|
application_for: z.string().optional(),
|
||||||
|
description: z.string().optional(),
|
||||||
|
|
||||||
|
// Status fields
|
||||||
|
active: z.boolean().default(true),
|
||||||
|
deleted: z.boolean().default(false),
|
||||||
|
|
||||||
|
// System fields
|
||||||
|
created_at: z.string().optional(),
|
||||||
|
updated_at: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// For backward compatibility
|
||||||
|
const ApplicationBaseSchema = getApplicationBaseSchema("en");
|
||||||
|
|
||||||
|
export const ApplicationBaseTranslationTr = {
|
||||||
|
uu_id: "UUID",
|
||||||
|
name: "Name",
|
||||||
|
application_code: "Application Code",
|
||||||
|
site_url: "Site URL",
|
||||||
|
application_type: "Application Type",
|
||||||
|
application_for: "Application For",
|
||||||
|
description: "Description",
|
||||||
|
active: "Active",
|
||||||
|
deleted: "Deleted",
|
||||||
|
created_at: "Created At",
|
||||||
|
updated_at: "Updated At",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ApplicationBaseTranslationEn = {
|
||||||
|
uu_id: "UUID",
|
||||||
|
name: "Name",
|
||||||
|
application_code: "Application Code",
|
||||||
|
site_url: "Site URL",
|
||||||
|
application_type: "Application Type",
|
||||||
|
application_for: "Application For",
|
||||||
|
description: "Description",
|
||||||
|
active: "Active",
|
||||||
|
deleted: "Deleted",
|
||||||
|
created_at: "Created At",
|
||||||
|
updated_at: "Updated At",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create schema for creating new applications with language support
|
||||||
|
const getCreateApplicationSchema = (lang: "en" | "tr" = "en") =>
|
||||||
|
getApplicationBaseSchema(lang).omit({
|
||||||
|
uu_id: true,
|
||||||
|
created_at: true,
|
||||||
|
updated_at: true,
|
||||||
|
deleted: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update schema for updating existing applications with language support
|
||||||
|
const getUpdateApplicationSchema = (lang: "en" | "tr" = "en") =>
|
||||||
|
getApplicationBaseSchema(lang)
|
||||||
|
.omit({
|
||||||
|
created_at: true,
|
||||||
|
updated_at: true,
|
||||||
|
deleted: true,
|
||||||
|
})
|
||||||
|
.required({
|
||||||
|
uu_id: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// For backward compatibility
|
||||||
|
const CreateApplicationSchema = getCreateApplicationSchema("en");
|
||||||
|
const UpdateApplicationSchema = getUpdateApplicationSchema("en");
|
||||||
|
|
||||||
|
// Schema for viewing an application (all fields)
|
||||||
|
const ViewApplicationSchema = ApplicationBaseSchema;
|
||||||
|
|
||||||
|
// Default schema (used for validation)
|
||||||
|
const ApplicationSchema = ApplicationBaseSchema;
|
||||||
|
|
||||||
|
// Export all schemas and schema generators
|
||||||
|
export {
|
||||||
|
ApplicationBaseSchema,
|
||||||
|
ApplicationSchema,
|
||||||
|
CreateApplicationSchema,
|
||||||
|
UpdateApplicationSchema,
|
||||||
|
ViewApplicationSchema,
|
||||||
|
getApplicationBaseSchema,
|
||||||
|
getCreateApplicationSchema,
|
||||||
|
getUpdateApplicationSchema,
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ApplicationFormData = z.infer<typeof ApplicationSchema>;
|
||||||
|
export type CreateApplicationFormData = z.infer<typeof CreateApplicationSchema>;
|
||||||
|
export type UpdateApplicationFormData = z.infer<typeof UpdateApplicationSchema>;
|
||||||
|
export type ViewApplicationFormData = z.infer<typeof ViewApplicationSchema>;
|
||||||
|
|
||||||
|
// Base field definitions grouped by section
|
||||||
|
const baseFieldDefinitions = {
|
||||||
|
// Identification fields
|
||||||
|
identificationInfo: {
|
||||||
|
title: "Identification Information",
|
||||||
|
order: 1,
|
||||||
|
fields: {
|
||||||
|
uu_id: {
|
||||||
|
type: "text",
|
||||||
|
label: {
|
||||||
|
tr: ApplicationBaseTranslationTr.uu_id,
|
||||||
|
en: ApplicationBaseTranslationEn.uu_id,
|
||||||
|
},
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: "text",
|
||||||
|
label: {
|
||||||
|
tr: ApplicationBaseTranslationTr.name,
|
||||||
|
en: ApplicationBaseTranslationEn.name,
|
||||||
|
},
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
application_code: {
|
||||||
|
type: "text",
|
||||||
|
label: {
|
||||||
|
tr: ApplicationBaseTranslationTr.application_code,
|
||||||
|
en: ApplicationBaseTranslationEn.application_code,
|
||||||
|
},
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Application details
|
||||||
|
applicationDetails: {
|
||||||
|
title: "Application Details",
|
||||||
|
order: 2,
|
||||||
|
fields: {
|
||||||
|
site_url: {
|
||||||
|
type: "text",
|
||||||
|
label: {
|
||||||
|
tr: ApplicationBaseTranslationTr.site_url,
|
||||||
|
en: ApplicationBaseTranslationEn.site_url,
|
||||||
|
},
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
application_type: {
|
||||||
|
type: "select",
|
||||||
|
label: {
|
||||||
|
tr: ApplicationBaseTranslationTr.application_type,
|
||||||
|
en: ApplicationBaseTranslationEn.application_type,
|
||||||
|
},
|
||||||
|
options: ["info", "Dash", "Admin"],
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
application_for: {
|
||||||
|
type: "select",
|
||||||
|
label: {
|
||||||
|
tr: ApplicationBaseTranslationTr.application_for,
|
||||||
|
en: ApplicationBaseTranslationEn.application_for,
|
||||||
|
},
|
||||||
|
options: ["EMP", "OCC"],
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: "textarea",
|
||||||
|
label: {
|
||||||
|
tr: ApplicationBaseTranslationTr.description,
|
||||||
|
en: ApplicationBaseTranslationEn.description,
|
||||||
|
},
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Status fields
|
||||||
|
statusInfo: {
|
||||||
|
title: "Status Information",
|
||||||
|
order: 3,
|
||||||
|
fields: {
|
||||||
|
active: {
|
||||||
|
type: "checkbox",
|
||||||
|
label: {
|
||||||
|
tr: ApplicationBaseTranslationTr.active,
|
||||||
|
en: ApplicationBaseTranslationEn.active,
|
||||||
|
},
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
defaultValue: true,
|
||||||
|
},
|
||||||
|
deleted: {
|
||||||
|
type: "checkbox",
|
||||||
|
label: {
|
||||||
|
tr: ApplicationBaseTranslationTr.deleted,
|
||||||
|
en: ApplicationBaseTranslationEn.deleted,
|
||||||
|
},
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// System fields
|
||||||
|
systemInfo: {
|
||||||
|
title: "System Information",
|
||||||
|
order: 4,
|
||||||
|
fields: {
|
||||||
|
created_at: {
|
||||||
|
type: "date",
|
||||||
|
label: {
|
||||||
|
tr: ApplicationBaseTranslationTr.created_at,
|
||||||
|
en: ApplicationBaseTranslationEn.created_at,
|
||||||
|
},
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
updated_at: {
|
||||||
|
type: "date",
|
||||||
|
label: {
|
||||||
|
tr: ApplicationBaseTranslationTr.updated_at,
|
||||||
|
en: ApplicationBaseTranslationEn.updated_at,
|
||||||
|
},
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a flat version of the field definitions for compatibility
|
||||||
|
const flatFieldDefinitions = flattenFieldDefinitions(baseFieldDefinitions);
|
||||||
|
|
||||||
|
// Create mode-specific field definitions using the flattened structure
|
||||||
|
export const createFieldDefinitions = {
|
||||||
|
name: {
|
||||||
|
...flatFieldDefinitions.name,
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
application_code: {
|
||||||
|
...flatFieldDefinitions.application_code,
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
site_url: {
|
||||||
|
...flatFieldDefinitions.site_url,
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
application_type: {
|
||||||
|
...flatFieldDefinitions.application_type,
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
application_for: {
|
||||||
|
...flatFieldDefinitions.application_for,
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "EMP",
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
...flatFieldDefinitions.description,
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
...flatFieldDefinitions.active,
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
defaultValue: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update mode-specific field definitions
|
||||||
|
export const updateFieldDefinitions = {
|
||||||
|
uu_id: {
|
||||||
|
...flatFieldDefinitions.uu_id,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
...flatFieldDefinitions.name,
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
application_code: {
|
||||||
|
...flatFieldDefinitions.application_code,
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
site_url: {
|
||||||
|
...flatFieldDefinitions.site_url,
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
application_type: {
|
||||||
|
...flatFieldDefinitions.application_type,
|
||||||
|
readOnly: false,
|
||||||
|
required: true,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
application_for: {
|
||||||
|
...flatFieldDefinitions.application_for,
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
...flatFieldDefinitions.description,
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
...flatFieldDefinitions.active,
|
||||||
|
readOnly: false,
|
||||||
|
required: false,
|
||||||
|
defaultValue: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// View mode-specific field definitions
|
||||||
|
export const viewFieldDefinitions = {
|
||||||
|
uu_id: {
|
||||||
|
...flatFieldDefinitions.uu_id,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: 0,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
...flatFieldDefinitions.name,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
application_code: {
|
||||||
|
...flatFieldDefinitions.application_code,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
site_url: {
|
||||||
|
...flatFieldDefinitions.site_url,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
application_type: {
|
||||||
|
...flatFieldDefinitions.application_type,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
application_for: {
|
||||||
|
...flatFieldDefinitions.application_for,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
...flatFieldDefinitions.description,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
active: {
|
||||||
|
...flatFieldDefinitions.active,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: true,
|
||||||
|
},
|
||||||
|
deleted: {
|
||||||
|
...flatFieldDefinitions.deleted,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: false,
|
||||||
|
},
|
||||||
|
created_at: {
|
||||||
|
...flatFieldDefinitions.created_at,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
updated_at: {
|
||||||
|
...flatFieldDefinitions.updated_at,
|
||||||
|
readOnly: true,
|
||||||
|
required: false,
|
||||||
|
defaultValue: "",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Combined field definitions for all modes
|
||||||
|
export const fieldDefinitions = {
|
||||||
|
...baseFieldDefinitions,
|
||||||
|
getDefinitionsByMode: (mode: "create" | "update" | "view") => {
|
||||||
|
switch (mode) {
|
||||||
|
case "create":
|
||||||
|
return createFieldDefinitions;
|
||||||
|
case "update":
|
||||||
|
return updateFieldDefinitions;
|
||||||
|
case "view":
|
||||||
|
return viewFieldDefinitions;
|
||||||
|
default:
|
||||||
|
return baseFieldDefinitions;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fields to show based on mode - dynamically generated from field definitions
|
||||||
|
export const fieldsByMode = {
|
||||||
|
create: Object.keys(createFieldDefinitions),
|
||||||
|
update: Object.keys(updateFieldDefinitions),
|
||||||
|
view: Object.keys(viewFieldDefinitions),
|
||||||
|
};
|
||||||
|
|
||||||
|
export type FieldDefinitionsType =
|
||||||
|
| typeof createFieldDefinitions
|
||||||
|
| typeof updateFieldDefinitions
|
||||||
|
| typeof viewFieldDefinitions;
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { Language } from "@/components/common/schemas";
|
||||||
|
import { GridSize } from "@/components/common/HeaderSelections/GridSelectionComponent";
|
||||||
|
import * as schema from "./schemaList/schema";
|
||||||
|
|
||||||
|
export interface ListComponentProps {
|
||||||
|
lang: Language;
|
||||||
|
loading: boolean;
|
||||||
|
error: any;
|
||||||
|
data: schema.ApplicationData[];
|
||||||
|
pagination: any;
|
||||||
|
showFields: string[];
|
||||||
|
gridCols: GridSize;
|
||||||
|
handleQueryChange: (key: string, value: string | null) => void;
|
||||||
|
updatePagination: (pagination: any) => void;
|
||||||
|
handleCardClick: (item: schema.ApplicationData) => void;
|
||||||
|
handleViewClick: (item: schema.ApplicationData) => void;
|
||||||
|
}
|
||||||
|
|
@ -2,42 +2,17 @@ import {
|
||||||
LanguageKey,
|
LanguageKey,
|
||||||
TranslationSet,
|
TranslationSet,
|
||||||
} from "@/validations/translations/translation";
|
} from "@/validations/translations/translation";
|
||||||
|
import {
|
||||||
export const fieldLanguageTranslation = {
|
ApplicationBaseTranslationEn,
|
||||||
tr: {
|
ApplicationBaseTranslationTr,
|
||||||
uu_id: "UUID",
|
} from "./schema";
|
||||||
name: "Ad",
|
|
||||||
application_code: "Kod",
|
|
||||||
site_url: "URL",
|
|
||||||
application_type: "Tür",
|
|
||||||
application_for: "Uygulama için",
|
|
||||||
description: "Açıklama",
|
|
||||||
active: "Aktif",
|
|
||||||
deleted: "Silindi",
|
|
||||||
created_at: "Oluşturulma Tarihi",
|
|
||||||
updated_at: "Güncellenme Tarihi",
|
|
||||||
},
|
|
||||||
en: {
|
|
||||||
uu_id: "UUID",
|
|
||||||
name: "Name",
|
|
||||||
application_code: "Code",
|
|
||||||
site_url: "URL",
|
|
||||||
application_type: "Type",
|
|
||||||
application_for: "Application for",
|
|
||||||
description: "Description",
|
|
||||||
active: "Active",
|
|
||||||
deleted: "Deleted",
|
|
||||||
created_at: "Created At",
|
|
||||||
updated_at: "Updated At",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Define translations as a flat object structure to match the common components expectations
|
// Define translations as a flat object structure to match the common components expectations
|
||||||
export const translations = {
|
export const translations = {
|
||||||
en: {
|
en: {
|
||||||
...fieldLanguageTranslation.en,
|
...ApplicationBaseTranslationEn,
|
||||||
// Page title
|
// Page title
|
||||||
applicationTitle: "Applications",
|
title: "Applications",
|
||||||
|
|
||||||
// Common actions
|
// Common actions
|
||||||
create: "Create",
|
create: "Create",
|
||||||
|
|
@ -108,8 +83,8 @@ export const translations = {
|
||||||
},
|
},
|
||||||
tr: {
|
tr: {
|
||||||
// Page title
|
// Page title
|
||||||
...fieldLanguageTranslation.tr,
|
...ApplicationBaseTranslationTr,
|
||||||
applicationTitle: "Uygulamalar",
|
title: "Uygulamalar",
|
||||||
|
|
||||||
// Common actions
|
// Common actions
|
||||||
create: "Oluştur",
|
create: "Oluştur",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
"use client";
|
"use client";
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import * as schema from "./schema";
|
import * as schema from "./schema";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
import { Card, CardContent } from "@/components/ui/card";
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
import { Building, Filter, User } from "lucide-react";
|
import { Building, Filter, User } from "lucide-react";
|
||||||
import { TypeQueryModifier } from "@/components/common/QueryModifiers/TypeQueryModifier";
|
import { TypeQueryModifier } from "@/components/common/QueryModifiers/TypeQueryModifier";
|
||||||
|
|
@ -12,7 +14,6 @@ import { CardDisplay } from "@/components/common/CardDisplay/CardDisplay";
|
||||||
import { FormMode } from "@/components/common/FormDisplay/types";
|
import { FormMode } from "@/components/common/FormDisplay/types";
|
||||||
import { FormDisplay } from "@/components/common/FormDisplay/FormDisplay";
|
import { FormDisplay } from "@/components/common/FormDisplay/FormDisplay";
|
||||||
import { GridSelectionComponent, GridSize } from "@/components/common/HeaderSelections/GridSelectionComponent";
|
import { GridSelectionComponent, GridSize } from "@/components/common/HeaderSelections/GridSelectionComponent";
|
||||||
import { LanguageSelectionComponent } from "@/components/common/HeaderSelections/LanguageSelectionComponent";
|
|
||||||
import { getCreateApplicationSchema, getUpdateApplicationSchema } from "./schema";
|
import { getCreateApplicationSchema, getUpdateApplicationSchema } from "./schema";
|
||||||
import { translations } from "./language";
|
import { translations } from "./language";
|
||||||
import { PageProps } from "@/validations/translations/translation";
|
import { PageProps } from "@/validations/translations/translation";
|
||||||
|
|
@ -21,64 +22,34 @@ import { Language } from "@/components/common/schemas";
|
||||||
|
|
||||||
const ApplicationPage: React.FC<PageProps> = ({ lang }: { lang: Language }) => {
|
const ApplicationPage: React.FC<PageProps> = ({ lang }: { lang: Language }) => {
|
||||||
|
|
||||||
const {
|
const { data, pagination, loading, error, updatePagination, refetch } = useApiData<schema.ApplicationData>('/api/applications');
|
||||||
data,
|
|
||||||
pagination,
|
|
||||||
loading,
|
|
||||||
error,
|
|
||||||
updatePagination,
|
|
||||||
refetch
|
|
||||||
} = useApiData<schema.ApplicationData>('/api/applications');
|
|
||||||
|
|
||||||
// State for managing view/edit modes
|
|
||||||
const [mode, setMode] = useState<FormMode>("list");
|
const [mode, setMode] = useState<FormMode>("list");
|
||||||
const [selectedItem, setSelectedItem] = useState<schema.ApplicationData | null>(null);
|
const [selectedItem, setSelectedItem] = useState<schema.ApplicationData | null>(null);
|
||||||
const [gridCols, setGridCols] = useState<GridSize>(3);
|
const [gridCols, setGridCols] = useState<GridSize>(3);
|
||||||
|
const [fieldDefinitions, setFieldDefinitions] = useState<schema.FieldDefinitionsType | null>(null);
|
||||||
|
const [validationSchema, setValidationSchema] = useState<z.ZodSchema | null>(null);
|
||||||
|
|
||||||
// Use state to store the field definitions and validation schema
|
|
||||||
const [fieldDefinitions, setFieldDefinitions] = useState(() =>
|
|
||||||
mode === 'create' ? schema.createFieldDefinitions :
|
|
||||||
mode === 'update' ? schema.updateFieldDefinitions :
|
|
||||||
schema.viewFieldDefinitions
|
|
||||||
);
|
|
||||||
|
|
||||||
const [validationSchema, setValidationSchema] = useState(() =>
|
|
||||||
mode === 'create' ? getCreateApplicationSchema(lang) :
|
|
||||||
mode === 'update' ? getUpdateApplicationSchema(lang) :
|
|
||||||
schema.ViewApplicationSchema
|
|
||||||
);
|
|
||||||
|
|
||||||
// Update field definitions when mode changes
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Select the appropriate field definitions based on the current mode
|
if (mode === 'create') {
|
||||||
const newFieldDefs = mode === 'create' ? schema.createFieldDefinitions :
|
setFieldDefinitions(schema.createFieldDefinitions);
|
||||||
mode === 'update' ? schema.updateFieldDefinitions :
|
setValidationSchema(getCreateApplicationSchema(lang));
|
||||||
schema.viewFieldDefinitions;
|
} else if (mode === 'update') {
|
||||||
|
setFieldDefinitions(schema.updateFieldDefinitions);
|
||||||
setFieldDefinitions(newFieldDefs);
|
setValidationSchema(getUpdateApplicationSchema(lang));
|
||||||
}, [mode]);
|
} else {
|
||||||
|
setFieldDefinitions(schema.viewFieldDefinitions);
|
||||||
// Update validation schema when mode or language changes
|
setValidationSchema(schema.ViewApplicationSchema);
|
||||||
useEffect(() => {
|
}
|
||||||
setValidationSchema(
|
|
||||||
mode === 'create' ? getCreateApplicationSchema(lang) :
|
|
||||||
mode === 'update' ? getUpdateApplicationSchema(lang) :
|
|
||||||
schema.ViewApplicationSchema
|
|
||||||
);
|
|
||||||
}, [mode, lang]);
|
}, [mode, lang]);
|
||||||
|
|
||||||
|
|
||||||
// Fields to display in the cards
|
|
||||||
const showFields = ["application_code", "site_url", "application_type"];
|
const showFields = ["application_code", "site_url", "application_type"];
|
||||||
|
|
||||||
// Search options
|
|
||||||
const searchOptions = {
|
const searchOptions = {
|
||||||
typeOptions: [
|
typeOptions: [
|
||||||
{
|
{
|
||||||
value: "EMP",
|
value: "EMP",
|
||||||
label: translations[lang].employee,
|
label: translations[lang].employee,
|
||||||
icon: <User className="mr-2 h-4 w-4" />
|
icon: <User className="mr-2 h-4 w-4" />
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "OCC",
|
value: "OCC",
|
||||||
|
|
@ -107,67 +78,61 @@ const ApplicationPage: React.FC<PageProps> = ({ lang }: { lang: Language }) => {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle query changes
|
|
||||||
const handleQueryChange = (key: string, value: string | null) => {
|
const handleQueryChange = (key: string, value: string | null) => {
|
||||||
const newQuery = { ...pagination.query };
|
const newQuery = { ...pagination.query };
|
||||||
|
if (value === null) { delete newQuery[key]; } else if (value.trim() === "") { delete newQuery[key]; } else { newQuery[key] = value; }
|
||||||
if (value === null) {
|
updatePagination({ page: 1, query: newQuery });
|
||||||
// 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: newQuery,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
const handleCardClick = (item: schema.ApplicationData) => { console.log("Card clicked:", item) };
|
||||||
|
const handleViewClick = (item: schema.ApplicationData) => { setSelectedItem(item); setMode("view"); };
|
||||||
|
const handleUpdateClick = (item: schema.ApplicationData) => { setSelectedItem(item); setTimeout(() => { setMode("update") }, 0); };
|
||||||
|
const handleCreateClick = () => { setSelectedItem(null); setMode("create"); };
|
||||||
|
|
||||||
|
const cancelAllSelections = () => {
|
||||||
// Handle card actions
|
|
||||||
const handleCardClick = (item: schema.ApplicationData) => {
|
|
||||||
console.log("Card clicked:", item);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleViewClick = (item: schema.ApplicationData) => {
|
|
||||||
setSelectedItem(item);
|
|
||||||
setMode("view");
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleUpdateClick = (item: schema.ApplicationData) => {
|
|
||||||
setSelectedItem(item);
|
|
||||||
setTimeout(() => {
|
|
||||||
setMode("update");
|
|
||||||
}, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle create button click
|
|
||||||
const handleCreateClick = () => {
|
|
||||||
setSelectedItem(null);
|
setSelectedItem(null);
|
||||||
setMode("create");
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle cancel
|
|
||||||
const handleCancel = () => {
|
|
||||||
setMode("list");
|
setMode("list");
|
||||||
setSelectedItem(null);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const applicationCardDisplayProps = {
|
||||||
|
showFields: showFields,
|
||||||
|
data: data,
|
||||||
|
lang: lang,
|
||||||
|
translations: translations,
|
||||||
|
error: error,
|
||||||
|
loading: loading,
|
||||||
|
titleField: "name",
|
||||||
|
onCardClick: handleCardClick,
|
||||||
|
gridCols: gridCols,
|
||||||
|
showViewIcon: true,
|
||||||
|
showUpdateIcon: true,
|
||||||
|
onViewClick: handleViewClick,
|
||||||
|
onUpdateClick: handleUpdateClick
|
||||||
|
};
|
||||||
|
|
||||||
|
const applicationFormProps = {
|
||||||
|
initialData: selectedItem || undefined,
|
||||||
|
mode,
|
||||||
|
refetch,
|
||||||
|
setMode,
|
||||||
|
setSelectedItem,
|
||||||
|
onCancel: cancelAllSelections,
|
||||||
|
lang,
|
||||||
|
translations,
|
||||||
|
apiUrl: '/api/applications',
|
||||||
|
formProps: {
|
||||||
|
fieldDefinitions,
|
||||||
|
validationSchema,
|
||||||
|
fieldsByMode: schema.fieldsByMode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container mx-auto p-4 overflow-y-auto" >
|
<div className="container mx-auto p-4 overflow-y-auto" >
|
||||||
<div className="mb-4 flex justify-between items-center">
|
<div className="mb-4 flex justify-between items-center">
|
||||||
<h1 className="text-2xl font-bold">{translations[lang].applicationTitle || "Applications"}</h1>
|
<h1 className="text-2xl font-bold">{translations[lang].title}</h1>
|
||||||
<div className="flex space-x-4">
|
<div className="flex space-x-4">
|
||||||
{/* Grid Selection */}
|
{/* Grid Selection */}
|
||||||
<GridSelectionComponent
|
<GridSelectionComponent gridCols={gridCols} setGridCols={setGridCols} />
|
||||||
gridCols={gridCols}
|
|
||||||
setGridCols={setGridCols}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -193,42 +158,23 @@ const ApplicationPage: React.FC<PageProps> = ({ lang }: { lang: Language }) => {
|
||||||
{/* Filters on the right */}
|
{/* Filters on the right */}
|
||||||
<div className={`w-full ${searchOptions.typeOptions.length > 0 ? 'md:w-1/2 md:pl-4' : ''} flex flex-col space-y-4`}>
|
<div className={`w-full ${searchOptions.typeOptions.length > 0 ? 'md:w-1/2 md:pl-4' : ''} flex flex-col space-y-4`}>
|
||||||
<div className="font-medium text-sm mb-2 flex justify-between items-center">
|
<div className="font-medium text-sm mb-2 flex justify-between items-center">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center"><Filter className="mr-2 h-4 w-4" />{translations[lang].filterSelection}</div>
|
||||||
<Filter className="mr-2 h-4 w-4" />
|
|
||||||
{translations[lang].filterSelection || "Filter Selection"}
|
|
||||||
</div>
|
|
||||||
{/* <Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={handleResetAllFilters}
|
|
||||||
className="text-xs"
|
|
||||||
>
|
|
||||||
{translations[lang].resetAll || "Reset All"}
|
|
||||||
</Button> */}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Search input */}
|
{/* Search input */}
|
||||||
<TextQueryModifier
|
<TextQueryModifier fieldKey="name" value={pagination.query["name__ilike"] ? pagination.query["name__ilike"].replace(/%/g, "") : ""} label={translations[lang].search} onQueryChange={handleQueryChange} translations={translations} lang={lang} />
|
||||||
fieldKey="name"
|
|
||||||
value={pagination.query["name__ilike"] ? pagination.query["name__ilike"].replace(/%/g, "") : ""}
|
|
||||||
label={translations[lang].search || "Search"}
|
|
||||||
onQueryChange={handleQueryChange}
|
|
||||||
translations={translations}
|
|
||||||
lang={lang}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Site URL dropdown */}
|
{/* Site URL dropdown */}
|
||||||
{searchOptions.urlOptions.length > 0 && (
|
{
|
||||||
<SelectQueryModifier
|
searchOptions.urlOptions.length > 0 && <SelectQueryModifier fieldKey="site_url"
|
||||||
fieldKey="site_url"
|
|
||||||
value={pagination.query["site_url__ilike"] ? pagination.query["site_url__ilike"].replace(/%/g, "") : ""}
|
value={pagination.query["site_url__ilike"] ? pagination.query["site_url__ilike"].replace(/%/g, "") : ""}
|
||||||
label={translations[lang].siteUrl || "Site URL"}
|
label={translations[lang].siteUrl}
|
||||||
options={searchOptions.urlOptions.map(url => ({ value: url, label: url }))}
|
options={searchOptions.urlOptions.map(url => ({ value: url, label: url }))}
|
||||||
onQueryChange={handleQueryChange}
|
onQueryChange={handleQueryChange}
|
||||||
translations={translations}
|
translations={translations}
|
||||||
lang={lang}
|
lang={lang}
|
||||||
/>
|
/>
|
||||||
)}
|
}
|
||||||
|
|
||||||
{/* Additional fields */}
|
{/* Additional fields */}
|
||||||
{/* {searchOptions.additionalFields && searchOptions.additionalFields?.map(field => (
|
{/* {searchOptions.additionalFields && searchOptions.additionalFields?.map(field => (
|
||||||
|
|
@ -249,65 +195,26 @@ const ApplicationPage: React.FC<PageProps> = ({ lang }: { lang: Language }) => {
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Create Button */}
|
{/* Create Button */}
|
||||||
<Card className="my-4">
|
<Card className="my-4"><CardContent className="pt-6"><CreateButton
|
||||||
<CardContent className="pt-6">
|
|
||||||
<CreateButton
|
|
||||||
onClick={handleCreateClick}
|
onClick={handleCreateClick}
|
||||||
translations={translations}
|
translations={translations}
|
||||||
lang={lang}
|
lang={lang}
|
||||||
/>
|
/></CardContent></Card>
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
{/* Pagination Tools Component */}
|
{/* Pagination Tools Component */}
|
||||||
<Card className="my-4">
|
<Card className="my-4"><CardContent className="pt-6"><PaginationToolsComponent
|
||||||
<CardContent className="pt-6">
|
|
||||||
<PaginationToolsComponent
|
|
||||||
pagination={pagination}
|
pagination={pagination}
|
||||||
updatePagination={updatePagination}
|
updatePagination={updatePagination}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
lang={lang}
|
lang={lang}
|
||||||
translations={translations}
|
translations={translations}
|
||||||
/>
|
/></CardContent></Card>
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
{/* Card Display Component */}
|
{/* Card Display Component */}
|
||||||
<div className="mt-6">
|
<div className="mt-6"><CardDisplay {...applicationCardDisplayProps} /></div>
|
||||||
<CardDisplay
|
|
||||||
showFields={showFields}
|
|
||||||
data={data}
|
|
||||||
lang={lang}
|
|
||||||
translations={translations}
|
|
||||||
error={error}
|
|
||||||
loading={loading}
|
|
||||||
titleField="name"
|
|
||||||
onCardClick={handleCardClick}
|
|
||||||
gridCols={gridCols}
|
|
||||||
showViewIcon={true}
|
|
||||||
showUpdateIcon={true}
|
|
||||||
onViewClick={handleViewClick}
|
|
||||||
onUpdateClick={handleUpdateClick}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<FormDisplay<schema.ApplicationData>
|
<FormDisplay<schema.ApplicationData> {...applicationFormProps} />
|
||||||
initialData={selectedItem || undefined}
|
|
||||||
mode={mode}
|
|
||||||
refetch={refetch}
|
|
||||||
setMode={setMode}
|
|
||||||
setSelectedItem={setSelectedItem}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
lang={lang}
|
|
||||||
translations={translations}
|
|
||||||
apiUrl='/api/applications'
|
|
||||||
formProps={{
|
|
||||||
fieldDefinitions,
|
|
||||||
validationSchema,
|
|
||||||
fieldsByMode: schema.fieldsByMode
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { flattenFieldDefinitions } from "../schemas/zodSchemas";
|
import { flattenFieldDefinitions } from "@/eventRouters/schemas/zodSchemas";
|
||||||
|
|
||||||
export interface ApplicationData {
|
export interface ApplicationData {
|
||||||
id?: number;
|
id?: number;
|
||||||
|
|
@ -21,26 +21,31 @@ const errorMessages = {
|
||||||
nameRequired: "Name is required",
|
nameRequired: "Name is required",
|
||||||
applicationCodeRequired: "Application code is required",
|
applicationCodeRequired: "Application code is required",
|
||||||
siteUrlRequired: "Site URL is required",
|
siteUrlRequired: "Site URL is required",
|
||||||
applicationTypeRequired: "Application type is required"
|
applicationTypeRequired: "Application type is required",
|
||||||
},
|
},
|
||||||
tr: {
|
tr: {
|
||||||
nameRequired: "İsim gereklidir",
|
nameRequired: "İsim gereklidir",
|
||||||
applicationCodeRequired: "Uygulama kodu gereklidir",
|
applicationCodeRequired: "Uygulama kodu gereklidir",
|
||||||
siteUrlRequired: "Site URL'si gereklidir",
|
siteUrlRequired: "Site URL'si gereklidir",
|
||||||
applicationTypeRequired: "Uygulama tipi gereklidir"
|
applicationTypeRequired: "Uygulama tipi gereklidir",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Function to get schema with language-specific validation messages
|
// Function to get schema with language-specific validation messages
|
||||||
const getApplicationBaseSchema = (lang: "en" | "tr" = "en") => z.object({
|
const getApplicationBaseSchema = (lang: "en" | "tr" = "en") =>
|
||||||
|
z.object({
|
||||||
// Identification fields
|
// Identification fields
|
||||||
uu_id: z.string().optional(),
|
uu_id: z.string().optional(),
|
||||||
name: z.string().min(1, errorMessages[lang].nameRequired),
|
name: z.string().min(1, errorMessages[lang].nameRequired),
|
||||||
application_code: z.string().min(1, errorMessages[lang].applicationCodeRequired),
|
application_code: z
|
||||||
|
.string()
|
||||||
|
.min(1, errorMessages[lang].applicationCodeRequired),
|
||||||
|
|
||||||
// Application details
|
// Application details
|
||||||
site_url: z.string().min(1, errorMessages[lang].siteUrlRequired),
|
site_url: z.string().min(1, errorMessages[lang].siteUrlRequired),
|
||||||
application_type: z.string().min(1, errorMessages[lang].applicationTypeRequired),
|
application_type: z
|
||||||
|
.string()
|
||||||
|
.min(1, errorMessages[lang].applicationTypeRequired),
|
||||||
application_for: z.string().optional(),
|
application_for: z.string().optional(),
|
||||||
description: z.string().optional(),
|
description: z.string().optional(),
|
||||||
|
|
||||||
|
|
@ -56,7 +61,7 @@ const getApplicationBaseSchema = (lang: "en" | "tr" = "en") => z.object({
|
||||||
// For backward compatibility
|
// For backward compatibility
|
||||||
const ApplicationBaseSchema = getApplicationBaseSchema("en");
|
const ApplicationBaseSchema = getApplicationBaseSchema("en");
|
||||||
|
|
||||||
const ApplicationBaseTranslationTr = {
|
export const ApplicationBaseTranslationTr = {
|
||||||
uu_id: "UUID",
|
uu_id: "UUID",
|
||||||
name: "Name",
|
name: "Name",
|
||||||
application_code: "Application Code",
|
application_code: "Application Code",
|
||||||
|
|
@ -70,7 +75,7 @@ const ApplicationBaseTranslationTr = {
|
||||||
updated_at: "Updated At",
|
updated_at: "Updated At",
|
||||||
};
|
};
|
||||||
|
|
||||||
const ApplicationBaseTranslationEn = {
|
export const ApplicationBaseTranslationEn = {
|
||||||
uu_id: "UUID",
|
uu_id: "UUID",
|
||||||
name: "Name",
|
name: "Name",
|
||||||
application_code: "Application Code",
|
application_code: "Application Code",
|
||||||
|
|
@ -95,11 +100,13 @@ const getCreateApplicationSchema = (lang: "en" | "tr" = "en") =>
|
||||||
|
|
||||||
// Update schema for updating existing applications with language support
|
// Update schema for updating existing applications with language support
|
||||||
const getUpdateApplicationSchema = (lang: "en" | "tr" = "en") =>
|
const getUpdateApplicationSchema = (lang: "en" | "tr" = "en") =>
|
||||||
getApplicationBaseSchema(lang).omit({
|
getApplicationBaseSchema(lang)
|
||||||
|
.omit({
|
||||||
created_at: true,
|
created_at: true,
|
||||||
updated_at: true,
|
updated_at: true,
|
||||||
deleted: true,
|
deleted: true,
|
||||||
}).required({
|
})
|
||||||
|
.required({
|
||||||
uu_id: true,
|
uu_id: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -462,3 +469,8 @@ export const fieldsByMode = {
|
||||||
update: Object.keys(updateFieldDefinitions),
|
update: Object.keys(updateFieldDefinitions),
|
||||||
view: Object.keys(viewFieldDefinitions),
|
view: Object.keys(viewFieldDefinitions),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type FieldDefinitionsType =
|
||||||
|
| typeof createFieldDefinitions
|
||||||
|
| typeof updateFieldDefinitions
|
||||||
|
| typeof viewFieldDefinitions;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue