updated management service bind

This commit is contained in:
Berkay 2025-05-03 18:38:50 +03:00
parent c6b1a2b1e8
commit ac8c3fe1c3
15 changed files with 1085 additions and 293 deletions

View File

@ -47,7 +47,7 @@ export function CardDisplay<T>({
{(translations[lang] || {}).noData || "No data found"}
</div>
) : (
data.map((item, index) => (
data.map((item: T, index: number) => (
<CardItem
key={index}
item={item}

View File

@ -19,16 +19,12 @@ export function FormDisplay<T>({
}: FormDisplayProps<T>) {
const [enhancedFormProps, setEnhancedFormProps] = useState(formProps);
// Update form props when language or mode changes
useEffect(() => {
const updateFormProps = async () => {
try {
// Check if schemaPath is provided in formProps
if (formProps.schemaPath) {
// Dynamic import of the schema module
const schemaModule = await import(formProps.schemaPath);
// Get the appropriate field definitions based on mode
let fieldDefs;
if (schemaModule.fieldDefinitions?.getDefinitionsByMode) {
fieldDefs = schemaModule.fieldDefinitions.getDefinitionsByMode(mode);
@ -40,13 +36,10 @@ export function FormDisplay<T>({
fieldDefs = schemaModule.viewFieldDefinitions;
}
// Get the appropriate validation schema based on mode and language
let validationSchema;
if (mode === "create" && schemaModule.getCreateApplicationSchema) {
// Use language-aware schema factory function
validationSchema = schemaModule.getCreateApplicationSchema(lang as "en" | "tr");
} else if (mode === "update" && schemaModule.getUpdateApplicationSchema) {
// Use language-aware schema factory function
validationSchema = schemaModule.getUpdateApplicationSchema(lang as "en" | "tr");
} else if (mode === "view" && schemaModule.ViewApplicationSchema) {
validationSchema = schemaModule.ViewApplicationSchema;
@ -54,23 +47,17 @@ export function FormDisplay<T>({
validationSchema = schemaModule.ApplicationSchema;
}
// Get the grouped field definitions structure if available
const groupedFieldDefs = schemaModule.baseFieldDefinitions || {};
// Update form props with schema information and current language
setEnhancedFormProps({
...formProps,
fieldDefinitions: fieldDefs || {},
validationSchema,
fieldsByMode: schemaModule.fieldsByMode || {},
groupedFieldDefinitions: groupedFieldDefs,
// Add current language to force child components to recognize changes
currentLang: lang,
// Add schema path for dynamic imports in child components
schemaPath: formProps.schemaPath
});
} else {
// If no schema path, just update with current language
setEnhancedFormProps({
...formProps,
currentLang: lang
@ -78,7 +65,6 @@ export function FormDisplay<T>({
}
} catch (error) {
console.error("Error loading schema definitions:", error);
// Even on error, update the language
setEnhancedFormProps({
...formProps,
currentLang: lang
@ -87,17 +73,13 @@ export function FormDisplay<T>({
};
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) {
case "create":
return (
<CreateComponent<T>
key={`create-${lang}`} // Add key with lang to force re-render on language change
key={`create-${lang}`}
refetch={refetch}
setMode={setMode}
setSelectedItem={setSelectedItem}

View File

@ -1,6 +1,5 @@
"use client";
// Import field definitions type
export interface FieldDefinition {
type: string;
group: string;
@ -12,13 +11,13 @@ export interface FieldDefinition {
name?: string;
}
// Define the FormMode type to ensure consistency
export type FormMode = "list" | "create" | "update" | "view";
export type FormModeView = "list" | "view";
export interface BaseFormProps<T> {
initialData?: T;
refetch?: () => void;
setMode: React.Dispatch<React.SetStateAction<FormMode>>;
setMode: React.Dispatch<React.SetStateAction<FormMode | FormModeView>>;
setSelectedItem: React.Dispatch<React.SetStateAction<T | null>>;
onCancel: () => void;
lang: string;
@ -30,19 +29,19 @@ export interface BaseFormProps<T> {
export interface CreateComponentProps<T> extends BaseFormProps<T> {}
export interface UpdateComponentProps<T> extends BaseFormProps<T> {
initialData: T; // Required for update
initialData: T;
apiUrl: string;
}
export interface ViewComponentProps<T> extends BaseFormProps<T> {
initialData: T; // Required for view
initialData: T;
}
export interface FormDisplayProps<T> {
mode: FormMode;
mode: FormMode | FormModeView;
initialData?: T;
refetch?: () => void;
setMode: React.Dispatch<React.SetStateAction<FormMode>>;
setMode: React.Dispatch<React.SetStateAction<FormModeView | FormMode>>;
setSelectedItem: React.Dispatch<React.SetStateAction<T | null>>;
onCancel: () => void;
lang: string;

View File

@ -10,26 +10,21 @@ export const TextQueryModifier: React.FC<TextQueryModifierProps> = ({
value,
label,
placeholder,
onQueryChange,
translations,
lang,
onQueryChange,
}) => {
const t = translations[lang] || {};
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value;
onQueryChange(fieldKey, newValue);
const newValue = e.target.value; onQueryChange(fieldKey, newValue);
}, [fieldKey, onQueryChange]);
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]);
const handleKeyUp = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
// Apply the search immediately on Enter
const formattedValue = value.trim() ? `%${value.trim()}%` : null;
onQueryChange(`${fieldKey}__ilike`, formattedValue);
}
@ -42,9 +37,7 @@ export const TextQueryModifier: React.FC<TextQueryModifierProps> = ({
return (
<div className="w-full">
<label className="block text-xs font-medium mb-1">
{label || t[fieldKey] || fieldKey}
</label>
<label className="block text-xs font-medium mb-1">{label || t[fieldKey] || fieldKey}</label>
<div className="relative w-full flex">
<div className="relative w-full">
<Input
@ -61,19 +54,15 @@ export const TextQueryModifier: React.FC<TextQueryModifierProps> = ({
size="icon"
className="absolute right-1 top-1 h-8 w-8"
onClick={handleClear}
>
<X className="h-4 w-4" />
</Button>
><X className="h-4 w-4" /></Button>
)}
</div>
<Button
variant="default"
size="sm"
size="lg"
className="ml-2"
onClick={handleSearch}
>
<Search className="h-4 w-4" />
</Button>
><Search className="h-4 w-4" /></Button>
</div>
</div>
);

View File

@ -12,14 +12,14 @@ export const dashboardLanguage = {
export const NavigationLanguage = {
en: {
"/dashboard": "Dashboard",
"/append/event": "Event Board",
"/append/service": "Service Board",
"/append/application": "Application Bind Board",
"/append/service": "Service Bind Board",
"/application": "Application Board",
},
tr: {
"/dashboard": "Kontrol Paneli",
"/append/event": "Event Paneli",
"/append/service": "Servis Paneli",
"/append/application": "Uygulama Bağlama Paneli",
"/append/service": "Servis Bağlama Paneli",
"/application": "Uygulama Paneli",
},
};
@ -70,4 +70,4 @@ export const OccupantProfileLanguage = {
backToBuildings: "Back to buildings",
buildNo: "Build No",
},
};
};

View File

@ -44,7 +44,7 @@ function SelectTrigger({
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDownIcon className="size-4 opacity-50" />
{/* <ChevronDownIcon className="size-4 opacity-50" /> */}
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
)
@ -63,7 +63,7 @@ function SelectContent({
className={cn(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className
)}
position={position}
@ -74,7 +74,7 @@ function SelectContent({
className={cn(
"p-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
)}
>
{children}

View File

@ -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];
}

View File

@ -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;

View File

@ -1,9 +1,215 @@
"use client";
import React from "react";
import { PageProps } from "@/validations/translations/translation";
import React, { useState, useEffect } from "react";
import { z } from "zod";
const AppendersServicePage: React.FC<PageProps> = () => {
return <div>AppendersServicePage</div>;
import * as schema from "./schemaList/schema";
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;

View File

@ -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;

View File

@ -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;
}

View File

@ -2,42 +2,17 @@ import {
LanguageKey,
TranslationSet,
} from "@/validations/translations/translation";
export const fieldLanguageTranslation = {
tr: {
uu_id: "UUID",
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",
},
};
import {
ApplicationBaseTranslationEn,
ApplicationBaseTranslationTr,
} from "./schema";
// Define translations as a flat object structure to match the common components expectations
export const translations = {
en: {
...fieldLanguageTranslation.en,
...ApplicationBaseTranslationEn,
// Page title
applicationTitle: "Applications",
title: "Applications",
// Common actions
create: "Create",
@ -108,8 +83,8 @@ export const translations = {
},
tr: {
// Page title
...fieldLanguageTranslation.tr,
applicationTitle: "Uygulamalar",
...ApplicationBaseTranslationTr,
title: "Uygulamalar",
// Common actions
create: "Oluştur",

View File

@ -1,6 +1,8 @@
"use client";
import React, { useState, useEffect } from "react";
import * as schema from "./schema";
import { z } from "zod";
import { Card, CardContent } from "@/components/ui/card";
import { Building, Filter, User } from "lucide-react";
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 { FormDisplay } from "@/components/common/FormDisplay/FormDisplay";
import { GridSelectionComponent, GridSize } from "@/components/common/HeaderSelections/GridSelectionComponent";
import { LanguageSelectionComponent } from "@/components/common/HeaderSelections/LanguageSelectionComponent";
import { getCreateApplicationSchema, getUpdateApplicationSchema } from "./schema";
import { translations } from "./language";
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 {
data,
pagination,
loading,
error,
updatePagination,
refetch
} = useApiData<schema.ApplicationData>('/api/applications');
const { data, pagination, loading, error, updatePagination, refetch } = useApiData<schema.ApplicationData>('/api/applications');
// State for managing view/edit modes
const [mode, setMode] = useState<FormMode>("list");
const [selectedItem, setSelectedItem] = useState<schema.ApplicationData | null>(null);
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(() => {
// Select the appropriate field definitions based on the current mode
const newFieldDefs = mode === 'create' ? schema.createFieldDefinitions :
mode === 'update' ? schema.updateFieldDefinitions :
schema.viewFieldDefinitions;
setFieldDefinitions(newFieldDefs);
}, [mode]);
// Update validation schema when mode or language changes
useEffect(() => {
setValidationSchema(
mode === 'create' ? getCreateApplicationSchema(lang) :
mode === 'update' ? getUpdateApplicationSchema(lang) :
schema.ViewApplicationSchema
);
if (mode === 'create') {
setFieldDefinitions(schema.createFieldDefinitions);
setValidationSchema(getCreateApplicationSchema(lang));
} else if (mode === 'update') {
setFieldDefinitions(schema.updateFieldDefinitions);
setValidationSchema(getUpdateApplicationSchema(lang));
} else {
setFieldDefinitions(schema.viewFieldDefinitions);
setValidationSchema(schema.ViewApplicationSchema);
}
}, [mode, lang]);
// Fields to display in the cards
const showFields = ["application_code", "site_url", "application_type"];
// Search options
const searchOptions = {
typeOptions: [
{
value: "EMP",
label: translations[lang].employee,
icon: <User className="mr-2 h-4 w-4" />
},
{
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 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: newQuery,
});
if (value === null) { delete newQuery[key]; } else if (value.trim() === "") { delete newQuery[key]; } else { newQuery[key] = value; }
updatePagination({ page: 1, 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"); };
// 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 = () => {
const cancelAllSelections = () => {
setSelectedItem(null);
setMode("create");
};
// Handle cancel
const handleCancel = () => {
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 (
<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].applicationTitle || "Applications"}</h1>
<h1 className="text-2xl font-bold">{translations[lang].title}</h1>
<div className="flex space-x-4">
{/* Grid Selection */}
<GridSelectionComponent
gridCols={gridCols}
setGridCols={setGridCols}
/>
<GridSelectionComponent gridCols={gridCols} setGridCols={setGridCols} />
</div>
</div>
@ -193,42 +158,23 @@ const ApplicationPage: React.FC<PageProps> = ({ lang }: { lang: Language }) => {
{/* 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="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 || "Filter Selection"}
</div>
{/* <Button
variant="outline"
size="sm"
onClick={handleResetAllFilters}
className="text-xs"
>
{translations[lang].resetAll || "Reset All"}
</Button> */}
<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 || "Search"}
onQueryChange={handleQueryChange}
translations={translations}
lang={lang}
/>
<TextQueryModifier fieldKey="name" value={pagination.query["name__ilike"] ? pagination.query["name__ilike"].replace(/%/g, "") : ""} label={translations[lang].search} onQueryChange={handleQueryChange} translations={translations} lang={lang} />
{/* Site URL dropdown */}
{searchOptions.urlOptions.length > 0 && (
<SelectQueryModifier
fieldKey="site_url"
{
searchOptions.urlOptions.length > 0 && <SelectQueryModifier fieldKey="site_url"
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 }))}
onQueryChange={handleQueryChange}
translations={translations}
lang={lang}
/>
)}
}
{/* Additional fields */}
{/* {searchOptions.additionalFields && searchOptions.additionalFields?.map(field => (
@ -249,65 +195,26 @@ const ApplicationPage: React.FC<PageProps> = ({ lang }: { lang: Language }) => {
</Card>
{/* Create Button */}
<Card className="my-4">
<CardContent className="pt-6">
<CreateButton
onClick={handleCreateClick}
translations={translations}
lang={lang}
/>
</CardContent>
</Card>
<Card className="my-4"><CardContent className="pt-6"><CreateButton
onClick={handleCreateClick}
translations={translations}
lang={lang}
/></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 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}
onUpdateClick={handleUpdateClick}
/>
</div>
<div className="mt-6"><CardDisplay {...applicationCardDisplayProps} /></div>
</>
) : (
<FormDisplay<schema.ApplicationData>
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
}}
/>
<FormDisplay<schema.ApplicationData> {...applicationFormProps} />
)}
</div>
);

View File

@ -1,5 +1,5 @@
import { z } from "zod";
import { flattenFieldDefinitions } from "../schemas/zodSchemas";
import { flattenFieldDefinitions } from "@/eventRouters/schemas/zodSchemas";
export interface ApplicationData {
id?: number;
@ -21,42 +21,47 @@ const errorMessages = {
nameRequired: "Name is required",
applicationCodeRequired: "Application code is required",
siteUrlRequired: "Site URL is required",
applicationTypeRequired: "Application type is required"
applicationTypeRequired: "Application type is required",
},
tr: {
nameRequired: "İsim gereklidir",
applicationCodeRequired: "Uygulama kodu gereklidir",
siteUrlRequired: "Site URL'si gereklidir",
applicationTypeRequired: "Uygulama tipi 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),
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(),
// 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),
// Status fields
active: z.boolean().default(true),
deleted: z.boolean().default(false),
// System fields
created_at: z.string().optional(),
updated_at: z.string().optional(),
});
// System fields
created_at: z.string().optional(),
updated_at: z.string().optional(),
});
// For backward compatibility
const ApplicationBaseSchema = getApplicationBaseSchema("en");
const ApplicationBaseTranslationTr = {
export const ApplicationBaseTranslationTr = {
uu_id: "UUID",
name: "Name",
application_code: "Application Code",
@ -70,7 +75,7 @@ const ApplicationBaseTranslationTr = {
updated_at: "Updated At",
};
const ApplicationBaseTranslationEn = {
export const ApplicationBaseTranslationEn = {
uu_id: "UUID",
name: "Name",
application_code: "Application Code",
@ -85,7 +90,7 @@ const ApplicationBaseTranslationEn = {
};
// Create schema for creating new applications with language support
const getCreateApplicationSchema = (lang: "en" | "tr" = "en") =>
const getCreateApplicationSchema = (lang: "en" | "tr" = "en") =>
getApplicationBaseSchema(lang).omit({
uu_id: true,
created_at: true,
@ -94,14 +99,16 @@ const getCreateApplicationSchema = (lang: "en" | "tr" = "en") =>
});
// 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,
});
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");
@ -462,3 +469,8 @@ export const fieldsByMode = {
update: Object.keys(updateFieldDefinitions),
view: Object.keys(viewFieldDefinitions),
};
export type FieldDefinitionsType =
| typeof createFieldDefinitions
| typeof updateFieldDefinitions
| typeof viewFieldDefinitions;