diff --git a/apicalls/basics.ts b/apicalls/basics.ts index f1b03f5..7d786b7 100644 --- a/apicalls/basics.ts +++ b/apicalls/basics.ts @@ -3,9 +3,10 @@ export const tokenSecret = process.env.TOKENSECRET || ""; export const cookieObject: any = { httpOnly: true, path: "/", - sameSite: "lax", + sameSite: "none", secure: true, maxAge: 3600, + priority: "high", }; interface FilterListInterface { @@ -34,7 +35,7 @@ class FilterList { }: FilterListInterface = {}) { this.page = page ?? 1; this.size = size ?? 5; - this.orderField = orderField ?? "id"; + this.orderField = orderField ?? "uu_id"; this.orderType = orderType ?? "asc"; this.orderType = this.orderType.startsWith("a") ? "asc" : "desc"; this.includeJoins = includeJoins ?? []; diff --git a/apicalls/building/build.tsx b/apicalls/building/build.tsx index 200cf9a..d061fcb 100644 --- a/apicalls/building/build.tsx +++ b/apicalls/building/build.tsx @@ -13,7 +13,6 @@ const buildUpdateEndpoint = `${baseUrl}/building/build/update`; async function retrieveBuildList(payload: FilterListInterface) { const feedObject = new FilterList(payload).filter(); - console.log("feedObject", feedObject); const tokenResponse: any = await fetchDataWithToken( buildListEndpoint, feedObject, @@ -41,6 +40,7 @@ async function updateBuild(payload: any) { } async function createBuild(payload: any) { + console.log("payload", payload); const tokenResponse: any = await fetchDataWithToken( buildCreateEndpoint, payload, diff --git a/apicalls/login/login.tsx b/apicalls/login/login.tsx index 916fdab..62918a0 100644 --- a/apicalls/login/login.tsx +++ b/apicalls/login/login.tsx @@ -3,7 +3,7 @@ import { fetchData, fetchDataWithToken } from "../api-fetcher"; import { cookies } from "next/headers"; import { baseUrl, cookieObject, tokenSecret } from "../basics"; import NextCrypto from "next-crypto"; -import { setAvailableEvents } from "../events/available"; +// import { setAvailableEvents } from "../events/available"; const loginEndpoint = `${baseUrl}/authentication/login`; const loginSelectEndpoint = `${baseUrl}/authentication/select`; @@ -75,11 +75,6 @@ async function loginViaAccessKeys(payload: LoginViaAccessKeys) { value: JSON.stringify(userProfile), ...cookieObject, }); - // cookieStore.set({ - // name: "userType", - // value: userType, - // ...cookieObject, - // }); } return tokenResponse; } @@ -108,7 +103,6 @@ async function loginSelectEmployee(payload: LoginSelectEmployee) { value: usersSelection, ...cookieObject, }); - await setAvailableEvents(); } return selectResponse; } @@ -143,7 +137,7 @@ async function loginSelectOccupant(payload: LoginSelectOccupant) { value: usersSelection, ...cookieObject, }); - await setAvailableEvents(); + // await setAvailableEvents(); } return selectResponse; } diff --git a/apicalls/login/logout.tsx b/apicalls/login/logout.tsx index c190208..ad016a2 100644 --- a/apicalls/login/logout.tsx +++ b/apicalls/login/logout.tsx @@ -2,6 +2,7 @@ import { fetchDataWithToken } from "../api-fetcher"; import { cookies } from "next/headers"; import { baseUrl } from "../basics"; +import { redirect } from "next/navigation"; const logOutEndpoint = `${baseUrl}/authentication/logout`; const logOutAllEndpoint = `${baseUrl}/authentication/disconnect`; @@ -11,7 +12,6 @@ interface LoginOutUser { } async function logoutActiveSession(payload: LoginOutUser) { - "use server"; const cookieStore = await cookies(); cookieStore.delete("accessToken"); cookieStore.delete("accessObject"); @@ -26,10 +26,7 @@ async function logoutActiveSession(payload: LoginOutUser) { "POST", false ); - if (tokenResponse.status === 200) { - return true; - } - return false; + return tokenResponse.status === 200 ? true : false; } async function logoutAllSessions(payload: LoginOutUser) { diff --git a/apicalls/validations/validationProcesser.ts b/apicalls/validations/validationProcesser.ts index 06af10f..582187d 100644 --- a/apicalls/validations/validationProcesser.ts +++ b/apicalls/validations/validationProcesser.ts @@ -33,7 +33,7 @@ class HeadersAndValidations { parseProcesser() { Object.entries(this.validation).map(([key, value]) => { this.validated[key] = { - required: !value.required, + required: value.required, fieldType: value?.type, }; }); diff --git a/apimaps/building/pageInfo.ts b/apimaps/building/pageInfo.ts index 8e3f3a5..6a0a32e 100644 --- a/apimaps/building/pageInfo.ts +++ b/apimaps/building/pageInfo.ts @@ -1,3 +1,5 @@ +import { url } from "inspector"; + const BuildPageInfo = { tr: [ { @@ -6,6 +8,7 @@ const BuildPageInfo = { icon: null, description: "Bina listeyebilirsiniz", endpoint: "/building/build/list", + url: "/building", component: "Table", }, { @@ -14,6 +17,7 @@ const BuildPageInfo = { name: "create", description: "Bina oluşturma sayfasına hoş geldiniz", endpoint: "/building/build/create", + url: "/building/create", component: "AddCreate2Table", }, { @@ -22,6 +26,7 @@ const BuildPageInfo = { name: "update", description: "Bina güncelleme sayfasına hoş geldiniz", endpoint: "/building/build/update/{build_uu_id}", + url: "/building/update", component: "AddUpdate2Table", }, ], @@ -31,6 +36,7 @@ const BuildPageInfo = { icon: null, description: "Welcome to the building update page", endpoint: "/building/build/list", + url: "/building", component: "Table", }, { @@ -38,6 +44,7 @@ const BuildPageInfo = { icon: "BadgePlus", description: "Welcome to the building creation page", endpoint: "/building/build/create", + url: "/building/create", component: "AddCreate2Table", }, { @@ -45,6 +52,7 @@ const BuildPageInfo = { icon: "Pencil", description: "Welcome to the building update page", endpoint: "/building/build/update/{build_uu_id}", + url: "/building/update", component: "AddUpdate2Table", }, ], diff --git a/apimaps/mappingApi.ts b/apimaps/mappingApi.ts index 8470edd..d10782a 100644 --- a/apimaps/mappingApi.ts +++ b/apimaps/mappingApi.ts @@ -30,13 +30,13 @@ const PagesInfosAndEndpoints = [ subCategories: BuildCategories, }, { - name: "", + name: "MeetingsPage", title: { tr: "Toplantılar", en: "Meetings", }, icon: "Logs", - url: "/meetings?page=1", + url: "/meetings", pageInfo: null, component: null, allEndpoints: MeetingAllEndpoints, @@ -50,7 +50,7 @@ const PagesInfosAndEndpoints = [ }, icon: "Landmark", component: "AccountPage", - url: "/accounts?page=1", + url: "/accounts", pageInfo: AccountPageInfo, allEndpoints: AccountAllEndpoints, subCategories: AccountSubCategories, @@ -63,7 +63,7 @@ const PagesInfosAndEndpoints = [ }, icon: "ScrollText", component: "DecisionBookPage", - url: "/decisions?page=1", + url: "/decisions", pageInfo: DecisionBookPageInfo, allEndpoints: DecisionBookAllEndpoints, subCategories: DecisionBookSubCategories, @@ -76,7 +76,7 @@ const PagesInfosAndEndpoints = [ }, icon: "UserPlus", component: null, - url: "/identities?page=1", + url: "/identities", pageInfo: null, allEndpoints: IdentityAllEndpoints, subCategories: IdentityCategories, @@ -89,7 +89,7 @@ const PagesInfosAndEndpoints = [ }, icon: "Cog", component: null, - url: "/accessibilities?page=1", + url: "/accessibilities", pageInfo: null, allEndpoints: AccesibleAllEndpoints, subCategories: AccesibleCategories, @@ -102,7 +102,7 @@ const PagesInfosAndEndpoints = [ }, icon: "Store", component: "CompanyPage", - url: "/companies?page=1", + url: "/companies", pageInfo: CompanyPageInfo, allEndpoints: CompanyAllEndpoints, subCategories: CompanyCategories, diff --git a/next.config.ts b/next.config.ts index e9ffa30..e4305c2 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,14 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + images: { + remotePatterns: [ + { + protocol: "https", + hostname: "s.tmimgcdn.com", + }, + ], + }, }; export default nextConfig; diff --git a/oldCode/building/create/CreatePage.tsx b/oldCode/building/create/CreatePage.tsx new file mode 100644 index 0000000..fab1786 --- /dev/null +++ b/oldCode/building/create/CreatePage.tsx @@ -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 = ({ + validator, + headers, +}) => { + const returnValidation = convertApiValidationToZodValidation(validator); + const { validSchemaZod, zodValidation, apiValidation } = returnValidation; + + const form = useForm>({ + resolver: zodResolver(validSchemaZod), + defaultValues: {}, + }); + + function submitUpdate(formData: z.infer) { + // 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 ( +
+
+ + {Object.entries(validator).map(([key, value]: [string, any]) => ( + { + return ( + + + {headers[key] || `Header not found ${key}`} + + + {RetrieveInputByType({ + type: value?.fieldType || "string", + props: { + className: "", + field: field, + placeholder: headers[key], + required: value?.required || false, + }, + })} + + {String(form.formState.errors[key]?.type) === + "invalid_type" ? ( + + "Lütfen metinsel bir değer giriniz" + + ) : ( + <> + )} + + ); + }} + /> + ))} + + + +
+ ); +}; + +export default CreatePageComponent; diff --git a/oldCode/building/create/page.tsx b/oldCode/building/create/page.tsx new file mode 100644 index 0000000..745fa8c --- /dev/null +++ b/oldCode/building/create/page.tsx @@ -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 ( +
+

Create Building

+

{JSON.stringify(queryEncrypt)}

+ +
+ ); +} diff --git a/oldCode/building/page.tsx b/oldCode/building/page.tsx new file mode 100644 index 0000000..aafb79d --- /dev/null +++ b/oldCode/building/page.tsx @@ -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 ( + User selection is not successfully retrieved.} + /> + ); + } else { + const pageContent = retrievePageInfoByComponentName(pageName, user?.lang); + const restrictionsChecked = await checkPageAvaliable({ + pageContent, + restrictions, + queryEncrypt, + }); + + if (!restrictionsChecked || !restrictionsChecked?.table) { + return ( + This user does not have access to this page.} + /> + ); + } + + const BuildingPage = ( +
+

Dashboard

+
+
+

Welcome to your dashboard

+ {restrictionsChecked?.create && ( + + + Create + + )} +

{JSON.stringify(queryEncrypt)}

+ + {restrictionsChecked && ( +
+ + +
+ )} + + + +
+
+
+ ); + return ( + <> + + + ); + } +}; + +export default BuildinPage; diff --git a/oldCode/building/update/page.tsx b/oldCode/building/update/page.tsx new file mode 100644 index 0000000..2072a1e --- /dev/null +++ b/oldCode/building/update/page.tsx @@ -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 ( +
+

Update Building

+

{JSON.stringify(queryEncrypt)}

+ + +
+ ); +} diff --git a/oldCode/loading.tsx b/oldCode/loading.tsx new file mode 100644 index 0000000..3410dea --- /dev/null +++ b/oldCode/loading.tsx @@ -0,0 +1,14 @@ +"use server"; + +export default async function Loading() { + return ( + <> +
+

Page is being loaded

+
+
+
+
+ + ); +} diff --git a/oldCode/pageTemplate.tsx b/oldCode/pageTemplate.tsx new file mode 100644 index 0000000..c5f8747 --- /dev/null +++ b/oldCode/pageTemplate.tsx @@ -0,0 +1,50 @@ +const BuildingPage = ( +
+

Dashboard

+
+
+

Welcome to your dashboard

+ {restrictionsChecked?.create && ( + + + Create + + )} +

{JSON.stringify(queryEncrypt)}

+ + {restrictionsChecked && ( + <> + + + + )} + + + +
+
+
+ ); \ No newline at end of file diff --git a/src/components/commons/table.tsx b/oldCode/table.tsx similarity index 81% rename from src/components/commons/table.tsx rename to oldCode/table.tsx index 9c23aa6..9df1755 100644 --- a/src/components/commons/table.tsx +++ b/oldCode/table.tsx @@ -16,23 +16,30 @@ import { TableFooter, } from "@/components/ui/table"; -import { ArrowUpDown, ArrowUp, ArrowDown } from "lucide-react"; import { getIconByName } from "@/Icons/icons"; import { useRouter } from "next/navigation"; import { encryptQuery, handleUpdateSubmission } from "@/apicalls/test"; +import SingleTableHeader from "./SingleTableHeader"; interface TableComponentInterFace { restrictions: any; query: any; + orderByValue: string; + orderTypeValue: string; } - const TableComponent: React.FC = ({ restrictions, query, + orderByValue, + orderTypeValue, }) => { const router = useRouter(); const [updateRow, setUpdateRow] = React.useState(null); const [columns, setColumns] = React.useState([]); + const [orderBy, setOrderBy] = React.useState<"asc" | "desc">( + orderByValue as "asc" | "desc" + ); + const [orderColumn, setOrderColumn] = React.useState(orderTypeValue); const columnHelper = createColumnHelper(); const table = useReactTable({ @@ -82,37 +89,48 @@ const TableComponent: React.FC = ({ 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 ( <>

{JSON.stringify(updateRow)}

+ + {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( -
- {/* {header.id !== "update" && ( - changeOrderState(header.id)} - /> - )} */} - {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext() - )} - {/* {tableInfo.field === header.id && - header.id !== "update" && - (tableInfo.type.startsWith("a") ? ( - - ) : ( - - ))} */} -
+
))}
diff --git a/public/green-house.webp b/public/green-house.webp new file mode 100644 index 0000000..30d3ce5 Binary files /dev/null and b/public/green-house.webp differ diff --git a/src/app/accessibilities/page.tsx b/src/app/accessibilities/page.tsx new file mode 100644 index 0000000..f56ce76 --- /dev/null +++ b/src/app/accessibilities/page.tsx @@ -0,0 +1,13 @@ +"use server"; +import React from "react"; +import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader"; + +const Accessibilities = async () => { + return ( +
+ } section="BuildingPage" /> +
+ ); +}; + +export default Accessibilities; diff --git a/src/app/accounts/page.tsx b/src/app/accounts/page.tsx index a051f28..94ecd3d 100644 --- a/src/app/accounts/page.tsx +++ b/src/app/accounts/page.tsx @@ -1,57 +1,14 @@ "use server"; 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 { redirect } from "next/navigation"; +import AccountPage from "@/pages/Account/AccountPage"; -const AccountsPage = async ({ searchParams }: { searchParams: any }) => { - const searchParamsKeys = await searchParams; - if (!searchParamsKeys?.q) { - const defaultURL = await defaultPagination(); - redirect(`/accounts?q=${defaultURL}`); - } - const queryEncrypt = await decryptQuery( - searchParamsKeys?.q.replace(/ /g, "+") - ); - - const accountPage = ( -
-

Dashboard

-
-
-

Welcome to your dashboard

-

{JSON.stringify(queryEncrypt)}

- - - - -
- +const Accounts = async () => { + return ( +
+
); - return ; }; -export default AccountsPage; +export default Accounts; diff --git a/src/app/building/create/page.tsx b/src/app/building/create/page.tsx index 745fa8c..fa7e079 100644 --- a/src/app/building/create/page.tsx +++ b/src/app/building/create/page.tsx @@ -1,40 +1,27 @@ "use server"; - -import { retrieveAvailableEndpoint } from "@/apicalls/checkEndpoint"; -import { checkAccessTokenIsValid } from "@/apicalls/cookies/token"; -import { decryptQuery, defaultPagination } from "@/apicalls/test"; +import { Suspense } from "react"; import { retrieveHeadersAndValidationByEndpoint } from "@/apicalls/validations/validations"; -import { redirect } from "next/navigation"; -import CreatePageComponent from "./CreatePage"; +import { createBuild } from "@/apicalls/building/build"; +import CreatePageComponent from "@/components/commons/CreatePage"; -export default async function BuildingCreatePage({ - searchParams, -}: { - searchParams: any; -}) { - if (!(await checkAccessTokenIsValid())) { - redirect("/login/email"); - } - - const buildKey = "building"; - const searchParamsKeys = await searchParams; +export default async function BuildingCreatePage() { 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 (
-

Create Building

-

{JSON.stringify(queryEncrypt)}

- + Loading Create Page...
}> +

Create Building

+ +
); } diff --git a/src/app/building/page.tsx b/src/app/building/page.tsx index b4bfec9..b9cdadb 100644 --- a/src/app/building/page.tsx +++ b/src/app/building/page.tsx @@ -1,153 +1,14 @@ "use server"; -import React, { Suspense } from "react"; -import Link from "next/link"; -import { RefreshCcw, PlusCircle } from "lucide-react"; +import React from "react"; import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader"; -import { - 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"; +import BuildingPage from "@/pages/Build/BuildingPage"; -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 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 = ( -
-

Dashboard

-
-
-

Welcome to your dashboard

- {restrictionsChecked?.create && ( - - - Create - - )} -

{JSON.stringify(queryEncrypt)}

- - {restrictionsChecked && ( - <> - - - - )} - - - -
- -
- ); +const BuildinPage = async () => { return ( - <> - Loading...}> - - - +
+ +
); }; diff --git a/src/app/building/update/page.tsx b/src/app/building/update/page.tsx index eeaf986..5704f3d 100644 --- a/src/app/building/update/page.tsx +++ b/src/app/building/update/page.tsx @@ -1,63 +1,36 @@ "use server"; +import React, { Suspense } from "react"; 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 { redirect } from "next/navigation"; -import { RetrieveInputByType } from "@/hooks/renderInputWithValidation"; - -import React from "react"; -import UpdatePageComponent from "./UpdatePage"; +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 queryEncrypt = decodeURIComponent(searchParamsKeys?.data); + const queryEncryptJSON = JSON.parse(queryEncrypt); 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({ 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 ( -
-

Update Building

-

{JSON.stringify(queryEncrypt)}

- - - -
+ Building Update Page is Loading...}> +
+

Update Building

+ +
+
); } diff --git a/src/app/companies/page.tsx b/src/app/companies/page.tsx new file mode 100644 index 0000000..e01ffd5 --- /dev/null +++ b/src/app/companies/page.tsx @@ -0,0 +1,13 @@ +"use server"; +import React from "react"; +import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader"; + +const Companies = async () => { + return ( +
+ } section="CompaniesPage" /> +
+ ); +}; + +export default Companies; diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx new file mode 100644 index 0000000..86a4eee --- /dev/null +++ b/src/app/dashboard/page.tsx @@ -0,0 +1,17 @@ +"use server"; + +import React from "react"; + +interface WebPageProps { + // Add your props here if needed +} + +const WebPage: React.FC = () => { + return ( +
+

Web Page

+
+ ); +}; + +export default WebPage; diff --git a/src/app/decisions/page.tsx b/src/app/decisions/page.tsx new file mode 100644 index 0000000..47a946a --- /dev/null +++ b/src/app/decisions/page.tsx @@ -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 ( +
+ +
+ ); +}; + +export default Decision; diff --git a/src/app/identities/page.tsx b/src/app/identities/page.tsx new file mode 100644 index 0000000..b43b192 --- /dev/null +++ b/src/app/identities/page.tsx @@ -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 ( +
+ +
+ ); +}; + +export default Identities; diff --git a/src/app/loading.tsx b/src/app/loading.tsx new file mode 100644 index 0000000..3410dea --- /dev/null +++ b/src/app/loading.tsx @@ -0,0 +1,14 @@ +"use server"; + +export default async function Loading() { + return ( + <> +
+

Page is being loaded

+
+
+
+
+ + ); +} diff --git a/src/app/meetings/page.tsx b/src/app/meetings/page.tsx new file mode 100644 index 0000000..c2a8441 --- /dev/null +++ b/src/app/meetings/page.tsx @@ -0,0 +1,12 @@ +import React from "react"; +import MainBodyWithHeader from "@/components/defaultLayout/MainBodyWithHeader"; + +const Meetings = async () => { + return ( +
+ } section="IdentitiesPage" /> +
+ ); +}; + +export default Meetings; diff --git a/src/app/building/create/CreatePage.tsx b/src/components/commons/CreatePage.tsx similarity index 69% rename from src/app/building/create/CreatePage.tsx rename to src/components/commons/CreatePage.tsx index 9e6836f..49429c8 100644 --- a/src/app/building/create/CreatePage.tsx +++ b/src/components/commons/CreatePage.tsx @@ -13,49 +13,56 @@ import { FormMessage, FormDescription, } from "@/components/ui/form"; -import { convertApiValidationToZodValidation } from "@/lib/renderZodValidation"; +import { + convertApiValidationToZodValidation, + retrieveDataDefaults, + retrieveDataWhichHaveValidation, +} from "@/lib/renderZodValidation"; +import { useRouter } from "next/navigation"; interface CreatePageComponentInterface { validator: any; headers: any; + saveFunction: any; + pageToReturn: string; } const CreatePageComponent: React.FC = ({ validator, headers, + saveFunction, + pageToReturn, }) => { + const router = useRouter(); const returnValidation = convertApiValidationToZodValidation(validator); const { validSchemaZod, zodValidation, apiValidation } = returnValidation; - console.log("validSchemaZod", { - validSchemaZod, - zodValidation, - apiValidation, - validator, - headers, - }); + const defaultValuesFromValidator = retrieveDataDefaults(validator); const form = useForm>({ resolver: zodResolver(validSchemaZod), - defaultValues: {}, + defaultValues: defaultValuesFromValidator, }); function submitUpdate(formData: z.infer) { - // 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"); - // } - // }); + console.log("submitUpdate", { + ...retrieveDataWhichHaveValidation(formData, validator), + }); + saveFunction(retrieveDataWhichHaveValidation(formData, validator)).then( + (res: any) => { + console.log(res); + if (res?.status === 200) { + router.push(pageToReturn); + } else { + alert("Güncelleme başarısız"); + } + } + ); } return ( <>
- + {Object.entries(validator).map(([key, value]: [string, any]) => ( = ({ }} /> ))} - diff --git a/src/components/commons/MainPage.tsx b/src/components/commons/MainPage.tsx new file mode 100644 index 0000000..d04a2c3 --- /dev/null +++ b/src/components/commons/MainPage.tsx @@ -0,0 +1,17 @@ +"use server"; +import React from "react"; +interface MainPageProps { + lang: string; + RenderPage: any; + section?: string; +} + +const MainPage: React.FC = async ({ + lang, + section, + RenderPage, +}) => { + return ; +}; + +export default MainPage; diff --git a/src/components/commons/SingleTableHeader.tsx b/src/components/commons/SingleTableHeader.tsx new file mode 100644 index 0000000..00346d3 --- /dev/null +++ b/src/components/commons/SingleTableHeader.tsx @@ -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>; +} + +const SingleTableHeader: React.FC = ({ + header, + orderBy, + orderColumn, + changeOrderState, +}) => { + const ClickeAbleArrow = ( + changeOrderState(String(header.id))} + /> + ); + if (header.id !== "update") { + if (orderColumn === header.id) { + if (orderBy === "asc") { + return ( +
+ {ClickeAbleArrow} + {flexRender(header.column.columnDef.header, header.getContext())} + +
+ ); + } else { + return ( +
+ {ClickeAbleArrow} + {flexRender(header.column.columnDef.header, header.getContext())} + +
+ ); + } + } else { + return ( +
+ {ClickeAbleArrow} + {flexRender(header.column.columnDef.header, header.getContext())} +
+ ); + } + } else { + return ( +
+ {flexRender(header.column.columnDef.header, header.getContext())} +
+ ); + } +}; + +export default SingleTableHeader; diff --git a/src/components/commons/Table.tsx b/src/components/commons/Table.tsx new file mode 100644 index 0000000..d4092a3 --- /dev/null +++ b/src/components/commons/Table.tsx @@ -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 = ({ + pageContent, + tableValidateAndHeaders, + apiFunction, + redirectTo, +}) => { + const { headers } = tableValidateAndHeaders; + const router = useRouter(); + + const [data, setData] = React.useState([]); + const [columns, setColumns] = React.useState([]); + + const [orderBy, setOrderBy] = React.useState<"asc" | "desc">("asc"); + const [orderColumn, setOrderColumn] = React.useState("uu_id"); + const [page, setPage] = React.useState(1); + const [size, setSize] = React.useState(10); + const [totalPage, setTotalPage] = React.useState(1); + const [totalCount, setTotalCount] = React.useState(1); + const [query, setQuery] = React.useState({}); + const [currentPage, setCurrentPage] = React.useState(1); + + const [updateRow, setUpdateRow] = React.useState(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: () => {headers[key]}, + cell: (info) => {info.getValue()}, + }); + }); + if (pageContent?.update) { + columns.push( + columnHelper.accessor("update", { + id: "update", + footer: "Update", + header: () => Update, + cell: () => ( +
+ {pageContent?.update.icon && + React.createElement(getIconByName(pageContent?.update.icon))} +
+ ), + }) + ); + } + 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 ( + <> + Table is Loading...
}> +
+ + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + + + ))} + + ))} + + Table Data Loading...}> + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => + cell.column.id !== "update" ? ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ) : ( + setUpdateRow(row.original)} + > + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ) + )} + + )) + ) : ( + + + No results. + + + )} + + + + {table.getFooterGroups().map((footerGroup) => ( + + {footerGroup.headers.map( + (footer) => + footer.id !== "update" && ( + + {footer.isPlaceholder ? null : ( + + setActiveQueryState(footer.id, e.target.value) + } + /> + )} + + ) + )} + + ))} + +
+ +
+ + + {page != 1 && ( + + setPage(page - 1) : () => null} + /> + + )} + +
+ + {currentPage} / {totalPage} + + + | {totalCount} | + +
+
+ {page != totalPage && ( + + setPage(page + 1) : () => null + } + /> + + )} +
+
+
+ + ); +}; + +export { TableComponent }; diff --git a/src/app/building/update/UpdatePage.tsx b/src/components/commons/UpdatePage.tsx similarity index 72% rename from src/app/building/update/UpdatePage.tsx rename to src/components/commons/UpdatePage.tsx index ff4cd34..b416c89 100644 --- a/src/app/building/update/UpdatePage.tsx +++ b/src/components/commons/UpdatePage.tsx @@ -13,29 +13,32 @@ import { FormMessage, FormDescription, } 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 { validator: any; headers: any; queryEncrypt: any; + commitFunction: any; + pageToReturn: string; } const UpdatePageComponent: React.FC = ({ validator, headers, queryEncrypt, + commitFunction, + pageToReturn, }) => { + const router = useRouter(); const returnValidation = convertApiValidationToZodValidation(validator); const { validSchemaZod, zodValidation, apiValidation } = returnValidation; - console.log("validSchemaZod", { - validSchemaZod, - zodValidation, - apiValidation, - validator, - headers, - queryEncrypt, - }); + const form = useForm>({ resolver: zodResolver(validSchemaZod), defaultValues: { @@ -45,23 +48,23 @@ const UpdatePageComponent: React.FC = ({ function submitUpdate(formData: z.infer) { const updateUUID = queryEncrypt?.uu_id; - // 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"); - // } - // }); + commitFunction({ + uu_id: updateUUID, + payload: retrieveDataWhichHaveValidation(formData, validator), + }).then((res: any) => { + if (res?.status === 200) { + router.push(pageToReturn); + } else { + alert("Güncelleme başarısız"); + } + }); } return ( <>
- + {Object.entries(validator).map(([key, value]: [string, any]) => ( = ({ className: "", field: field, placeholder: headers[key], - required: value?.required || false, + required: value.required ? true : false, }, })} @@ -97,8 +100,11 @@ const UpdatePageComponent: React.FC = ({ }} /> ))} - diff --git a/src/components/commons/pagination.tsx b/src/components/commons/pagination.tsx index fedbd42..8f02d74 100644 --- a/src/components/commons/pagination.tsx +++ b/src/components/commons/pagination.tsx @@ -57,13 +57,11 @@ const Pagination = ({ /> orderBy: orderType: diff --git a/src/components/defaultLayout/Header.tsx b/src/components/defaultLayout/Header.tsx new file mode 100644 index 0000000..0795b8a --- /dev/null +++ b/src/components/defaultLayout/Header.tsx @@ -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 ( +
+

Sticky Header

+
+ + {isDropdownOpen && ( +
+ + Profile + + + Settings + +
+ +
+ )} +
+
+ ); +}; + +export default Header; diff --git a/src/components/defaultLayout/MainBodyWithHeader.tsx b/src/components/defaultLayout/MainBodyWithHeader.tsx index 52c89d3..54c9d13 100644 --- a/src/components/defaultLayout/MainBodyWithHeader.tsx +++ b/src/components/defaultLayout/MainBodyWithHeader.tsx @@ -1,24 +1,45 @@ "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 { - children: ReactNode; + children: any; + section?: string; } -const MainBodyWithHeader: FC = ({ children }) => { +const MainBodyWithHeader: React.FC = async ({ + children, + section, +}) => { + const user = await checkServerPageAvaliable(); return ( -
-
-
01
-
02
-
-
-
-

Sticky Header

+
+ Loading Profile...
}> +
+
+ +
+
+ +
-
- {children} + +
+
+
+
+ +
); diff --git a/src/components/defaultLayout/SideMenu.tsx b/src/components/defaultLayout/SideMenu.tsx new file mode 100644 index 0000000..10ccbed --- /dev/null +++ b/src/components/defaultLayout/SideMenu.tsx @@ -0,0 +1,29 @@ +"use server"; +import React from "react"; + +interface SideMenuPropsInterface { + activeSection?: string; +} + +const SideMenu: React.FC = ({ activeSection }) => { + const section = activeSection || ""; + return ( +
+ +
+ ); +}; + +export default SideMenu; diff --git a/src/components/defaultLayout/SideMenuProfile.tsx b/src/components/defaultLayout/SideMenuProfile.tsx new file mode 100644 index 0000000..99d7669 --- /dev/null +++ b/src/components/defaultLayout/SideMenuProfile.tsx @@ -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 = ({ profileInfo }) => { + return ( +
+
+ {`${profileInfo?.fullName +
+
+ {profileInfo?.fullName ? profileInfo?.fullName : "User"} +
+
+ {profileInfo?.fullName ? profileInfo?.fullName : "User"} +
+
+ + Şirket : + {profileInfo?.occupantName ? profileInfo?.occupantName : "Change"} + +
+
+ ); +}; + +export default SideMenuProfile; diff --git a/src/components/login/logout.tsx b/src/components/login/logout.tsx new file mode 100644 index 0000000..0780c0e --- /dev/null +++ b/src/components/login/logout.tsx @@ -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 = () => { + const router = useRouter(); + const handleLogout = () => { + logoutActiveSession({ domain: "evyos.com.tr" }).then((res) => { + if (res) { + router.replace("/login/email"); + } + }); + }; + + return ( + + ); +}; + +export default LogoutButton; diff --git a/src/components/ui/smart-datetime-input.tsx b/src/components/ui/smart-datetime-input.tsx index e69aafb..92d8a53 100644 --- a/src/components/ui/smart-datetime-input.tsx +++ b/src/components/ui/smart-datetime-input.tsx @@ -294,8 +294,6 @@ const TimePicker = () => { PM_AM === "AM" ? hours : hours === 12 ? hours : hours + 12; const formattedHours = formatIndex; - console.log(formatIndex); - for (let j = 0; j <= 3; j++) { const diff = Math.abs(j * timestamp - minutes); const selected = diff --git a/src/hooks/checkpageAvaliable.tsx b/src/hooks/checkpageAvaliable.tsx index efa245c..474bd6c 100644 --- a/src/hooks/checkpageAvaliable.tsx +++ b/src/hooks/checkpageAvaliable.tsx @@ -1,6 +1,32 @@ "use server"; import { retrieveAvailableEndpoint } from "@/apicalls/checkEndpoint"; 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({ pageContent, @@ -52,4 +78,4 @@ async function checkPageAvaliable({ return restrictionsList; } -export { checkPageAvaliable }; +export { checkPageAvaliable, checkEndpointsAvailable }; diff --git a/src/hooks/renderInputWithValidation.tsx b/src/hooks/renderInputWithValidation.tsx index 4653cfe..6aa2f58 100644 --- a/src/hooks/renderInputWithValidation.tsx +++ b/src/hooks/renderInputWithValidation.tsx @@ -42,11 +42,13 @@ const NumberInput = ({ <> @@ -79,13 +81,12 @@ const DatetimeInput = ({ }: InputProps) => { return ( <> -

); diff --git a/src/hooks/retrievePageInfoByComponentName.tsx b/src/hooks/retrievePageInfoByComponentName.tsx index 65f4fac..3a44af7 100644 --- a/src/hooks/retrievePageInfoByComponentName.tsx +++ b/src/hooks/retrievePageInfoByComponentName.tsx @@ -1,5 +1,14 @@ import { PagesInfosAndEndpoints } from "@/apimaps/mappingApi"; +interface MainPageProps { + user: { + lang: string; + avatar: string; + fullName: string; + occupantName: string; + }; +} + const retrievePageInfoByComponentName = ( componentName: string, lang: string @@ -21,7 +30,7 @@ const retrievePageInfoByComponentName = ( for (const category in PagesInfosAndEndpoints) { const result = searchInCategory(PagesInfosAndEndpoints[category]); if (result) { - return result; + return result as MainPageProps; } } return null; diff --git a/src/hooks/serverCheckPageAvailable.tsx b/src/hooks/serverCheckPageAvailable.tsx new file mode 100644 index 0000000..f2f1828 --- /dev/null +++ b/src/hooks/serverCheckPageAvailable.tsx @@ -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 }; diff --git a/src/lib/renderZodValidation.ts b/src/lib/renderZodValidation.ts index c8b3a7c..f44fc88 100644 --- a/src/lib/renderZodValidation.ts +++ b/src/lib/renderZodValidation.ts @@ -27,7 +27,7 @@ function convertApiValidationToZodValidation(apiValidation: any) { } catch (error) { return undefined; } - }, z.number().min(1)) + }, z.number()) : z.preprocess((value) => { try { const parsedValue = Number(value); @@ -35,11 +35,13 @@ function convertApiValidationToZodValidation(apiValidation: any) { } catch (error) { return undefined; } - }, z.number().min(1).optional()); + }, z.number().optional()); } else if (fieldType === "boolean") { zodValidation[key] = required ? z.boolean() : z.boolean().optional(); } 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") { zodValidation[key] = required ? ZodDecimal.create({ coerce: true }) @@ -57,8 +59,7 @@ function convertApiValidationToZodValidation(apiValidation: any) { } function retrieveDataWhichHaveValidation(data: any, apiValidation: any) { - const apiValidated = apiValidation?.validated || {}; - Object.entries(apiValidated).forEach(([key, value]: any) => { + Object.entries(apiValidation).forEach(([key, value]: any) => { const fieldType: String = value.fieldType || "string"; const required = value.required || false; if (fieldType === "string") { @@ -68,11 +69,36 @@ function retrieveDataWhichHaveValidation(data: any, apiValidation: any) { } else if (fieldType === "boolean") { data[key] = required ? data[key] : data[key] || false; } 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") { 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, +}; diff --git a/src/pages/Account/AccountPage.tsx b/src/pages/Account/AccountPage.tsx new file mode 100644 index 0000000..c158f84 --- /dev/null +++ b/src/pages/Account/AccountPage.tsx @@ -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 = async ({ lang, section }) => { + const pageEndpoint = "/account/records/list"; + const availablePageContent = await checkEndpointsAvailable({ + section: section as string, + lang, + }); + const tableValidateAndHeaders = await retrieveHeadersAndValidationByEndpoint({ + endpoint: pageEndpoint, + }); + + return ( +
+ Account Page is Loading...
}> +

+ {availablePageContent?.table?.title} +

+

+ {availablePageContent?.table?.description} +

+
+ {availablePageContent?.create && ( + + + Create + + )} +
+
+ {availablePageContent?.table && ( + + )} +
+ +
+ ); +}; + +export default AccountPage; diff --git a/src/pages/Build/Build.tsx b/src/pages/Build/Build.tsx deleted file mode 100644 index ad50b43..0000000 --- a/src/pages/Build/Build.tsx +++ /dev/null @@ -1,33 +0,0 @@ -"use server"; -import React from "react"; - -const BuildChildComponent = () => { - return ( - <> -

Building Management

-
-

Building page content goes here

-
-
-

More content goes here

-
-
-

Building page content goes here

-
-
-

More content goes here

-
-
-

Building page content goes here

-
-
-

More content goes here

-
-
-

Even more content goes here

-
- - ); -}; - -export default BuildChildComponent; diff --git a/src/pages/Build/BuildingPage.tsx b/src/pages/Build/BuildingPage.tsx new file mode 100644 index 0000000..0d94dcb --- /dev/null +++ b/src/pages/Build/BuildingPage.tsx @@ -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 = async ({ + lang, + section, +}) => { + const pageEndpoint = "building/build/list"; + const availablePageContent = await checkEndpointsAvailable({ + section: section as string, + lang, + }); + const tableValidateAndHeaders = await retrieveHeadersAndValidationByEndpoint({ + endpoint: pageEndpoint, + }); + + return ( +
+ Building Page is Loading...
}> +

+ {availablePageContent?.table?.title} +

+

+ {availablePageContent?.table?.description} +

+
+ {availablePageContent?.create && ( + + + Create + + )} +
+
+ {availablePageContent?.table && ( + + )} +
+ +
+ ); +}; + +export default BuildingPage; diff --git a/src/pages/Decisions/DecisionsPage.tsx b/src/pages/Decisions/DecisionsPage.tsx new file mode 100644 index 0000000..14ea70c --- /dev/null +++ b/src/pages/Decisions/DecisionsPage.tsx @@ -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 = 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 ( +
+ Decision Book Page is Loading...
}> +

+ {availablePageContent?.table?.title} +

+

+ {availablePageContent?.table?.description} +

+
+ {availablePageContent?.create && ( + + + Create + + )} +
+
+ {availablePageContent?.table && ( + console.log("apiFunction")} + redirectTo="/decisions/update" + /> + )} +
+ +
+ ); +}; + +export default DecisionsPage; diff --git a/src/pages/Identities/IdentitiesPage.tsx b/src/pages/Identities/IdentitiesPage.tsx new file mode 100644 index 0000000..f8aabd7 --- /dev/null +++ b/src/pages/Identities/IdentitiesPage.tsx @@ -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 = async ({ + lang, + section, +}) => { + const pageEndpoint = "/account/records/list"; + const availablePageContent = await checkEndpointsAvailable({ + section: section as string, + lang, + }); + const tableValidateAndHeaders = await retrieveHeadersAndValidationByEndpoint({ + endpoint: pageEndpoint, + }); + + return ( +
+ Account Page is Loading...
}> +

+ {availablePageContent?.table?.title} +

+

+ {availablePageContent?.table?.description} +

+
+ {availablePageContent?.create && ( + + + Create + + )} +
+
+ {availablePageContent?.table && ( + console.log("apiFunction")} + redirectTo="/building/update" + /> + )} +
+ +
+ ); +}; + +export default IdentitiesPage; diff --git a/src/pages/Meetings/MeetingsPage.tsx b/src/pages/Meetings/MeetingsPage.tsx new file mode 100644 index 0000000..758c570 --- /dev/null +++ b/src/pages/Meetings/MeetingsPage.tsx @@ -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 = async ({ + lang, + section, +}) => { + const pageEndpoint = "/account/records/list"; + const availablePageContent = await checkEndpointsAvailable({ + section: section as string, + lang, + }); + const tableValidateAndHeaders = await retrieveHeadersAndValidationByEndpoint({ + endpoint: pageEndpoint, + }); + + return ( +
+ Meetings Page is Loading...
}> +

+ {availablePageContent?.table?.title} +

+

+ {availablePageContent?.table?.description} +

+
+ {availablePageContent?.create && ( + + + Create + + )} +
+
+ {availablePageContent?.table && ( + console.log("retrieveaccountsList")} + redirectTo="/" + /> + )} +
+ +
+ ); +}; + +export default MeetingsPage; diff --git a/src/schemas/PageSchema.ts b/src/schemas/PageSchema.ts new file mode 100644 index 0000000..079a295 --- /dev/null +++ b/src/schemas/PageSchema.ts @@ -0,0 +1,6 @@ +interface PagePropsInterface { + lang: string; + section?: string; +} + +export type { PagePropsInterface };