From 05f3e019a877b74daccf18f8710f82c480b7be5b Mon Sep 17 00:00:00 2001 From: Thanu Poptiphueng Date: Thu, 16 May 2024 12:50:14 +0700 Subject: [PATCH] added location element --- app/grouping/page.tsx | 14 +++++ components/LocationSelector/index.tsx | 76 +++++++++++++++++++++++++++ components/locationContenxt.tsx | 32 +++++++++++ tsconfig.json | 34 +++++------- 4 files changed, 135 insertions(+), 21 deletions(-) create mode 100644 components/LocationSelector/index.tsx create mode 100644 components/locationContenxt.tsx diff --git a/app/grouping/page.tsx b/app/grouping/page.tsx index e69de29..7920bd4 100644 --- a/app/grouping/page.tsx +++ b/app/grouping/page.tsx @@ -0,0 +1,14 @@ +import { db } from "@/src/db"; +import LocationSelector from "../../components/LocationSelector"; +import LocationContextProvider from "@/components/locationContenxt"; + +export default async function Page() { + let provinces = await db.query.province + .findMany({ with: { zones: true } }) + .execute(); + return ( + + + + ); +} diff --git a/components/LocationSelector/index.tsx b/components/LocationSelector/index.tsx new file mode 100644 index 0000000..b5be462 --- /dev/null +++ b/components/LocationSelector/index.tsx @@ -0,0 +1,76 @@ +"use client"; + +import { useContext, useEffect, useState } from "react"; +import { LocationContext } from "../locationContenxt"; + +type Props = { + provinces: Province[]; +}; +type Province = { + id: number; + name: string; + zones: Zone[]; +}; +type Zone = { + id: number; + name: string; + province: number; +}; +export default function LocationSelector({ provinces }: Props) { + let [provinceId, setProvinceId] = useState(undefined); + let [amphurList, setAmphurList] = useState(undefined); + let [amphurId, setAmphurId] = useState(undefined); + const locationContext = useContext(LocationContext); + function setProvince(_id: string) { + let id = parseInt(_id); + setProvinceId(id); + let province = provinces.find((p) => p.id == id); + if (province == undefined) return; + setAmphurList(province.zones); + setAmphurId(undefined); + } + function setAmphur(_id: string) { + let id = parseInt(_id); + setAmphurId(id); + } + useEffect(() => { + if (locationContext == undefined) return; + if (amphurId == undefined || provinceId == undefined) { + locationContext.zone[1](undefined); + locationContext.province[1](undefined); + return; + } + + locationContext.zone[1](amphurId); + locationContext.province[1](provinceId); + }, [amphurId]); + return ( +
+ + + {amphurList && ( + + )} +
+ ); +} diff --git a/components/locationContenxt.tsx b/components/locationContenxt.tsx new file mode 100644 index 0000000..5cab2c5 --- /dev/null +++ b/components/locationContenxt.tsx @@ -0,0 +1,32 @@ +"use client"; +import { + Dispatch, + ReactNode, + SetStateAction, + createContext, + useState, +} from "react"; + +type LocationContextType = { + zone: [number | undefined, Dispatch>]; + province: [number | undefined, Dispatch>]; +}; + +export const LocationContext = createContext( + undefined +); + +export default function LocationContextProvider({ + children, +}: { + children?: ReactNode; +}) { + let zone = useState(undefined); + let province = useState(undefined); + + return ( + + {children} + + ); +} diff --git a/tsconfig.json b/tsconfig.json index 3d97892..a48ede5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,7 @@ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ @@ -21,10 +21,13 @@ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */// "rootDir": "./", /* Specify the root folder within your source files. */ + "module": "commonjs" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + "baseUrl": "." /* Specify the base directory to resolve non-relative module names. */, + "paths": { + "@/components/*": ["components/*"], + "@/src/*": ["src/*"] + }, // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ @@ -69,9 +72,9 @@ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. *//* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */ /* Type Checking */, + "strict": true /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ @@ -92,11 +95,7 @@ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */, - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], + "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "noEmit": true, "incremental": true, @@ -110,13 +109,6 @@ } ] }, - "include": [ - "next-env.d.ts", - ".next/types/**/*.ts", - "**/*.ts", - "**/*.tsx" - ], - "exclude": [ - "node_modules" - ] + "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] }