pages updated

This commit is contained in:
berkay 2025-01-06 16:38:27 +03:00
parent 24d2169132
commit c1f517d32d
51 changed files with 1619 additions and 420 deletions

View File

@ -3,9 +3,10 @@ export const tokenSecret = process.env.TOKENSECRET || "";
export const cookieObject: any = { export const cookieObject: any = {
httpOnly: true, httpOnly: true,
path: "/", path: "/",
sameSite: "lax", sameSite: "none",
secure: true, secure: true,
maxAge: 3600, maxAge: 3600,
priority: "high",
}; };
interface FilterListInterface { interface FilterListInterface {
@ -34,7 +35,7 @@ class FilterList {
}: FilterListInterface = {}) { }: FilterListInterface = {}) {
this.page = page ?? 1; this.page = page ?? 1;
this.size = size ?? 5; this.size = size ?? 5;
this.orderField = orderField ?? "id"; this.orderField = orderField ?? "uu_id";
this.orderType = orderType ?? "asc"; this.orderType = orderType ?? "asc";
this.orderType = this.orderType.startsWith("a") ? "asc" : "desc"; this.orderType = this.orderType.startsWith("a") ? "asc" : "desc";
this.includeJoins = includeJoins ?? []; this.includeJoins = includeJoins ?? [];

View File

@ -13,7 +13,6 @@ const buildUpdateEndpoint = `${baseUrl}/building/build/update`;
async function retrieveBuildList(payload: FilterListInterface) { async function retrieveBuildList(payload: FilterListInterface) {
const feedObject = new FilterList(payload).filter(); const feedObject = new FilterList(payload).filter();
console.log("feedObject", feedObject);
const tokenResponse: any = await fetchDataWithToken( const tokenResponse: any = await fetchDataWithToken(
buildListEndpoint, buildListEndpoint,
feedObject, feedObject,
@ -41,6 +40,7 @@ async function updateBuild(payload: any) {
} }
async function createBuild(payload: any) { async function createBuild(payload: any) {
console.log("payload", payload);
const tokenResponse: any = await fetchDataWithToken( const tokenResponse: any = await fetchDataWithToken(
buildCreateEndpoint, buildCreateEndpoint,
payload, payload,

View File

@ -3,7 +3,7 @@ import { fetchData, fetchDataWithToken } from "../api-fetcher";
import { cookies } from "next/headers"; import { cookies } from "next/headers";
import { baseUrl, cookieObject, tokenSecret } from "../basics"; import { baseUrl, cookieObject, tokenSecret } from "../basics";
import NextCrypto from "next-crypto"; import NextCrypto from "next-crypto";
import { setAvailableEvents } from "../events/available"; // import { setAvailableEvents } from "../events/available";
const loginEndpoint = `${baseUrl}/authentication/login`; const loginEndpoint = `${baseUrl}/authentication/login`;
const loginSelectEndpoint = `${baseUrl}/authentication/select`; const loginSelectEndpoint = `${baseUrl}/authentication/select`;
@ -75,11 +75,6 @@ async function loginViaAccessKeys(payload: LoginViaAccessKeys) {
value: JSON.stringify(userProfile), value: JSON.stringify(userProfile),
...cookieObject, ...cookieObject,
}); });
// cookieStore.set({
// name: "userType",
// value: userType,
// ...cookieObject,
// });
} }
return tokenResponse; return tokenResponse;
} }
@ -108,7 +103,6 @@ async function loginSelectEmployee(payload: LoginSelectEmployee) {
value: usersSelection, value: usersSelection,
...cookieObject, ...cookieObject,
}); });
await setAvailableEvents();
} }
return selectResponse; return selectResponse;
} }
@ -143,7 +137,7 @@ async function loginSelectOccupant(payload: LoginSelectOccupant) {
value: usersSelection, value: usersSelection,
...cookieObject, ...cookieObject,
}); });
await setAvailableEvents(); // await setAvailableEvents();
} }
return selectResponse; return selectResponse;
} }

View File

@ -2,6 +2,7 @@
import { fetchDataWithToken } from "../api-fetcher"; import { fetchDataWithToken } from "../api-fetcher";
import { cookies } from "next/headers"; import { cookies } from "next/headers";
import { baseUrl } from "../basics"; import { baseUrl } from "../basics";
import { redirect } from "next/navigation";
const logOutEndpoint = `${baseUrl}/authentication/logout`; const logOutEndpoint = `${baseUrl}/authentication/logout`;
const logOutAllEndpoint = `${baseUrl}/authentication/disconnect`; const logOutAllEndpoint = `${baseUrl}/authentication/disconnect`;
@ -11,7 +12,6 @@ interface LoginOutUser {
} }
async function logoutActiveSession(payload: LoginOutUser) { async function logoutActiveSession(payload: LoginOutUser) {
"use server";
const cookieStore = await cookies(); const cookieStore = await cookies();
cookieStore.delete("accessToken"); cookieStore.delete("accessToken");
cookieStore.delete("accessObject"); cookieStore.delete("accessObject");
@ -26,10 +26,7 @@ async function logoutActiveSession(payload: LoginOutUser) {
"POST", "POST",
false false
); );
if (tokenResponse.status === 200) { return tokenResponse.status === 200 ? true : false;
return true;
}
return false;
} }
async function logoutAllSessions(payload: LoginOutUser) { async function logoutAllSessions(payload: LoginOutUser) {

View File

@ -33,7 +33,7 @@ class HeadersAndValidations {
parseProcesser() { parseProcesser() {
Object.entries(this.validation).map(([key, value]) => { Object.entries(this.validation).map(([key, value]) => {
this.validated[key] = { this.validated[key] = {
required: !value.required, required: value.required,
fieldType: value?.type, fieldType: value?.type,
}; };
}); });

View File

@ -1,3 +1,5 @@
import { url } from "inspector";
const BuildPageInfo = { const BuildPageInfo = {
tr: [ tr: [
{ {
@ -6,6 +8,7 @@ const BuildPageInfo = {
icon: null, icon: null,
description: "Bina listeyebilirsiniz", description: "Bina listeyebilirsiniz",
endpoint: "/building/build/list", endpoint: "/building/build/list",
url: "/building",
component: "Table", component: "Table",
}, },
{ {
@ -14,6 +17,7 @@ const BuildPageInfo = {
name: "create", name: "create",
description: "Bina oluşturma sayfasına hoş geldiniz", description: "Bina oluşturma sayfasına hoş geldiniz",
endpoint: "/building/build/create", endpoint: "/building/build/create",
url: "/building/create",
component: "AddCreate2Table", component: "AddCreate2Table",
}, },
{ {
@ -22,6 +26,7 @@ const BuildPageInfo = {
name: "update", name: "update",
description: "Bina güncelleme sayfasına hoş geldiniz", description: "Bina güncelleme sayfasına hoş geldiniz",
endpoint: "/building/build/update/{build_uu_id}", endpoint: "/building/build/update/{build_uu_id}",
url: "/building/update",
component: "AddUpdate2Table", component: "AddUpdate2Table",
}, },
], ],
@ -31,6 +36,7 @@ const BuildPageInfo = {
icon: null, icon: null,
description: "Welcome to the building update page", description: "Welcome to the building update page",
endpoint: "/building/build/list", endpoint: "/building/build/list",
url: "/building",
component: "Table", component: "Table",
}, },
{ {
@ -38,6 +44,7 @@ const BuildPageInfo = {
icon: "BadgePlus", icon: "BadgePlus",
description: "Welcome to the building creation page", description: "Welcome to the building creation page",
endpoint: "/building/build/create", endpoint: "/building/build/create",
url: "/building/create",
component: "AddCreate2Table", component: "AddCreate2Table",
}, },
{ {
@ -45,6 +52,7 @@ const BuildPageInfo = {
icon: "Pencil", icon: "Pencil",
description: "Welcome to the building update page", description: "Welcome to the building update page",
endpoint: "/building/build/update/{build_uu_id}", endpoint: "/building/build/update/{build_uu_id}",
url: "/building/update",
component: "AddUpdate2Table", component: "AddUpdate2Table",
}, },
], ],

View File

@ -30,13 +30,13 @@ const PagesInfosAndEndpoints = [
subCategories: BuildCategories, subCategories: BuildCategories,
}, },
{ {
name: "", name: "MeetingsPage",
title: { title: {
tr: "Toplantılar", tr: "Toplantılar",
en: "Meetings", en: "Meetings",
}, },
icon: "Logs", icon: "Logs",
url: "/meetings?page=1", url: "/meetings",
pageInfo: null, pageInfo: null,
component: null, component: null,
allEndpoints: MeetingAllEndpoints, allEndpoints: MeetingAllEndpoints,
@ -50,7 +50,7 @@ const PagesInfosAndEndpoints = [
}, },
icon: "Landmark", icon: "Landmark",
component: "AccountPage", component: "AccountPage",
url: "/accounts?page=1", url: "/accounts",
pageInfo: AccountPageInfo, pageInfo: AccountPageInfo,
allEndpoints: AccountAllEndpoints, allEndpoints: AccountAllEndpoints,
subCategories: AccountSubCategories, subCategories: AccountSubCategories,
@ -63,7 +63,7 @@ const PagesInfosAndEndpoints = [
}, },
icon: "ScrollText", icon: "ScrollText",
component: "DecisionBookPage", component: "DecisionBookPage",
url: "/decisions?page=1", url: "/decisions",
pageInfo: DecisionBookPageInfo, pageInfo: DecisionBookPageInfo,
allEndpoints: DecisionBookAllEndpoints, allEndpoints: DecisionBookAllEndpoints,
subCategories: DecisionBookSubCategories, subCategories: DecisionBookSubCategories,
@ -76,7 +76,7 @@ const PagesInfosAndEndpoints = [
}, },
icon: "UserPlus", icon: "UserPlus",
component: null, component: null,
url: "/identities?page=1", url: "/identities",
pageInfo: null, pageInfo: null,
allEndpoints: IdentityAllEndpoints, allEndpoints: IdentityAllEndpoints,
subCategories: IdentityCategories, subCategories: IdentityCategories,
@ -89,7 +89,7 @@ const PagesInfosAndEndpoints = [
}, },
icon: "Cog", icon: "Cog",
component: null, component: null,
url: "/accessibilities?page=1", url: "/accessibilities",
pageInfo: null, pageInfo: null,
allEndpoints: AccesibleAllEndpoints, allEndpoints: AccesibleAllEndpoints,
subCategories: AccesibleCategories, subCategories: AccesibleCategories,
@ -102,7 +102,7 @@ const PagesInfosAndEndpoints = [
}, },
icon: "Store", icon: "Store",
component: "CompanyPage", component: "CompanyPage",
url: "/companies?page=1", url: "/companies",
pageInfo: CompanyPageInfo, pageInfo: CompanyPageInfo,
allEndpoints: CompanyAllEndpoints, allEndpoints: CompanyAllEndpoints,
subCategories: CompanyCategories, subCategories: CompanyCategories,

View File

@ -1,7 +1,14 @@
import type { NextConfig } from "next"; import type { NextConfig } from "next";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
/* config options here */ images: {
remotePatterns: [
{
protocol: "https",
hostname: "s.tmimgcdn.com",
},
],
},
}; };
export default nextConfig; export default nextConfig;

View File

@ -0,0 +1,96 @@
"use client";
import { RetrieveInputByType } from "@/hooks/renderInputWithValidation";
import * as z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
FormDescription,
} from "@/components/ui/form";
import { convertApiValidationToZodValidation } from "@/lib/renderZodValidation";
interface CreatePageComponentInterface {
validator: any;
headers: any;
}
const CreatePageComponent: React.FC<CreatePageComponentInterface> = ({
validator,
headers,
}) => {
const returnValidation = convertApiValidationToZodValidation(validator);
const { validSchemaZod, zodValidation, apiValidation } = returnValidation;
const form = useForm<z.infer<typeof validSchemaZod>>({
resolver: zodResolver(validSchemaZod),
defaultValues: {},
});
function submitUpdate(formData: z.infer<typeof validSchemaZod>) {
// saveFunction({
// uu_id: updateUUID,
// payload: validDataParser(formData),
// }).then((res: any) => {
// console.log(res);
// if (res?.status === 200) {
// } else {
// alert("Güncelleme başarısız");
// }
// });
}
return (
<div className="container mx-auto p-4">
<Form {...form}>
<form action="">
{Object.entries(validator).map(([key, value]: [string, any]) => (
<FormField
key={key}
control={form.control}
name={String(key)}
render={({ field }) => {
return (
<FormItem>
<FormLabel>
{headers[key] || `Header not found ${key}`}
</FormLabel>
<FormControl>
{RetrieveInputByType({
type: value?.fieldType || "string",
props: {
className: "",
field: field,
placeholder: headers[key],
required: value?.required || false,
},
})}
</FormControl>
{String(form.formState.errors[key]?.type) ===
"invalid_type" ? (
<span id={key} className="text-red-700">
"Lütfen metinsel bir değer giriniz"
</span>
) : (
<></>
)}
</FormItem>
);
}}
/>
))}
<button type="submit" className="mt-4">
Submit
</button>
</form>
</Form>
</div>
);
};
export default CreatePageComponent;

View File

@ -0,0 +1,40 @@
"use server";
import { retrieveAvailableEndpoint } from "@/apicalls/checkEndpoint";
import { checkAccessTokenIsValid } from "@/apicalls/cookies/token";
import { decryptQuery, defaultPagination } from "@/apicalls/test";
import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations";
import { redirect } from "next/navigation";
import CreatePageComponent from "./CreatePage";
export default async function BuildingCreatePage({
searchParams,
}: {
searchParams: any;
}) {
if (!(await checkAccessTokenIsValid())) {
redirect("/login/email");
}
const buildKey = "building";
const searchParamsKeys = await searchParams;
const endpointUrl = "/building/build/create";
const queryEncrypt = await decryptQuery(searchParamsKeys?.q);
const endpointAvailable = await retrieveAvailableEndpoint(endpointUrl);
const validateAndHeaders = await retrieveHeadersAndValidationByEndpoint({
endpoint: endpointUrl,
});
const validator = validateAndHeaders?.validated || {};
const headers = validateAndHeaders?.headers || {};
console.log("validateAndHeaders", validateAndHeaders);
console.log("endpointAvailable", endpointAvailable);
console.log("queryEncrypt", queryEncrypt);
return (
<div>
<h1>Create Building</h1>
<h1>{JSON.stringify(queryEncrypt)}</h1>
<CreatePageComponent validator={validator} headers={headers} />
</div>
);
}

159
oldCode/building/page.tsx Normal file
View File

@ -0,0 +1,159 @@
"use server";
import React from "react";
import Link from "next/link";
import { redirect } from "next/navigation";
import { RefreshCcw, PlusCircle } from "lucide-react";
import {
decryptQuery,
defaultPagination,
handleFormSubmission,
} from "@/apicalls/test";
import { TableComponent } from "@/components/commons/Table";
import Pagination from "@/components/commons/pagination";
import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader";
import {
createBuild,
retrieveBuildList,
updateBuild,
} from "@/apicalls/building/build";
import {
checkAccessTokenIsValid,
retrieveUserSelection,
} from "@/apicalls/cookies/token";
import { retrievePageInfoByComponentName } from "@/hooks/retrievePageInfoByComponentName";
import { checkPageAvaliable } from "@/hooks/checkpageAvaliable";
const BuildinPage = async ({ searchParams }: { searchParams: any }) => {
const buildKey = "building";
const pageName = "BuildingPage";
const searchParamsKeys = await searchParams;
if (!searchParamsKeys?.q) {
const defaultURL = await defaultPagination();
redirect(`/${buildKey}?q=${defaultURL}`);
}
const queryEncrypt = await decryptQuery(searchParamsKeys?.q);
if (!(await checkAccessTokenIsValid())) {
redirect("/login/email");
}
const user = await retrieveUserSelection();
const tableValues = {
endpoint: "building/build/list",
name: "table",
url: "/building",
function: retrieveBuildList,
data: [],
headers: {},
validation: {},
};
const createValues = {
endpoint: "building/build/create",
name: "create",
url: "/building/create",
function: createBuild,
data: [],
headers: {},
validation: {},
};
const updateValues = {
endpoint: "building/build/update/{build_uu_id}",
function: updateBuild,
name: "update",
url: "/building/update",
data: [],
headers: {},
validation: {},
};
let restrictions: any = {
update: updateValues,
create: createValues,
table: tableValues,
};
if (!user?.lang) {
return (
<MainBodyWithHeader
children={<h1>User selection is not successfully retrieved.</h1>}
/>
);
} else {
const pageContent = retrievePageInfoByComponentName(pageName, user?.lang);
const restrictionsChecked = await checkPageAvaliable({
pageContent,
restrictions,
queryEncrypt,
});
if (!restrictionsChecked || !restrictionsChecked?.table) {
return (
<MainBodyWithHeader
children={<h1>This user does not have access to this page.</h1>}
/>
);
}
const BuildingPage = (
<div className="p-4 overflow-hidden">
<h1 className="text-2xl font-bold mb-4 ">Dashboard</h1>
<form
action={handleFormSubmission}
className="bg-white p-4 rounded-lg shadow"
>
<div className="grid gap-4">
<p>Welcome to your dashboard</p>
{restrictionsChecked?.create && (
<Link
href={"/building/create"}
className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
>
<PlusCircle size={16} />
Create
</Link>
)}
<h1>{JSON.stringify(queryEncrypt)}</h1>
{restrictionsChecked && (
<div>
<input type="hidden" name="section" value={buildKey} readOnly />
<TableComponent
pageContent={pageContent}
tableValidateAndHeaders={restrictionsChecked?.table}
apiFunction={retrieveBuildList}
redirectTo={"/building/update"}
/>
</div>
)}
<button
type="submit"
className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
>
<RefreshCcw size={16} />
Search
</button>
<Pagination
size={parseInt(queryEncrypt?.size || "10")}
page={parseInt(queryEncrypt?.page || "1")}
orderBy={queryEncrypt?.orderBy || "id"}
orderType={queryEncrypt?.orderType || "asc"}
totalPage={3}
/>
</div>
</form>
</div>
);
return (
<>
<MainBodyWithHeader
children={BuildingPage}
section={`/${buildKey}`}
profileInfo={user}
/>
</>
);
}
};
export default BuildinPage;

View File

@ -0,0 +1,55 @@
"use server";
import { redirect } from "next/navigation";
import { updateBuild } from "@/apicalls/building/build";
import { retrieveAvailableEndpoint } from "@/apicalls/checkEndpoint";
import { checkAccessTokenIsValid } from "@/apicalls/cookies/token";
import { decryptQuery, defaultPagination } from "@/apicalls/test";
import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations";
import { RetrieveInputByType } from "@/hooks/renderInputWithValidation";
import React from "react";
import UpdatePageComponent from "@/components/commons/UpdatePage";
export default async function BuildingUpdatePage({
searchParams,
}: {
searchParams: any;
}) {
if (!(await checkAccessTokenIsValid())) {
redirect("/login/email");
}
const buildKey = "building/update";
const searchParamsKeys = await searchParams;
const endpointUrl = "building/build/update/{build_uu_id}";
if (!searchParamsKeys?.q) {
redirect(`/${buildKey}`);
}
const queryEncrypt = await decryptQuery(searchParamsKeys?.q);
const endpointAvailable = await retrieveAvailableEndpoint(endpointUrl);
const validateAndHeaders = await retrieveHeadersAndValidationByEndpoint({
endpoint: endpointUrl,
});
const validator = validateAndHeaders?.validated || {};
const headers = validateAndHeaders?.headers || {};
console.log("endpointAvailable", endpointAvailable);
console.log("validator", validator);
console.log("headers", headers);
console.log("queryEncrypt", queryEncrypt);
return (
<div>
<h1>Update Building</h1>
<h1>{JSON.stringify(queryEncrypt)}</h1>
<UpdatePageComponent
validator={validator}
headers={headers}
queryEncrypt={queryEncrypt}
commitFunction={updateBuild}
/>
</div>
);
}

14
oldCode/loading.tsx Normal file
View File

@ -0,0 +1,14 @@
"use server";
export default async function Loading() {
return (
<>
<div className="flex-col items-center justify-center text-center">
<h1 className="my-8">Page is being loaded</h1>
<div className="loading-container">
<div className="spinner"></div>
</div>
</div>
</>
);
}

50
oldCode/pageTemplate.tsx Normal file
View File

@ -0,0 +1,50 @@
const BuildingPage = (
<div className="p-4 overflow-hidden">
<h1 className="text-2xl font-bold mb-4 ">Dashboard</h1>
<form
action={handleFormSubmission}
className="bg-white p-4 rounded-lg shadow"
>
<div className="grid gap-4">
<p>Welcome to your dashboard</p>
{restrictionsChecked?.create && (
<Link
href={"/building/create"}
className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
>
<PlusCircle size={16} />
Create
</Link>
)}
<h1>{JSON.stringify(queryEncrypt)}</h1>
{restrictionsChecked && (
<>
<input type="hidden" name="section" value={buildKey} readOnly />
<TableComponent
restrictions={restrictionsChecked}
query={queryEncrypt?.query || {}}
orderByValue={queryEncrypt?.orderBy || "uu_id"}
orderTypeValue={queryEncrypt?.orderType || "asc"}
/>
</>
)}
<button
type="submit"
className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
>
<RefreshCcw size={16} />
Search
</button>
<Pagination
size={parseInt(queryEncrypt?.size || "10")}
page={parseInt(queryEncrypt?.page || "1")}
orderBy={queryEncrypt?.orderBy || "id"}
orderType={queryEncrypt?.orderType || "asc"}
totalPage={3}
/>
</div>
</form>
</div>
);

View File

@ -16,23 +16,30 @@ import {
TableFooter, TableFooter,
} from "@/components/ui/table"; } from "@/components/ui/table";
import { ArrowUpDown, ArrowUp, ArrowDown } from "lucide-react";
import { getIconByName } from "@/Icons/icons"; import { getIconByName } from "@/Icons/icons";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { encryptQuery, handleUpdateSubmission } from "@/apicalls/test"; import { encryptQuery, handleUpdateSubmission } from "@/apicalls/test";
import SingleTableHeader from "./SingleTableHeader";
interface TableComponentInterFace { interface TableComponentInterFace {
restrictions: any; restrictions: any;
query: any; query: any;
orderByValue: string;
orderTypeValue: string;
} }
const TableComponent: React.FC<TableComponentInterFace> = ({ const TableComponent: React.FC<TableComponentInterFace> = ({
restrictions, restrictions,
query, query,
orderByValue,
orderTypeValue,
}) => { }) => {
const router = useRouter(); const router = useRouter();
const [updateRow, setUpdateRow] = React.useState<any>(null); const [updateRow, setUpdateRow] = React.useState<any>(null);
const [columns, setColumns] = React.useState<any[]>([]); const [columns, setColumns] = React.useState<any[]>([]);
const [orderBy, setOrderBy] = React.useState<"asc" | "desc">(
orderByValue as "asc" | "desc"
);
const [orderColumn, setOrderColumn] = React.useState<string>(orderTypeValue);
const columnHelper = createColumnHelper(); const columnHelper = createColumnHelper();
const table = useReactTable({ const table = useReactTable({
@ -82,37 +89,48 @@ const TableComponent: React.FC<TableComponentInterFace> = ({
return columns; return columns;
} }
function changeOrderState(headerID: string) {
console.log("changeOrderState", headerID, orderColumn, orderBy);
if (orderColumn === headerID) {
setOrderBy(orderBy === "asc" ? "desc" : "asc");
} else {
setOrderColumn(headerID);
setOrderBy("asc");
}
}
return ( return (
<> <>
<div className="w-full min-w-full gap-4 mb-4"> <div className="w-full min-w-full gap-4 mb-4">
<h1>{JSON.stringify(updateRow)}</h1> <h1>{JSON.stringify(updateRow)}</h1>
<input
hidden
type="text"
key="orderBy"
name="orderBy"
defaultValue={orderBy}
readOnly
/>
<input
hidden
type="text"
key="orderType"
name="orderType"
defaultValue={orderColumn}
readOnly
/>
<Table className="px-8"> <Table className="px-8">
<TableHeader> <TableHeader>
{table.getHeaderGroups().map((headerGroup) => ( {table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}> <TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => ( {headerGroup.headers.map((header) => (
<TableHead key={header.id} className="relative"> <TableHead key={header.id} className="relative">
<div className="flex items-center gap-2 w-full"> <SingleTableHeader
{/* {header.id !== "update" && ( header={header}
<ArrowUpDown orderBy={orderBy}
className="h-4 w-4 cursor-pointer" orderColumn={orderColumn}
onClick={() => changeOrderState(header.id)} changeOrderState={changeOrderState}
/> />
)} */}
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
{/* {tableInfo.field === header.id &&
header.id !== "update" &&
(tableInfo.type.startsWith("a") ? (
<ArrowUp className="absolute right-0 h-4 w-4 cursor-pointer" />
) : (
<ArrowDown className="absolute right-0 h-4 w-4 cursor-pointer" />
))} */}
</div>
</TableHead> </TableHead>
))} ))}
</TableRow> </TableRow>

BIN
public/green-house.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

View File

@ -0,0 +1,13 @@
"use server";
import React from "react";
import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader";
const Accessibilities = async () => {
return (
<div className="overflow-hidden">
<MainBodyWithHeader children={<></>} section="BuildingPage" />
</div>
);
};
export default Accessibilities;

View File

@ -1,57 +1,14 @@
"use server"; "use server";
import React from "react"; import React from "react";
import { RefreshCcw } from "lucide-react";
import Pagination from "../../components/commons/pagination";
import TableComponent from "../../components/commons/table";
import {
decryptQuery,
defaultPagination,
handleFormSubmission,
} from "@/apicalls/test";
import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader"; import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader";
import { redirect } from "next/navigation"; import AccountPage from "@/pages/Account/AccountPage";
const AccountsPage = async ({ searchParams }: { searchParams: any }) => { const Accounts = async () => {
const searchParamsKeys = await searchParams; return (
if (!searchParamsKeys?.q) { <div className="overflow-hidden">
const defaultURL = await defaultPagination(); <MainBodyWithHeader children={AccountPage} section="BuildingPage" />
redirect(`/accounts?q=${defaultURL}`);
}
const queryEncrypt = await decryptQuery(
searchParamsKeys?.q.replace(/ /g, "+")
);
const accountPage = (
<div className="p-4 overflow-hidden">
<h1 className="text-2xl font-bold mb-4 ">Dashboard</h1>
<form
action={handleFormSubmission}
className="bg-white p-4 rounded-lg shadow"
>
<div className="grid gap-4">
<p>Welcome to your dashboard</p>
<h1>{JSON.stringify(queryEncrypt)}</h1>
<input type="hidden" name="section" value="accounts" readOnly />
<TableComponent inputHeaders={queryEncrypt?.query || {}} />
<button
type="submit"
className="flex items-center justify-center gap-2 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
>
<RefreshCcw size={16} />
Search
</button>
<Pagination
size={parseInt(queryEncrypt?.size || "10")}
page={parseInt(queryEncrypt?.page || "1")}
orderBy={queryEncrypt?.orderBy || "id"}
orderType={queryEncrypt?.orderType || "asc"}
totalPage={3}
/>
</div>
</form>
</div> </div>
); );
return <MainBodyWithHeader children={accountPage} />;
}; };
export default AccountsPage; export default Accounts;

View File

@ -1,40 +1,27 @@
"use server"; "use server";
import { Suspense } from "react";
import { retrieveAvailableEndpoint } from "@/apicalls/checkEndpoint";
import { checkAccessTokenIsValid } from "@/apicalls/cookies/token";
import { decryptQuery, defaultPagination } from "@/apicalls/test";
import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations"; import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations";
import { redirect } from "next/navigation"; import { createBuild } from "@/apicalls/building/build";
import CreatePageComponent from "./CreatePage"; import CreatePageComponent from "@/components/commons/CreatePage";
export default async function BuildingCreatePage({ export default async function BuildingCreatePage() {
searchParams,
}: {
searchParams: any;
}) {
if (!(await checkAccessTokenIsValid())) {
redirect("/login/email");
}
const buildKey = "building";
const searchParamsKeys = await searchParams;
const endpointUrl = "/building/build/create"; const endpointUrl = "/building/build/create";
const queryEncrypt = await decryptQuery(searchParamsKeys?.q);
const endpointAvailable = await retrieveAvailableEndpoint(endpointUrl);
const validateAndHeaders = await retrieveHeadersAndValidationByEndpoint({ const validateAndHeaders = await retrieveHeadersAndValidationByEndpoint({
endpoint: endpointUrl, endpoint: endpointUrl,
}); });
const validator = validateAndHeaders?.validated || {}; const validator = validateAndHeaders?.validated || {};
const headers = validateAndHeaders?.headers || {}; const headers = validateAndHeaders?.headers || {};
console.log("validateAndHeaders", validateAndHeaders);
console.log("endpointAvailable", endpointAvailable);
console.log("queryEncrypt", queryEncrypt);
return ( return (
<div> <div>
<Suspense fallback={<div>Loading Create Page...</div>}>
<h1>Create Building</h1> <h1>Create Building</h1>
<h1>{JSON.stringify(queryEncrypt)}</h1> <CreatePageComponent
<CreatePageComponent validator={validator} headers={headers} /> validator={validator}
headers={headers}
saveFunction={createBuild}
pageToReturn="/building"
/>
</Suspense>
</div> </div>
); );
} }

View File

@ -1,153 +1,14 @@
"use server"; "use server";
import React, { Suspense } from "react"; import React from "react";
import Link from "next/link";
import { RefreshCcw, PlusCircle } from "lucide-react";
import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader"; import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader";
import { import BuildingPage from "@/pages/Build/BuildingPage";
decryptQuery,
defaultPagination,
handleFormSubmission,
} from "@/apicalls/test";
import { redirect } from "next/navigation";
import TableComponent from "@/components/commons/table";
import Pagination from "@/components/commons/pagination";
import {
createBuild,
retrieveBuildList,
updateBuild,
} from "@/apicalls/building/build";
import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations";
import {
checkAccessTokenIsValid,
retrieveUserSelection,
} from "@/apicalls/cookies/token";
import { retrievePageInfoByComponentName } from "@/hooks/retrievePageInfoByComponentName";
import { retrieveAvailableEndpoint } from "@/apicalls/checkEndpoint";
import { checkPageAvaliable } from "@/hooks/checkpageAvaliable";
import { logoutActiveSession } from "@/apicalls/login/logout";
const BuildinPage = async ({ searchParams }: { searchParams: any }) => { const BuildinPage = async () => {
const buildKey = "building";
const pageName = "BuildingPage";
const searchParamsKeys = await searchParams;
if (!searchParamsKeys?.q) {
const defaultURL = await defaultPagination();
redirect(`/${buildKey}?q=${defaultURL}`);
}
const queryEncrypt = await decryptQuery(searchParamsKeys?.q);
if (!(await checkAccessTokenIsValid())) {
redirect("/login/email");
}
const tableValues = {
endpoint: "building/build/list",
name: "table",
url: "/building",
function: retrieveBuildList,
data: [],
headers: {},
validation: {},
};
const createValues = {
endpoint: "building/build/create",
name: "create",
url: "/building/create",
function: createBuild,
data: [],
headers: {},
validation: {},
};
const updateValues = {
endpoint: "building/build/update/{build_uu_id}",
function: updateBuild,
name: "update",
url: "/building/update",
data: [],
headers: {},
validation: {},
};
let restrictions: any = {
update: updateValues,
create: createValues,
table: tableValues,
};
const user = await retrieveUserSelection();
if (!user?.lang) {
await logoutActiveSession({ domain: "evyos.com.tr" });
redirect("/login/email");
}
const pageContent = await retrievePageInfoByComponentName(
pageName,
user?.lang
);
const restrictionsChecked = await checkPageAvaliable({
pageContent,
restrictions,
queryEncrypt,
});
if (!restrictionsChecked || !restrictionsChecked?.table) {
redirect("/home");
}
const BuildingPage = (
<div className="p-4 overflow-hidden">
<h1 className="text-2xl font-bold mb-4 ">Dashboard</h1>
<form
action={handleFormSubmission}
className="bg-white p-4 rounded-lg shadow"
>
<div className="grid gap-4">
<p>Welcome to your dashboard</p>
{restrictionsChecked?.create && (
<Link
href={"/building/create"}
className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
>
<PlusCircle size={16} />
Create
</Link>
)}
<h1>{JSON.stringify(queryEncrypt)}</h1>
{restrictionsChecked && (
<>
<input type="hidden" name="section" value={buildKey} readOnly />
<TableComponent
restrictions={restrictionsChecked}
query={queryEncrypt?.query || {}}
/>
</>
)}
<button
type="submit"
className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
>
<RefreshCcw size={16} />
Search
</button>
<Pagination
size={parseInt(queryEncrypt?.size || "10")}
page={parseInt(queryEncrypt?.page || "1")}
orderBy={queryEncrypt?.orderBy || "id"}
orderType={queryEncrypt?.orderType || "asc"}
totalPage={3}
/>
</div>
</form>
</div>
);
return ( return (
<> <div className="overflow-hidden">
<Suspense fallback={<div>Loading...</div>}> <MainBodyWithHeader children={BuildingPage} section="BuildingPage" />
<MainBodyWithHeader children={BuildingPage} /> </div>
</Suspense>
</>
); );
}; };

View File

@ -1,63 +1,36 @@
"use server"; "use server";
import React, { Suspense } from "react";
import { updateBuild } from "@/apicalls/building/build"; import { updateBuild } from "@/apicalls/building/build";
import { retrieveAvailableEndpoint } from "@/apicalls/checkEndpoint";
import { checkAccessTokenIsValid } from "@/apicalls/cookies/token";
import { decryptQuery, defaultPagination } from "@/apicalls/test";
import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations"; import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations";
import { redirect } from "next/navigation"; import UpdatePageComponent from "@/components/commons/UpdatePage";
import { RetrieveInputByType } from "@/hooks/renderInputWithValidation";
import React from "react";
import UpdatePageComponent from "./UpdatePage";
export default async function BuildingUpdatePage({ export default async function BuildingUpdatePage({
searchParams, searchParams,
}: { }: {
searchParams: any; searchParams: any;
}) { }) {
if (!(await checkAccessTokenIsValid())) {
redirect("/login/email");
}
const buildKey = "building/update";
const searchParamsKeys = await searchParams; const searchParamsKeys = await searchParams;
const queryEncrypt = decodeURIComponent(searchParamsKeys?.data);
const queryEncryptJSON = JSON.parse(queryEncrypt);
const endpointUrl = "building/build/update/{build_uu_id}"; const endpointUrl = "building/build/update/{build_uu_id}";
if (!searchParamsKeys?.q) {
redirect(`/${buildKey}`);
}
const queryEncrypt = await decryptQuery(searchParamsKeys?.q);
const updateValues = {
endpoint: "building/build/update/{build_uu_id}",
function: updateBuild,
name: "update",
url: "/building/update",
data: [],
headers: {},
validation: {},
};
const endpointAvailable = await retrieveAvailableEndpoint(endpointUrl);
const validateAndHeaders = await retrieveHeadersAndValidationByEndpoint({ const validateAndHeaders = await retrieveHeadersAndValidationByEndpoint({
endpoint: endpointUrl, endpoint: endpointUrl,
}); });
const validator = validateAndHeaders?.validated || {}; const validator = validateAndHeaders?.validated || {};
const headers = validateAndHeaders?.headers || {}; const headers = validateAndHeaders?.headers || {};
console.log("endpointAvailable", endpointAvailable);
console.log("validator", validator);
console.log("headers", headers);
console.log("queryEncrypt", queryEncrypt);
return ( return (
<Suspense fallback={<div>Building Update Page is Loading...</div>}>
<div> <div>
<h1>Update Building</h1> <h1>Update Building</h1>
<h1>{JSON.stringify(queryEncrypt)}</h1>
<UpdatePageComponent <UpdatePageComponent
validator={validator} validator={validator}
headers={headers} headers={headers}
queryEncrypt={queryEncrypt} queryEncrypt={queryEncryptJSON || {}}
commitFunction={updateBuild}
pageToReturn="/building"
/> />
</div> </div>
</Suspense>
); );
} }

View File

@ -0,0 +1,13 @@
"use server";
import React from "react";
import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader";
const Companies = async () => {
return (
<div className="overflow-hidden">
<MainBodyWithHeader children={<></>} section="CompaniesPage" />
</div>
);
};
export default Companies;

View File

@ -0,0 +1,17 @@
"use server";
import React from "react";
interface WebPageProps {
// Add your props here if needed
}
const WebPage: React.FC<WebPageProps> = () => {
return (
<div>
<h1>Web Page</h1>
</div>
);
};
export default WebPage;

View File

@ -0,0 +1,14 @@
"use server";
import React from "react";
import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader";
import BuildingPage from "@/pages/Build/BuildingPage";
const Decision = async () => {
return (
<div className="overflow-hidden">
<MainBodyWithHeader children={BuildingPage} section="BuildingPage" />
</div>
);
};
export default Decision;

View File

@ -0,0 +1,14 @@
"use server";
import React from "react";
import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader";
import IdentitiesPage from "@/pages/Identities/IdentitiesPage";
const Identities = async () => {
return (
<div className="overflow-hidden">
<MainBodyWithHeader children={IdentitiesPage} section="IdentitiesPage" />
</div>
);
};
export default Identities;

14
src/app/loading.tsx Normal file
View File

@ -0,0 +1,14 @@
"use server";
export default async function Loading() {
return (
<>
<div className="flex-col items-center justify-center text-center">
<h1 className="my-8">Page is being loaded</h1>
<div className="loading-container">
<div className="spinner"></div>
</div>
</div>
</>
);
}

12
src/app/meetings/page.tsx Normal file
View File

@ -0,0 +1,12 @@
import React from "react";
import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader";
const Meetings = async () => {
return (
<div className="overflow-hidden">
<MainBodyWithHeader children={<></>} section="IdentitiesPage" />
</div>
);
};
export default Meetings;

View File

@ -13,49 +13,56 @@ import {
FormMessage, FormMessage,
FormDescription, FormDescription,
} from "@/components/ui/form"; } from "@/components/ui/form";
import { convertApiValidationToZodValidation } from "@/lib/renderZodValidation"; import {
convertApiValidationToZodValidation,
retrieveDataDefaults,
retrieveDataWhichHaveValidation,
} from "@/lib/renderZodValidation";
import { useRouter } from "next/navigation";
interface CreatePageComponentInterface { interface CreatePageComponentInterface {
validator: any; validator: any;
headers: any; headers: any;
saveFunction: any;
pageToReturn: string;
} }
const CreatePageComponent: React.FC<CreatePageComponentInterface> = ({ const CreatePageComponent: React.FC<CreatePageComponentInterface> = ({
validator, validator,
headers, headers,
saveFunction,
pageToReturn,
}) => { }) => {
const router = useRouter();
const returnValidation = convertApiValidationToZodValidation(validator); const returnValidation = convertApiValidationToZodValidation(validator);
const { validSchemaZod, zodValidation, apiValidation } = returnValidation; const { validSchemaZod, zodValidation, apiValidation } = returnValidation;
console.log("validSchemaZod", { const defaultValuesFromValidator = retrieveDataDefaults(validator);
validSchemaZod,
zodValidation,
apiValidation,
validator,
headers,
});
const form = useForm<z.infer<typeof validSchemaZod>>({ const form = useForm<z.infer<typeof validSchemaZod>>({
resolver: zodResolver(validSchemaZod), resolver: zodResolver(validSchemaZod),
defaultValues: {}, defaultValues: defaultValuesFromValidator,
}); });
function submitUpdate(formData: z.infer<typeof validSchemaZod>) { function submitUpdate(formData: z.infer<typeof validSchemaZod>) {
// saveFunction({ console.log("submitUpdate", {
// uu_id: updateUUID, ...retrieveDataWhichHaveValidation(formData, validator),
// payload: validDataParser(formData), });
// }).then((res: any) => { saveFunction(retrieveDataWhichHaveValidation(formData, validator)).then(
// console.log(res); (res: any) => {
// if (res?.status === 200) { console.log(res);
// } else { if (res?.status === 200) {
// alert("Güncelleme başarısız"); router.push(pageToReturn);
// } } else {
// }); alert("Güncelleme başarısız");
}
}
);
} }
return ( return (
<> <>
<div className="container mx-auto p-4"> <div className="container mx-auto p-4">
<Form {...form}> <Form {...form}>
<form action=""> <form onSubmit={form.handleSubmit(submitUpdate)}>
{Object.entries(validator).map(([key, value]: [string, any]) => ( {Object.entries(validator).map(([key, value]: [string, any]) => (
<FormField <FormField
key={key} key={key}
@ -91,8 +98,11 @@ const CreatePageComponent: React.FC<CreatePageComponentInterface> = ({
}} }}
/> />
))} ))}
<button type="submit" className="mt-4"> <button
Submit type="submit"
className="w-full mt-4 bg-green-600 hover:bg-green-700 text-white font-semibold py-2 px-4 rounded-lg transition-colors"
>
Kaydet
</button> </button>
</form> </form>
</Form> </Form>

View File

@ -0,0 +1,17 @@
"use server";
import React from "react";
interface MainPageProps {
lang: string;
RenderPage: any;
section?: string;
}
const MainPage: React.FC<MainPageProps> = async ({
lang,
section,
RenderPage,
}) => {
return <RenderPage lang={lang} section={section} />;
};
export default MainPage;

View File

@ -0,0 +1,60 @@
import { flexRender } from "@tanstack/react-table";
import { ArrowDown, ArrowUp, ArrowUpDown } from "lucide-react";
import React from "react";
interface SingleTableHeaderProps {
header: any;
orderBy: string;
orderColumn: string;
changeOrderState: React.Dispatch<React.SetStateAction<any>>;
}
const SingleTableHeader: React.FC<SingleTableHeaderProps> = ({
header,
orderBy,
orderColumn,
changeOrderState,
}) => {
const ClickeAbleArrow = (
<ArrowUpDown
className="h-4 w-4 cursor-pointer"
onClick={() => changeOrderState(String(header.id))}
/>
);
if (header.id !== "update") {
if (orderColumn === header.id) {
if (orderBy === "asc") {
return (
<div className="flex items-center gap-2 w-full">
{ClickeAbleArrow}
{flexRender(header.column.columnDef.header, header.getContext())}
<ArrowUp className="absolute right-0 h-4 w-4 cursor-pointer" />
</div>
);
} else {
return (
<div className="flex items-center gap-2 w-full">
{ClickeAbleArrow}
{flexRender(header.column.columnDef.header, header.getContext())}
<ArrowDown className="absolute right-0 h-4 w-4 cursor-pointer" />
</div>
);
}
} else {
return (
<div className="flex items-center gap-2 w-full">
{ClickeAbleArrow}
{flexRender(header.column.columnDef.header, header.getContext())}
</div>
);
}
} else {
return (
<div className="flex items-center gap-2 w-full">
{flexRender(header.column.columnDef.header, header.getContext())}
</div>
);
}
};
export default SingleTableHeader;

View File

@ -0,0 +1,267 @@
"use client";
import React, { Suspense } from "react";
import {
useReactTable,
flexRender,
getCoreRowModel,
createColumnHelper,
} from "@tanstack/react-table";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
TableFooter,
} from "@/components/ui/table";
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
import SingleTableHeader from "@/components/commons/SingleTableHeader";
import { getIconByName } from "@/Icons/icons";
import { useRouter } from "next/navigation";
interface BuildTableProps {
pageContent: any;
tableValidateAndHeaders: any;
apiFunction: any;
redirectTo: string;
}
const TableComponent: React.FC<BuildTableProps> = ({
pageContent,
tableValidateAndHeaders,
apiFunction,
redirectTo,
}) => {
const { headers } = tableValidateAndHeaders;
const router = useRouter();
const [data, setData] = React.useState<any[]>([]);
const [columns, setColumns] = React.useState<any[]>([]);
const [orderBy, setOrderBy] = React.useState<"asc" | "desc">("asc");
const [orderColumn, setOrderColumn] = React.useState<string>("uu_id");
const [page, setPage] = React.useState<number>(1);
const [size, setSize] = React.useState<number>(10);
const [totalPage, setTotalPage] = React.useState<number>(1);
const [totalCount, setTotalCount] = React.useState<number>(1);
const [query, setQuery] = React.useState<any>({});
const [currentPage, setCurrentPage] = React.useState<number>(1);
const [updateRow, setUpdateRow] = React.useState<any>(null);
const columnHelper = createColumnHelper();
const table = useReactTable({
data: data,
columns,
getCoreRowModel: getCoreRowModel(),
});
function createColumnsFromValidations(headers: any) {
const columns = Object.entries(headers).map(([key]: [string, any]) => {
return columnHelper.accessor(key, {
id: key,
footer: headers[key],
header: () => <span>{headers[key]}</span>,
cell: (info) => <span>{info.getValue()}</span>,
});
});
if (pageContent?.update) {
columns.push(
columnHelper.accessor("update", {
id: "update",
footer: "Update",
header: () => <span>Update</span>,
cell: () => (
<div className="w-8 h-8 cursor-pointer">
{pageContent?.update.icon &&
React.createElement(getIconByName(pageContent?.update.icon))}
</div>
),
})
);
}
return columns;
}
React.useEffect(() => {
if (headers) {
setColumns(createColumnsFromValidations(headers));
}
}, [headers]);
React.useEffect(() => {
if (updateRow) {
router.push(
`${redirectTo}?data=${encodeURIComponent(JSON.stringify(updateRow))}`
);
}
}, [updateRow]);
React.useEffect(() => {
apiFunction({
page,
size,
orderBy: orderColumn,
orderType: orderBy,
query: query,
}).then((res: any) => {
setData(res?.data || []);
setTotalCount(res?.data?.length || 1);
});
}, [query, page, size, orderBy, orderColumn]);
function changeOrderState(headerID: string) {
console.log("changeOrderState", headerID, orderColumn, orderBy);
if (orderColumn === headerID) {
setOrderBy(orderBy === "asc" ? "desc" : "asc");
} else {
setOrderColumn(headerID);
setOrderBy("asc");
}
}
function setActiveQueryState(footerId: string, value?: string) {
const newQuery = { ...query };
value
? (newQuery[`${footerId}__ilike`] = `%${value}%`)
: delete newQuery[`${footerId}__ilike`];
setQuery(newQuery);
}
return (
<>
<Suspense fallback={<div>Table is Loading...</div>}>
<Table className="border-2 border-black w-full h-full overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<TableHead key={header.id} className="relative">
<SingleTableHeader
header={header}
orderBy={orderBy}
orderColumn={orderColumn}
changeOrderState={changeOrderState}
/>
</TableHead>
))}
</TableRow>
))}
</TableHeader>
<Suspense fallback={<div>Table Data Loading...</div>}>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
>
{row.getVisibleCells().map((cell) =>
cell.column.id !== "update" ? (
<TableCell key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</TableCell>
) : (
<TableCell
key={cell.id}
onClick={() => setUpdateRow(row.original)}
>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</TableCell>
)
)}
</TableRow>
))
) : (
<TableRow>
<TableCell
colSpan={columns.length}
className="h-24 text-center"
>
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Suspense>
<TableFooter>
{table.getFooterGroups().map((footerGroup) => (
<TableRow key={footerGroup.id}>
{footerGroup.headers.map(
(footer) =>
footer.id !== "update" && (
<TableCell key={footer.id}>
{footer.isPlaceholder ? null : (
<input
key={footer.id}
name={footer.id}
type="text"
className="w-full text-center border p-1 text-sm h-8"
placeholder={`${String(
footer.column.columnDef.footer
)}`}
defaultValue={query[footer.id] || ""}
onChange={(e) =>
setActiveQueryState(footer.id, e.target.value)
}
/>
)}
</TableCell>
)
)}
</TableRow>
))}
</TableFooter>
</Table>
</Suspense>
<div className="flex justify-center mt-4">
<Pagination>
<PaginationContent>
{page != 1 && (
<PaginationItem>
<PaginationPrevious
onClick={page != 1 ? () => setPage(page - 1) : () => null}
/>
</PaginationItem>
)}
<PaginationItem>
<div className="flex items-center gap-2">
<PaginationLink className="select-none text-md font-bold">
{currentPage} / {totalPage}
</PaginationLink>
<PaginationLink className="select-none text-md font-bold">
| {totalCount} |
</PaginationLink>
</div>
</PaginationItem>
{page != totalPage && (
<PaginationItem>
<PaginationNext
onClick={
page != totalPage ? () => setPage(page + 1) : () => null
}
/>
</PaginationItem>
)}
</PaginationContent>
</Pagination>
</div>
</>
);
};
export { TableComponent };

View File

@ -13,29 +13,32 @@ import {
FormMessage, FormMessage,
FormDescription, FormDescription,
} from "@/components/ui/form"; } from "@/components/ui/form";
import { convertApiValidationToZodValidation } from "@/lib/renderZodValidation"; import {
convertApiValidationToZodValidation,
retrieveDataWhichHaveValidation,
} from "@/lib/renderZodValidation";
import { updateBuild } from "@/apicalls/building/build";
import { useRouter } from "next/navigation";
interface UpdatePageInterface { interface UpdatePageInterface {
validator: any; validator: any;
headers: any; headers: any;
queryEncrypt: any; queryEncrypt: any;
commitFunction: any;
pageToReturn: string;
} }
const UpdatePageComponent: React.FC<UpdatePageInterface> = ({ const UpdatePageComponent: React.FC<UpdatePageInterface> = ({
validator, validator,
headers, headers,
queryEncrypt, queryEncrypt,
commitFunction,
pageToReturn,
}) => { }) => {
const router = useRouter();
const returnValidation = convertApiValidationToZodValidation(validator); const returnValidation = convertApiValidationToZodValidation(validator);
const { validSchemaZod, zodValidation, apiValidation } = returnValidation; const { validSchemaZod, zodValidation, apiValidation } = returnValidation;
console.log("validSchemaZod", {
validSchemaZod,
zodValidation,
apiValidation,
validator,
headers,
queryEncrypt,
});
const form = useForm<z.infer<typeof validSchemaZod>>({ const form = useForm<z.infer<typeof validSchemaZod>>({
resolver: zodResolver(validSchemaZod), resolver: zodResolver(validSchemaZod),
defaultValues: { defaultValues: {
@ -45,23 +48,23 @@ const UpdatePageComponent: React.FC<UpdatePageInterface> = ({
function submitUpdate(formData: z.infer<typeof validSchemaZod>) { function submitUpdate(formData: z.infer<typeof validSchemaZod>) {
const updateUUID = queryEncrypt?.uu_id; const updateUUID = queryEncrypt?.uu_id;
// saveFunction({ commitFunction({
// uu_id: updateUUID, uu_id: updateUUID,
// payload: validDataParser(formData), payload: retrieveDataWhichHaveValidation(formData, validator),
// }).then((res: any) => { }).then((res: any) => {
// console.log(res); if (res?.status === 200) {
// if (res?.status === 200) { router.push(pageToReturn);
// } else { } else {
// alert("Güncelleme başarısız"); alert("Güncelleme başarısız");
// } }
// }); });
} }
return ( return (
<> <>
<div className="container mx-auto p-4"> <div className="container mx-auto p-4">
<Form {...form}> <Form {...form}>
<form action=""> <form onSubmit={form.handleSubmit(submitUpdate)}>
{Object.entries(validator).map(([key, value]: [string, any]) => ( {Object.entries(validator).map(([key, value]: [string, any]) => (
<FormField <FormField
key={key} key={key}
@ -80,7 +83,7 @@ const UpdatePageComponent: React.FC<UpdatePageInterface> = ({
className: "", className: "",
field: field, field: field,
placeholder: headers[key], placeholder: headers[key],
required: value?.required || false, required: value.required ? true : false,
}, },
})} })}
</FormControl> </FormControl>
@ -97,8 +100,11 @@ const UpdatePageComponent: React.FC<UpdatePageInterface> = ({
}} }}
/> />
))} ))}
<button type="submit" className="mt-4"> <button
Submit type="submit"
className="w-full mt-4 bg-green-600 hover:bg-green-700 text-white font-semibold py-2 px-4 rounded-lg transition-colors"
>
Kaydet
</button> </button>
</form> </form>
</Form> </Form>

View File

@ -57,13 +57,11 @@ const Pagination = ({
/> />
orderBy: orderBy:
<input <input
name="orderBy"
defaultValue={orderBy} defaultValue={orderBy}
className="w-16 border p-1 rounded text-center" className="w-16 border p-1 rounded text-center"
/> />
orderType: orderType:
<input <input
name="orderType"
defaultValue={orderType} defaultValue={orderType}
className="w-16 border p-1 rounded text-center" className="w-16 border p-1 rounded text-center"
/> />

View File

@ -0,0 +1,55 @@
"use client";
import React from "react";
import LogoutButton from "../login/logout";
import Link from "next/link";
const Header: React.FC = () => {
const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
return (
<div className="flex justify-between items-center p-4 bg-gray-800 text-white">
<h1>Sticky Header</h1>
<div className="relative">
<button
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
className="flex items-center space-x-2 focus:outline-none"
>
<span>Profile</span>
<svg
className="w-4 h-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M19 9l-7 7-7-7"
/>
</svg>
</button>
{isDropdownOpen && (
<div className="absolute right-0 mt-2 w-48 text-center bg-white rounded-md shadow-lg py-2 space-y-2 text-gray-700 z-50">
<Link
href="/profile"
className="block w-full px-4 py-2 hover:bg-gray-100"
>
Profile
</Link>
<Link
href="/settings"
className="block w-full px-4 py-2 hover:bg-gray-100"
>
Settings
</Link>
<hr />
<LogoutButton className="block w-full px-4 py-2 hover:bg-gray-100" />
</div>
)}
</div>
</div>
);
};
export default Header;

View File

@ -1,24 +1,45 @@
"use server"; "use server";
import React, { FC, ReactNode } from "react"; import React, { Suspense } from "react";
import SideMenu from "./SideMenu";
import SideMenuProfile from "./SideMenuProfile";
import Header from "./Header";
import MainPage from "@/components/commons/MainPage";
import { checkServerPageAvaliable } from "@/hooks/serverCheckPageAvailable";
interface MainBodyWithHeaderProps { interface MainBodyWithHeaderProps {
children: ReactNode; children: any;
section?: string;
} }
const MainBodyWithHeader: FC<MainBodyWithHeaderProps> = ({ children }) => { const MainBodyWithHeader: React.FC<MainBodyWithHeaderProps> = async ({
children,
section,
}) => {
const user = await checkServerPageAvaliable();
return ( return (
<div className="flex flex-row min-h-screen"> <div className="flex w-full h-full">
<div className="basis-1/6 flex flex-col min-h-screen bg-slate-200"> <Suspense fallback={<div>Loading Profile...</div>}>
<div className="basis-1/4 p-4 border-2 border-black">01</div> <div className="flex flex-col min-h-screen bg-slate-200">
<div className="basis-3/4 p-4 border-2 border-black">02</div> <div className="basis-1/4 p-4 border-2 border-black">
<SideMenuProfile profileInfo={user} />
</div> </div>
<div className="flex flex-col basis-5/6 min-h-screen bg-slate-300"> <div className="basis-3/4 p-4 border-2 border-black">
<div className="sticky top-0 bg-slate-500 text-white p-4 z-10 border-2 border-black"> <SideMenu activeSection={section ? section : "building"} />
<h1>Sticky Header</h1>
</div> </div>
<div className="flex-1 border-2 border-black p-6 overflow-y-auto">
{children}
</div> </div>
</Suspense>
<div className="relative flex flex-1 w-full overflow-x-hidden flex-col lg:ml-72.5">
<div className="sticky top-0 z-50">
<Header />
</div>
<main className="p-6">
<MainPage
lang={user?.lang ?? "tr"}
RenderPage={children}
section={section}
/>
</main>
</div> </div>
</div> </div>
); );

View File

@ -0,0 +1,29 @@
"use server";
import React from "react";
interface SideMenuPropsInterface {
activeSection?: string;
}
const SideMenu: React.FC<SideMenuPropsInterface> = ({ activeSection }) => {
const section = activeSection || "";
return (
<div>
<nav className="flex flex-col">
{section === "building" ? (
<a href="/building" className="w-full p-4 bg-gray-100">
Building
</a>
) : (
<span className="w-full p-4 bg-gray-500">Building</span>
)}
<a href="/profile" className="w-full p-4 hover:bg-gray-300">
Profile
</a>
</nav>
</div>
);
};
export default SideMenu;

View File

@ -0,0 +1,40 @@
"use server";
import React from "react";
import Image from "next/image";
import Link from "next/link";
interface SideMenuProfileProps {
profileInfo?: any;
}
const SideMenuProfile: React.FC<SideMenuProfileProps> = ({ profileInfo }) => {
return (
<div className="flex flex-col items-center p-4 space-y-3">
<div className="relative w-16 h-16 overflow-hidden rounded-full">
<Image
src={profileInfo?.avatar ? profileInfo?.avatar : "/green-house.webp"}
alt={`${profileInfo?.fullName || ""} profile`}
fill
className="object-cover"
/>
</div>
<div className="text-lg font-bold">
{profileInfo?.fullName ? profileInfo?.fullName : "User"}
</div>
<div className="text-sm text-gray-600">
{profileInfo?.fullName ? profileInfo?.fullName : "User"}
</div>
<div>
<Link
href="/login/select"
className="text-blue-600 hover:text-blue-800 text-sm"
>
Şirket :
{profileInfo?.occupantName ? profileInfo?.occupantName : "Change"}
</Link>
</div>
</div>
);
};
export default SideMenuProfile;

View File

@ -0,0 +1,26 @@
"use client";
import React from "react";
import { logoutActiveSession } from "@/apicalls/login/logout";
import { useRouter } from "next/navigation";
const LogoutButton: React.FC<any> = () => {
const router = useRouter();
const handleLogout = () => {
logoutActiveSession({ domain: "evyos.com.tr" }).then((res) => {
if (res) {
router.replace("/login/email");
}
});
};
return (
<button
onClick={handleLogout}
className="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600 transition-colors"
>
Logout
</button>
);
};
export default LogoutButton;

View File

@ -294,8 +294,6 @@ const TimePicker = () => {
PM_AM === "AM" ? hours : hours === 12 ? hours : hours + 12; PM_AM === "AM" ? hours : hours === 12 ? hours : hours + 12;
const formattedHours = formatIndex; const formattedHours = formatIndex;
console.log(formatIndex);
for (let j = 0; j <= 3; j++) { for (let j = 0; j <= 3; j++) {
const diff = Math.abs(j * timestamp - minutes); const diff = Math.abs(j * timestamp - minutes);
const selected = const selected =

View File

@ -1,6 +1,32 @@
"use server"; "use server";
import { retrieveAvailableEndpoint } from "@/apicalls/checkEndpoint"; import { retrieveAvailableEndpoint } from "@/apicalls/checkEndpoint";
import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations"; import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations";
import { retrievePageInfoByComponentName } from "./retrievePageInfoByComponentName";
async function checkEndpointsAvailable({
section,
lang,
}: {
section: string;
lang: string;
}) {
const pageContent = retrievePageInfoByComponentName(section as string, lang);
let newContent: any = {};
if (Array.isArray(pageContent)) {
await Promise.all(
pageContent.map(async (listItem: any) => {
const { endpoint } = listItem;
const endpointAvailable = await retrieveAvailableEndpoint(endpoint);
if (endpointAvailable) {
newContent[listItem?.name] = {
...listItem,
};
}
})
);
}
return newContent;
}
async function checkPageAvaliable({ async function checkPageAvaliable({
pageContent, pageContent,
@ -52,4 +78,4 @@ async function checkPageAvaliable({
return restrictionsList; return restrictionsList;
} }
export { checkPageAvaliable }; export { checkPageAvaliable, checkEndpointsAvailable };

View File

@ -42,11 +42,13 @@ const NumberInput = ({
<> <>
<Input <Input
required={required} required={required}
type="number"
className={cn(className || "", "")} className={cn(className || "", "")}
type="number"
{...field} {...field}
onChange={field.onChange} onChange={field.onChange}
value={field.value === 0 ? "" : field.value} value={
Number(field.value) || field.value !== 0 ? Number(field.value) : ""
}
placeholder={placeholder} placeholder={placeholder}
/> />
</> </>
@ -79,13 +81,12 @@ const DatetimeInput = ({
}: InputProps) => { }: InputProps) => {
return ( return (
<> <>
<h1></h1>
<SmartDatetimeInput <SmartDatetimeInput
required={required} required={required}
className={cn(className || "", "")} className={cn(className || "", "")}
onValueChange={field.onChange}
value={field.value ? field.value.toString() : ""}
placeholder={placeholder} placeholder={placeholder}
value={field.value}
onValueChange={field.onChange}
/> />
</> </>
); );

View File

@ -1,5 +1,14 @@
import { PagesInfosAndEndpoints } from "@/apimaps/mappingApi"; import { PagesInfosAndEndpoints } from "@/apimaps/mappingApi";
interface MainPageProps {
user: {
lang: string;
avatar: string;
fullName: string;
occupantName: string;
};
}
const retrievePageInfoByComponentName = ( const retrievePageInfoByComponentName = (
componentName: string, componentName: string,
lang: string lang: string
@ -21,7 +30,7 @@ const retrievePageInfoByComponentName = (
for (const category in PagesInfosAndEndpoints) { for (const category in PagesInfosAndEndpoints) {
const result = searchInCategory(PagesInfosAndEndpoints[category]); const result = searchInCategory(PagesInfosAndEndpoints[category]);
if (result) { if (result) {
return result; return result as MainPageProps;
} }
} }
return null; return null;

View File

@ -0,0 +1,29 @@
"use server";
import {
checkAccessTokenIsValid,
retrieveUserSelection,
} from "@/apicalls/cookies/token";
import { redirect } from "next/navigation";
interface PageAvailableReturn {
user: {
lang: string;
avatar: string;
fullName: string;
occupantName: string;
};
}
async function checkServerPageAvaliable() {
const accessValid = await checkAccessTokenIsValid();
if (!accessValid) {
redirect("/login/email");
}
const user = await retrieveUserSelection();
if (!user?.lang) {
redirect("/login/email");
}
return user;
}
export { checkServerPageAvaliable };

View File

@ -27,7 +27,7 @@ function convertApiValidationToZodValidation(apiValidation: any) {
} catch (error) { } catch (error) {
return undefined; return undefined;
} }
}, z.number().min(1)) }, z.number())
: z.preprocess((value) => { : z.preprocess((value) => {
try { try {
const parsedValue = Number(value); const parsedValue = Number(value);
@ -35,11 +35,13 @@ function convertApiValidationToZodValidation(apiValidation: any) {
} catch (error) { } catch (error) {
return undefined; return undefined;
} }
}, z.number().min(1).optional()); }, z.number().optional());
} else if (fieldType === "boolean") { } else if (fieldType === "boolean") {
zodValidation[key] = required ? z.boolean() : z.boolean().optional(); zodValidation[key] = required ? z.boolean() : z.boolean().optional();
} else if (fieldType === "datetime") { } else if (fieldType === "datetime") {
zodValidation[key] = required ? z.date() : z.date().optional(); zodValidation[key] = required
? z.coerce.date()
: z.coerce.date().optional();
} else if (fieldType === "float") { } else if (fieldType === "float") {
zodValidation[key] = required zodValidation[key] = required
? ZodDecimal.create({ coerce: true }) ? ZodDecimal.create({ coerce: true })
@ -57,8 +59,7 @@ function convertApiValidationToZodValidation(apiValidation: any) {
} }
function retrieveDataWhichHaveValidation(data: any, apiValidation: any) { function retrieveDataWhichHaveValidation(data: any, apiValidation: any) {
const apiValidated = apiValidation?.validated || {}; Object.entries(apiValidation).forEach(([key, value]: any) => {
Object.entries(apiValidated).forEach(([key, value]: any) => {
const fieldType: String = value.fieldType || "string"; const fieldType: String = value.fieldType || "string";
const required = value.required || false; const required = value.required || false;
if (fieldType === "string") { if (fieldType === "string") {
@ -68,11 +69,36 @@ function retrieveDataWhichHaveValidation(data: any, apiValidation: any) {
} else if (fieldType === "boolean") { } else if (fieldType === "boolean") {
data[key] = required ? data[key] : data[key] || false; data[key] = required ? data[key] : data[key] || false;
} else if (fieldType === "datetime") { } else if (fieldType === "datetime") {
data[key] = required ? data[key] : new Date(data[key]) || ""; data[key] = data[key] ? new Date(data[key]).toISOString() : "";
} else if (fieldType === "float") { } else if (fieldType === "float") {
data[key] = required ? data[key] : data[key] || 0.0; data[key] = required ? data[key] : data[key] || 0.0;
} }
}); });
return data;
} }
export { convertApiValidationToZodValidation, retrieveDataWhichHaveValidation }; function retrieveDataDefaults(apiValidation: any) {
let data: any = {};
Object.entries(apiValidation).forEach(([key, value]: any) => {
const fieldType: String = value.fieldType || "string";
const required = value.required || false;
if (fieldType === "string") {
data[key] = "";
} else if (fieldType === "integer") {
data[key] = 0;
} else if (fieldType === "boolean") {
data[key] = false;
} else if (fieldType === "datetime") {
data[key] = required ? new Date().toISOString() : "";
} else if (fieldType === "float") {
data[key] = 0.0;
}
});
return data;
}
export {
convertApiValidationToZodValidation,
retrieveDataWhichHaveValidation,
retrieveDataDefaults,
};

View File

@ -0,0 +1,57 @@
"use server";
import React, { Suspense } from "react";
import Link from "next/link";
import { PlusCircle } from "lucide-react";
import { checkEndpointsAvailable } from "@/hooks/checkpageAvaliable";
import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations";
import { TableComponent } from "@/components/commons/Table";
import { retrieveaccountsList } from "@/apicalls/accounts/account";
import { PagePropsInterface } from "@/schemas/PageSchema";
const AccountPage: React.FC<PagePropsInterface> = async ({ lang, section }) => {
const pageEndpoint = "/account/records/list";
const availablePageContent = await checkEndpointsAvailable({
section: section as string,
lang,
});
const tableValidateAndHeaders = await retrieveHeadersAndValidationByEndpoint({
endpoint: pageEndpoint,
});
return (
<div>
<Suspense fallback={<div>Account Page is Loading...</div>}>
<h1 className="mt-8 text-center">
{availablePageContent?.table?.title}
</h1>
<h1 className="mt-4 text-center">
{availablePageContent?.table?.description}
</h1>
<div className="my-6">
{availablePageContent?.create && (
<Link
href={"/account/records/create"}
className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
>
<PlusCircle size={16} />
Create
</Link>
)}
</div>
<div className="overflow-x-scroll my-6">
{availablePageContent?.table && (
<TableComponent
pageContent={availablePageContent}
tableValidateAndHeaders={tableValidateAndHeaders}
apiFunction={retrieveaccountsList}
redirectTo="/building/update"
/>
)}
</div>
</Suspense>
</div>
);
};
export default AccountPage;

View File

@ -1,33 +0,0 @@
"use server";
import React from "react";
const BuildChildComponent = () => {
return (
<>
<h1>Building Management</h1>
<div className="bg-white rounded-lg shadow p-6 mb-4">
<p>Building page content goes here</p>
</div>
<div className="bg-white rounded-lg shadow p-6 mb-4">
<p>More content goes here</p>
</div>
<div className="bg-white rounded-lg shadow p-6 mb-4">
<p>Building page content goes here</p>
</div>
<div className="bg-white rounded-lg shadow p-6 mb-4">
<p>More content goes here</p>
</div>
<div className="bg-white rounded-lg shadow p-6 mb-4">
<p>Building page content goes here</p>
</div>
<div className="bg-white rounded-lg shadow p-6 mb-4">
<p>More content goes here</p>
</div>
<div className="bg-white rounded-lg shadow p-6 mb-4">
<p>Even more content goes here</p>
</div>
</>
);
};
export default BuildChildComponent;

View File

@ -0,0 +1,60 @@
"use server";
import React, { Suspense } from "react";
import Link from "next/link";
import { PlusCircle } from "lucide-react";
import { checkEndpointsAvailable } from "@/hooks/checkpageAvaliable";
import { retrieveBuildList } from "@/apicalls/building/build";
import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations";
import { TableComponent } from "@/components/commons/Table";
import { PagePropsInterface } from "@/schemas/PageSchema";
const BuildingPage: React.FC<PagePropsInterface> = async ({
lang,
section,
}) => {
const pageEndpoint = "building/build/list";
const availablePageContent = await checkEndpointsAvailable({
section: section as string,
lang,
});
const tableValidateAndHeaders = await retrieveHeadersAndValidationByEndpoint({
endpoint: pageEndpoint,
});
return (
<div>
<Suspense fallback={<div>Building Page is Loading...</div>}>
<h1 className="mt-8 text-center">
{availablePageContent?.table?.title}
</h1>
<h1 className="mt-4 text-center">
{availablePageContent?.table?.description}
</h1>
<div className="my-6">
{availablePageContent?.create && (
<Link
href={"/building/create"}
className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
>
<PlusCircle size={16} />
Create
</Link>
)}
</div>
<div className="overflow-x-scroll my-6">
{availablePageContent?.table && (
<TableComponent
pageContent={availablePageContent}
tableValidateAndHeaders={tableValidateAndHeaders}
apiFunction={retrieveBuildList}
redirectTo="/building/update"
/>
)}
</div>
</Suspense>
</div>
);
};
export default BuildingPage;

View File

@ -0,0 +1,59 @@
"use server";
import React, { Suspense } from "react";
import Link from "next/link";
import { PlusCircle } from "lucide-react";
import { checkEndpointsAvailable } from "@/hooks/checkpageAvaliable";
import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations";
import { TableComponent } from "@/components/commons/Table";
import { PagePropsInterface } from "@/schemas/PageSchema";
const DecisionsPage: React.FC<PagePropsInterface> = async ({
lang,
section,
}) => {
const pageEndpoint = "/build/decision_book/list";
const availablePageContent = await checkEndpointsAvailable({
section: section as string,
lang,
});
const tableValidateAndHeaders = await retrieveHeadersAndValidationByEndpoint({
endpoint: pageEndpoint,
});
return (
<div>
<Suspense fallback={<div>Decision Book Page is Loading...</div>}>
<h1 className="mt-8 text-center">
{availablePageContent?.table?.title}
</h1>
<h1 className="mt-4 text-center">
{availablePageContent?.table?.description}
</h1>
<div className="my-6">
{availablePageContent?.create && (
<Link
href={"/building/create"}
className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
>
<PlusCircle size={16} />
Create
</Link>
)}
</div>
<div className="overflow-x-scroll my-6">
{availablePageContent?.table && (
<TableComponent
pageContent={availablePageContent}
tableValidateAndHeaders={tableValidateAndHeaders}
apiFunction={() => console.log("apiFunction")}
redirectTo="/decisions/update"
/>
)}
</div>
</Suspense>
</div>
);
};
export default DecisionsPage;

View File

@ -0,0 +1,59 @@
"use server";
import React, { Suspense } from "react";
import Link from "next/link";
import { PlusCircle } from "lucide-react";
import { checkEndpointsAvailable } from "@/hooks/checkpageAvaliable";
import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations";
import { TableComponent } from "@/components/commons/Table";
import { PagePropsInterface } from "@/schemas/PageSchema";
const IdentitiesPage: React.FC<PagePropsInterface> = async ({
lang,
section,
}) => {
const pageEndpoint = "/account/records/list";
const availablePageContent = await checkEndpointsAvailable({
section: section as string,
lang,
});
const tableValidateAndHeaders = await retrieveHeadersAndValidationByEndpoint({
endpoint: pageEndpoint,
});
return (
<div>
<Suspense fallback={<div>Account Page is Loading...</div>}>
<h1 className="mt-8 text-center">
{availablePageContent?.table?.title}
</h1>
<h1 className="mt-4 text-center">
{availablePageContent?.table?.description}
</h1>
<div className="my-6">
{availablePageContent?.create && (
<Link
href={"/account/records/create"}
className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
>
<PlusCircle size={16} />
Create
</Link>
)}
</div>
<div className="overflow-x-scroll my-6">
{availablePageContent?.table && (
<TableComponent
pageContent={availablePageContent}
tableValidateAndHeaders={tableValidateAndHeaders}
apiFunction={() => console.log("apiFunction")}
redirectTo="/building/update"
/>
)}
</div>
</Suspense>
</div>
);
};
export default IdentitiesPage;

View File

@ -0,0 +1,59 @@
"use server";
import React, { Suspense } from "react";
import Link from "next/link";
import { PlusCircle } from "lucide-react";
import { checkEndpointsAvailable } from "@/hooks/checkpageAvaliable";
import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations";
import { TableComponent } from "@/components/commons/Table";
import { PagePropsInterface } from "@/schemas/PageSchema";
const MeetingsPage: React.FC<PagePropsInterface> = async ({
lang,
section,
}) => {
const pageEndpoint = "/account/records/list";
const availablePageContent = await checkEndpointsAvailable({
section: section as string,
lang,
});
const tableValidateAndHeaders = await retrieveHeadersAndValidationByEndpoint({
endpoint: pageEndpoint,
});
return (
<div>
<Suspense fallback={<div>Meetings Page is Loading...</div>}>
<h1 className="mt-8 text-center">
{availablePageContent?.table?.title}
</h1>
<h1 className="mt-4 text-center">
{availablePageContent?.table?.description}
</h1>
<div className="my-6">
{availablePageContent?.create && (
<Link
href={"/account/records/create"}
className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
>
<PlusCircle size={16} />
Create
</Link>
)}
</div>
<div className="overflow-x-scroll my-6">
{availablePageContent?.table && (
<TableComponent
pageContent={availablePageContent}
tableValidateAndHeaders={tableValidateAndHeaders}
apiFunction={() => console.log("retrieveaccountsList")}
redirectTo="/"
/>
)}
</div>
</Suspense>
</div>
);
};
export default MeetingsPage;

View File

@ -0,0 +1,6 @@
interface PagePropsInterface {
lang: string;
section?: string;
}
export type { PagePropsInterface };