กรุณารอการเลือกบ้าน
diff --git a/src/components/baan-selection/FilterButton.tsx b/src/components/baan-selection/FilterButton.tsx
new file mode 100644
index 0000000..0900718
--- /dev/null
+++ b/src/components/baan-selection/FilterButton.tsx
@@ -0,0 +1,58 @@
+import { BaanSize } from '@/types/baan';
+
+interface FilterButtonProps {
+ filter: BaanSize;
+ filterBaan: (f: BaanSize) => void;
+}
+
+const FilterButton = (props: FilterButtonProps) => {
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export default FilterButton;
diff --git a/src/components/baan-selection/ListBaan.tsx b/src/components/baan-selection/ListBaan.tsx
new file mode 100644
index 0000000..436e572
--- /dev/null
+++ b/src/components/baan-selection/ListBaan.tsx
@@ -0,0 +1,44 @@
+import Image from 'next/image';
+import { convertSize, isAdded } from '@/utils/baan-selection/utility';
+import { IBaan } from '@/types/baan';
+import { SelectedBaanRank } from '@/utils/baan-selection/types';
+
+const ListBaan = (props: {
+ baan: IBaan[];
+ input: string;
+ selectedBaan: SelectedBaanRank[];
+ handleClick: (e: IBaan) => void;
+}) => {
+ return props.baan
+ .filter(
+ (e: IBaan) =>
+ e.name.includes(props.input) && isAdded(props.selectedBaan, e)
+ )
+ .map((e: IBaan) => {
+ return (
+
props.handleClick(e)}
+ >
+
+ event.dataTransfer.setData(
+ 'Data',
+ JSON.stringify(e)
+ )
+ }
+ >
+
+
+
+ {e.name} ({convertSize.get(e.size)})
+
+
+ );
+ });
+};
+
+export default ListBaan;
diff --git a/src/components/baan-selection/SearchBar.tsx b/src/components/baan-selection/SearchBar.tsx
new file mode 100644
index 0000000..020d327
--- /dev/null
+++ b/src/components/baan-selection/SearchBar.tsx
@@ -0,0 +1,25 @@
+import { HomeIcon, MagnifyingGlassIcon } from '@heroicons/react/24/solid';
+import { ChangeEvent } from 'react';
+
+const SearchBar = (props: any) => {
+ return (
+
+ );
+};
+export default SearchBar;
diff --git a/src/components/baan-selection/SelectedBaan.tsx b/src/components/baan-selection/SelectedBaan.tsx
new file mode 100644
index 0000000..143d3ed
--- /dev/null
+++ b/src/components/baan-selection/SelectedBaan.tsx
@@ -0,0 +1,51 @@
+import TrashIcon from '@heroicons/react/24/solid/TrashIcon';
+import { SelectedBaanRank } from '@/utils/baan-selection/types';
+import Image from 'next/image';
+import { BaanSize } from '@/types/baan';
+import { convertSize } from '@/utils/baan-selection/utility';
+const SelectedBaan = (props: any) => {
+ return (
+
e.preventDefault()}
+ >
+
+
+ {props.num}
+
+ {props.id === '' ? (
+
Null
+ ) : (
+
+ )}
+
+ {props.id === '' ? (
+
ท่านยังไม่ได้เลือกบ้าน
+ ) : (
+
+
{`${props.name} (${convertSize.get(props.size)})`}
+
+
+ )}
+
+ );
+};
+export default SelectedBaan;
diff --git a/src/components/font.ts b/src/components/font.ts
new file mode 100644
index 0000000..fffdd38
--- /dev/null
+++ b/src/components/font.ts
@@ -0,0 +1,8 @@
+import { IBM_Plex_Sans_Thai } from 'next/font/google';
+
+export const ibmPlexSansThai = IBM_Plex_Sans_Thai({
+ subsets: ['latin'],
+ weight: ['500', '600', '700'],
+ display: 'swap',
+ variable: '--font-ibm',
+});
diff --git a/src/context/AuthContext.tsx b/src/context/AuthContext.tsx
index 5cb3d9d..9fcd644 100644
--- a/src/context/AuthContext.tsx
+++ b/src/context/AuthContext.tsx
@@ -7,7 +7,6 @@ import { useRouter } from 'next/router';
import {
ReactNode,
createContext,
- use,
useCallback,
useContext,
useEffect,
@@ -80,7 +79,7 @@ const AuthProvider = ({ children }: { children: ReactNode }) => {
switch (router.pathname) {
case '/':
if (user) {
- if (alreadyRegistered) router.push('/baan-selection');
+ if (alreadyRegistered) router.push('/profile');
else router.push('/register');
}
break;
@@ -88,9 +87,11 @@ const AuthProvider = ({ children }: { children: ReactNode }) => {
if (!user) {
router.push('/');
} else if (alreadyRegistered) {
- router.push('/baan-selection');
+ router.push('/profile');
}
break;
+ case '/wait-baan-selection':
+ case '/profile':
case '/baan-selection':
if (!user) {
router.push('/');
diff --git a/src/context/ModalContext.tsx b/src/context/ModalContext.tsx
new file mode 100644
index 0000000..9e7ab73
--- /dev/null
+++ b/src/context/ModalContext.tsx
@@ -0,0 +1,53 @@
+import { createContext, useContext, ReactNode, useState } from 'react';
+
+type ModalId =
+ | 'modal-1'
+ | 'modal-2'
+ | 'modal-3'
+ | 'modal-4'
+ | 'modal-5'
+ | 'modal-6'
+ | 'modal-7'
+ | 'modal-8'
+ | 'modal-9'
+ | 'modal-10'
+ | 'modal-join-group'
+ | 'modal-join-error'
+ | 'modal-leave-group'
+ | 'modal-kick-user';
+
+export interface AppContextProps {
+ modalToOpen: ModalId | null;
+ closeModal: () => void;
+ openModal: (id: ModalId) => void;
+}
+
+export const AppContext = createContext
({
+ modalToOpen: null,
+ closeModal: () => {},
+ openModal: (id: ModalId) => {},
+});
+
+export interface AppContextProviderProps {
+ children: ReactNode;
+}
+
+export const AppContextProvider = ({ children }: AppContextProviderProps) => {
+ const [modalToOpen, setModalToOpen] = useState(null);
+
+ const closeModal = () => {
+ setModalToOpen(null);
+ };
+
+ const openModal = (id: ModalId) => {
+ setModalToOpen(id);
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useAppContext = () => useContext(AppContext);
diff --git a/src/dto/baanDTO.ts b/src/dto/baanDTO.ts
index 943eee7..c83fcb5 100644
--- a/src/dto/baanDTO.ts
+++ b/src/dto/baanDTO.ts
@@ -1,20 +1,21 @@
import { BaanSize } from '@/types/baan';
export interface ShortBaanDTO {
- id: number;
- nameEN: string;
- nameTH: string;
- imageUrl: string;
+ id: string;
+ name_en: string;
+ name_th: string;
+ image_url: string;
+ baan_size: BaanSize;
}
-export interface BaanDTO extends ShortBaanDTO {
+export interface BaanDTO extends Omit {
size: BaanSize;
- descriptionEN: string;
- descriptionTH: string;
+ description_en: string;
+ description_th: string;
facebook: string;
- facebookUrl: string;
+ facebook_url: string;
instagram: string;
- instagramUrl: string;
+ instagram_url: string;
line: string;
- lineUrl: string;
+ line_url: string;
}
diff --git a/src/dto/groupDTO.ts b/src/dto/groupDTO.ts
index 04d7d98..e627149 100644
--- a/src/dto/groupDTO.ts
+++ b/src/dto/groupDTO.ts
@@ -11,7 +11,7 @@ export interface Member {
export interface GroupDTO {
id: string;
- leaderID: string;
+ leader_id: string;
members: IShortUser[];
baans: ShortBaanDTO[];
token: string;
diff --git a/src/dto/userDTO.ts b/src/dto/userDTO.ts
index ffbd1ce..46c142d 100644
--- a/src/dto/userDTO.ts
+++ b/src/dto/userDTO.ts
@@ -9,6 +9,8 @@ export interface UserDTO {
nickname?: string;
email?: string;
phone?: string;
+ emer_phone?: string;
+ emer_relation?: string;
line_id?: string;
disease?: string;
allergy_food?: string;
@@ -20,4 +22,5 @@ export interface UserDTO {
group_id?: string;
baan_id?: string;
is_got_ticket?: boolean;
+ want_bottle?: boolean;
}
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 1d6b560..694d639 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -8,13 +8,9 @@ import Head from 'next/head';
import Footer from '@/components/Footer';
import Navbar from '@/components/Navbar';
import { ToastProvider } from '@/components/Toast';
+import { AppContextProvider } from '@/context/ModalContext';
-const ibmPlexSansThai = IBM_Plex_Sans_Thai({
- subsets: ['latin'],
- weight: ['500', '600', '700'],
- display: 'swap',
- variable: '--font-ibm',
-});
+import { ibmPlexSansThai } from '@/components/font';
function MetaData() {
return (
@@ -64,12 +60,15 @@ export default function App({ Component, pageProps }: AppProps) {
-
+
+
-
-
-
-
+
+
+
+
+
+
diff --git a/src/pages/baan-selection/index.tsx b/src/pages/baan-selection/index.tsx
new file mode 100644
index 0000000..03ee9ee
--- /dev/null
+++ b/src/pages/baan-selection/index.tsx
@@ -0,0 +1,205 @@
+import { useEffect, useState, DragEvent } from 'react';
+import SelectedBaan from '@/components/baan-selection/SelectedBaan';
+import ListBaan from '@/components/baan-selection/ListBaan';
+import { BaanSize, IBaan, IShortBaan } from '@/types/baan';
+import { SelectedBaanRank } from '@/utils/baan-selection/types';
+import FilterButton from '@/components/baan-selection/FilterButton';
+import SearchBar from '@/components/baan-selection/SearchBar';
+import { httpGet, httpPut } from '@/utils/axios';
+import { BaanDTO } from '@/dto/baanDTO';
+import { transformBaanDTOtoIBaan } from '@/utils/baan';
+import { useRouter } from 'next/router';
+import { useAuth } from '@/context/AuthContext';
+import { useToast } from '@/components/Toast';
+
+function useAllBaans() {
+ const [allBaans, setAllBaans] = useState([]);
+ const { locale } = useRouter();
+
+ useEffect(() => {
+ async function fetchBaans() {
+ const { data } = await httpGet('/baan');
+ setAllBaans(
+ data.map((baan) =>
+ transformBaanDTOtoIBaan(
+ baan,
+ (locale?.toUpperCase() as 'TH' | 'EN') || 'TH'
+ )
+ )
+ );
+ }
+
+ fetchBaans();
+ }, [locale]);
+
+ return allBaans;
+}
+
+const BaanChoosing = () => {
+ const { group } = useAuth();
+ const router = useRouter();
+ const toast = useToast();
+
+ const [input, setInput] = useState(''); //Input in search-baan bar
+ const [filter, setFilter] = useState(BaanSize._); //Check if the baan size filter is activated in which button
+
+ const allBaans = useAllBaans();
+ const [baan, setBaan] = useState([]); //The list of every baans in RPKM...
+
+ useEffect(() => {
+ setBaan(allBaans);
+ if (group?.baans) {
+ const gBaans = (group?.baans ?? []).map(
+ (baan, index) =>
+ ({
+ id: baan.id,
+ name: baan.name,
+ imageUrl: baan.imageUrl,
+ size:
+ {
+ S: BaanSize.Small,
+ M: BaanSize.Medium,
+ L: BaanSize.Large,
+ XL: BaanSize.ExtraLarge,
+ XXL: BaanSize.ExtraExtraLarge,
+ }[baan.size as unknown as string] ?? BaanSize._,
+ num: index + 1,
+ } satisfies IShortBaan & { num: number })
+ );
+
+ while (gBaans.length < 3) {
+ gBaans.push({
+ id: '',
+ name: '',
+ imageUrl: '',
+ size: BaanSize._,
+ num: gBaans.length + 1,
+ });
+ }
+
+ setSelectedBaan(gBaans);
+ }
+ }, [allBaans, group?.baans]);
+
+ const [selectedBaan, setSelectedBaan] = useState(
+ Array.from({ length: 3 }, (_, index) => ({
+ id: '',
+ imageUrl: '',
+ name: '',
+ size: BaanSize._,
+ num: index + 1,
+ }))
+ );
+
+ const filterBaan = (f: BaanSize) => {
+ setBaan(allBaans);
+ if (filter == f) setFilter(BaanSize._);
+ else {
+ setFilter(f);
+ setBaan(allBaans.filter((e: IBaan) => e.size == f));
+ }
+ };
+
+ const handleClick = (e: IBaan) => {
+ let isSuccessFul = false;
+ const data: SelectedBaanRank[] = [...selectedBaan];
+ data.forEach((element) => {
+ if (element.id === '' && !isSuccessFul) {
+ element.id = e.id;
+ element.imageUrl = e.imageUrl;
+ element.name = e.name;
+ element.size = e.size;
+ isSuccessFul = true;
+ return;
+ }
+ });
+ if (!isSuccessFul) {
+ toast?.setToast('error', 'คุณเลือกบ้านครบแล้ว');
+ return;
+ }
+ setSelectedBaan(data);
+ };
+
+ const handleDrop = (e: DragEvent, n: number) => {
+ if (selectedBaan[n - 1].id !== '') return;
+ const widget: SelectedBaanRank = JSON.parse(
+ e.dataTransfer.getData('Data') as string
+ );
+ const data: SelectedBaanRank[] = [...selectedBaan];
+ data[n - 1] = {
+ ...data[n - 1],
+ name: widget.name,
+ size: widget.size,
+ imageUrl: widget.imageUrl,
+ id: widget.id,
+ };
+ setSelectedBaan(data);
+ };
+
+ return (
+
+
+
+
+ เลือกบ้าน
+
+
+ เลือก 3 บ้านที่สนใจมากที่สุด
+
+
+ {selectedBaan.map(
+ (e: SelectedBaanRank, index: number) => {
+ return (
+ ) =>
+ handleDrop(e, index + 1)
+ }
+ setSelectedBaan={setSelectedBaan}
+ {...e}
+ baan={selectedBaan}
+ />
+ );
+ }
+ )}
+
+
+
+
+
+
+
+ ค้นหาบ้าน
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default BaanChoosing;
diff --git a/src/pages/edit.tsx b/src/pages/edit.tsx
new file mode 100644
index 0000000..99c187f
--- /dev/null
+++ b/src/pages/edit.tsx
@@ -0,0 +1,109 @@
+import { useAuth } from '@/context/AuthContext';
+import { httpPatch } from '@/utils/axios';
+import { useRouter } from 'next/router';
+import { FormEvent, useEffect, useState } from 'react';
+import {
+ RegisterForm,
+ getFormData,
+ profilePicPlaceholderURL,
+ registerFormId,
+} from '@/components/Profile/Register';
+
+const ProfileEdit = () => {
+ const { user, refreshContext } = useAuth();
+ const router = useRouter();
+
+ const [error, setError] = useState([]);
+ const [previewImage, setPreviewImage] = useState(
+ profilePicPlaceholderURL
+ );
+
+ async function onFormComplete(e: FormEvent) {
+ const body = getFormData(user);
+
+ try {
+ await httpPatch(`/user`, body);
+ await refreshContext();
+ router.push('/profile');
+ } catch (_error: any) {
+ console.error(_error);
+ setError([_error]);
+ }
+ }
+
+ useEffect(() => {
+ if (user) {
+ setPreviewImage(user.imageUrl || profilePicPlaceholderURL);
+
+ const form = document.getElementById(
+ registerFormId
+ ) as HTMLFormElement;
+
+ for (const element of form) {
+ switch (element.id) {
+ case 'nametitle':
+ (element as HTMLSelectElement).value = user?.title;
+ break;
+ case 'firstname':
+ (element as HTMLInputElement).value = user?.firstname;
+ break;
+ case 'surname':
+ (element as HTMLInputElement).value = user?.lastname;
+ break;
+ case 'nickname':
+ (element as HTMLInputElement).value = user?.nickname;
+ break;
+ case 'phone':
+ (element as HTMLInputElement).value = user?.phone;
+ break;
+ case 'email':
+ (element as HTMLInputElement).value = user?.email;
+ break;
+ case 'lineId':
+ (element as HTMLInputElement).value = user?.lineID;
+ break;
+ case 'diseases':
+ (element as HTMLInputElement).value = user?.disease;
+ break;
+ case 'drugAllergy':
+ (element as HTMLInputElement).value =
+ user?.allergyMedicine;
+ break;
+ case 'foodAllergy':
+ (element as HTMLInputElement).value = user?.allergyFood;
+ break;
+ case 'foodRestriction':
+ (element as HTMLInputElement).value =
+ user?.foodRestriction;
+ break;
+ case 'emergencyNo':
+ (element as HTMLInputElement).value = user?.emerPhone;
+ break;
+ case 'emergencyRel':
+ (element as HTMLInputElement).value =
+ user?.emerRelation;
+ break;
+ case 'wantbottle':
+ (element as HTMLInputElement).checked =
+ user?.wantbottle;
+ break;
+ }
+ }
+ }
+ }, [user]);
+
+ return (
+
+
+
+ );
+};
+
+export default ProfileEdit;
diff --git a/src/pages/faq.tsx b/src/pages/faq.tsx
index 1b81fe3..09aa116 100644
--- a/src/pages/faq.tsx
+++ b/src/pages/faq.tsx
@@ -27,7 +27,7 @@ const FAQ = () => {
key={question.header}
className="flex flex-col gap-2 rounded-md bg-white px-8 py-8 shadow-md"
>
-
+
{question.header}
diff --git a/src/pages/join.tsx b/src/pages/join.tsx
new file mode 100644
index 0000000..4cc8568
--- /dev/null
+++ b/src/pages/join.tsx
@@ -0,0 +1,141 @@
+import { Modal } from '@/components/Modal';
+import { useAppContext } from '@/context/ModalContext';
+import { GroupPublicDTO } from '@/dto/groupDTO';
+import { httpGet, httpPost } from '@/utils/axios';
+import { AxiosError } from 'axios';
+import { NextPage } from 'next';
+import { useRouter } from 'next/router';
+import { useCallback, useEffect, useMemo, useState } from 'react';
+
+function useGroupData() {
+ const { query, replace } = useRouter();
+
+ const token = useMemo(
+ () => decodeURI((query.token as string | undefined) ?? ''),
+ [query]
+ );
+
+ const [loading, setLoading] = useState(true);
+ const [group, setGroup] = useState();
+ const [error, setError] = useState('');
+
+ useEffect(() => {
+ if (!token) return;
+
+ async function fetchGroup() {
+ try {
+ const { data } = await httpGet(
+ `/group/${encodeURIComponent(token)}`
+ );
+ setGroup(data);
+ setLoading(false);
+ } catch (err) {
+ setError(
+ (err as AxiosError).response?.status === 404
+ ? 'ไม่พบกลุ่มนี้'
+ : 'เกิดข้อผิดพลาดที่ไม่ทราบ'
+ );
+ }
+ }
+
+ fetchGroup();
+ }, [token]);
+
+ const joinGroup = useCallback(async () => {
+ try {
+ const { status } = await httpPost(
+ `/group/${encodeURIComponent(token)}`,
+ {}
+ );
+
+ if (status === 200) {
+ replace('/profile');
+ }
+ } catch (err) {
+ console.log({ err });
+ setError(
+ (err as AxiosError).response?.status === 403
+ ? 'สมาชิกในกลุ่มเต็มแล้ว หรือคุณเป็นหัวหน้ากลุ่มอยู่'
+ : 'เกิดข้อผิดพลาดที่ไม่ทราบ'
+ );
+ }
+ }, [replace, token]);
+
+ return {
+ token,
+ group,
+ error,
+ loading,
+ joinGroup,
+ };
+}
+
+const JoinPage: NextPage = () => {
+ const router = useRouter();
+ const { openModal, modalToOpen, closeModal } = useAppContext();
+
+ const { group, error, loading, joinGroup } = useGroupData();
+
+ useEffect(() => {
+ if (!loading && !error) {
+ openModal('modal-join-group');
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [loading]);
+
+ useEffect(() => {
+ if (error) {
+ openModal('modal-join-error');
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [error]);
+
+ function handleCloseModal(answer: 1 | 2 | undefined) {
+ if (answer === 2) {
+ joinGroup();
+ closeModal();
+ } else {
+ router.push('/profile');
+ }
+ }
+
+ return (
+
+
+
+
+ คุณต้องการเข้ากลุ่มของ{' '}
+
+ {group?.leader.firstname} {group?.leader.lastname}
+ {' '}
+ หรือไม่?
+
+
+
+
+
{
+ closeModal();
+ router.push('/profile');
+ }}
+ answer1=""
+ answer2="รับทราบ"
+ >
+
+
+ เกิดข้อผิดพลาดในการเข้าร่วมกลุ่ม
+
+
{error}
+
+
+
+ );
+};
+
+export default JoinPage;
diff --git a/src/pages/privacy-policy.tsx b/src/pages/privacy-policy.tsx
index b7649f6..ef5d455 100644
--- a/src/pages/privacy-policy.tsx
+++ b/src/pages/privacy-policy.tsx
@@ -12,7 +12,7 @@ export async function getStaticProps() {
const PrivacyPolicy = ({ source }: { source: any }) => {
return (
diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx
new file mode 100644
index 0000000..f365097
--- /dev/null
+++ b/src/pages/profile.tsx
@@ -0,0 +1,4 @@
+// import WaitForBaanselection from "@/components/Profile/WaitForBaan";
+import BaanSelection from '@/components/Profile/BaanSelection';
+
+export default BaanSelection;
diff --git a/src/pages/register.tsx b/src/pages/register.tsx
index a3a8c83..e62b431 100644
--- a/src/pages/register.tsx
+++ b/src/pages/register.tsx
@@ -1,201 +1,37 @@
import { useAuth } from '@/context/AuthContext';
-import { RegisterDTO } from '@/dto/registerDTO';
-import { httpPatch, httpPost } from '@/utils/axios';
-import { PencilSquareIcon, XMarkIcon } from '@heroicons/react/24/solid';
+import { httpPatch } from '@/utils/axios';
+import { XMarkIcon } from '@heroicons/react/24/solid';
import Image from 'next/image';
-import Link from 'next/link';
import { useRouter } from 'next/router';
-import { ChangeEvent, FormEvent, useEffect, useState } from 'react';
+import { FormEvent, useState } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
-import { useToast } from '@/components/Toast';
-
-const profilePicPlaceholderURL = '/images/pfp-placeholder.svg';
+import {
+ RegisterForm,
+ getFormData,
+ profilePicPlaceholderURL,
+} from '@/components/Profile/Register';
const Register = () => {
- const toast = useToast();
-
const { user, refreshContext } = useAuth();
const router = useRouter();
const [bottleModal, setBottleModal] = useState(false);
+ const [error, setError] = useState([]);
const [previewImage, setPreviewImage] = useState(
profilePicPlaceholderURL
);
- const [error, setError] = useState([]);
-
- async function handleImageUpload(file: File) {
- const formData = new FormData();
- const filename = `${Date.now()}.${file.name.split('.').pop()}${
- user?.studentID
- }`;
- formData.append('file', file, filename);
- formData.append('tag', '1');
- formData.append('type', '1');
- // if file larger than 10mb
- const TEN_MB = 10 * 1024 * 1024;
- if (file.size > TEN_MB) {
- toast?.setToast('error', 'ไฟล์มีขนาดใหญ่เกิน 10 MB');
- return;
- }
-
- try {
- const { data } = await httpPost<
- FormData,
- {
- url: string;
- }
- >('/file/upload', formData);
-
- setPreviewImage(data.url);
- } catch (error) {
- toast?.setToast('error', 'เกิดข้อผิดพลาดในการอัปโหลดรูปภาพ');
- }
+ function onFormComplete(e: FormEvent) {
+ setBottleModal(true);
}
- const onFormDone = (e: FormEvent) => {
- e.preventDefault();
-
- const _error = [];
+ const handleSubmit = async (wantBottle: boolean) => {
+ const body = getFormData(user, wantBottle);
- // validate form
- if (!e.currentTarget.image.files[0]) {
- _error.push('กรุณาอัปโหลดรูปภาพ');
- }
- if (
- !e.currentTarget.nametitle.value ||
- e.currentTarget.nametitle.value === ''
- ) {
- _error.push('กรุณาเลือกคำนำหน้าชื่อ');
- }
- if (
- !e.currentTarget.firstname.value ||
- e.currentTarget.firstname.value === ''
- ) {
- _error.push('กรุณากรอกชื่อ');
- }
- if (
- !e.currentTarget.surname.value ||
- e.currentTarget.surname.value === ''
- ) {
- _error.push('กรุณากรอกนามสกุล');
- }
- if (
- !e.currentTarget.nickname.value ||
- e.currentTarget.nickname.value === ''
- ) {
- _error.push('กรุณากรอกชื่อเล่น');
- }
- if (
- !e.currentTarget.phone.value ||
- e.currentTarget.phone.value === ''
- ) {
- _error.push('กรุณากรอกหมายเลขโทรศัพท์');
- } else if (!e.currentTarget.phone.value.match(/^[0-9]{10}$/)) {
- _error.push(
- 'หมายเลขโทรศัพท์ต้องประกอบด้วยตัวเลข 10 หลัก เช่น 0912345678'
- );
- }
- if (
- !e.currentTarget.email.value ||
- e.currentTarget.email.value === ''
- ) {
- _error.push('กรุณากรอก Email');
- } else if (
- !e.currentTarget.email.value.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)
- ) {
- _error.push('กรุณากรอก Email ให้ถูกต้อง');
- }
- if (
- !e.currentTarget.lineId.value ||
- e.currentTarget.lineId.value === ''
- ) {
- _error.push('กรุณากรอก LINE ID');
- }
- if (
- !e.currentTarget.diseases.value ||
- e.currentTarget.diseases.value === ''
- ) {
- _error.push('กรุณากรอกโรคประจำตัว');
- }
- if (
- !e.currentTarget.foodAllergy.value ||
- e.currentTarget.foodAllergy.value === ''
- ) {
- _error.push('กรุณากรอกอาหารที่แพ้');
- }
- if (
- !e.currentTarget.drugAllergy.value ||
- e.currentTarget.drugAllergy.value === ''
- ) {
- _error.push('กรุณากรอกยาที่แพ้');
- }
- if (
- !e.currentTarget.foodRestriction.value ||
- e.currentTarget.foodRestriction.value === ''
- ) {
- _error.push('กรุณากรอกข้อจำกัดทางอาหาร');
- }
- if (
- !e.currentTarget.emergencyNo.value ||
- e.currentTarget.emergencyNo.value === ''
- ) {
- _error.push('กรุณากรอกเบอร์ติดต่อฉุกเฉิน');
- } else if (!e.currentTarget.emergencyNo.value.match(/^[0-9]{10}$/)) {
- _error.push(
- 'หมายเลขโทรศัพท์ติดต่อฉุกเฉินต้องประกอบด้วยตัวเลข 10 หลัก เช่น 0912345678'
- );
- }
- if (
- !e.currentTarget.emergencyRel.value ||
- e.currentTarget.emergencyRel.value === ''
- ) {
- _error.push('กรุณากรอกความสัมพันธ์กับผู้ติดต่อฉุกเฉิน');
- }
- if (!e.currentTarget.tc.checked) {
- _error.push('กรุณายอมรับเงื่อนไขการใช้งานและนโยบายความเป็นส่วนตัว');
- }
- if (!e.currentTarget.pp.checked) {
- _error.push('กรุณายอมรับข้อตกลง');
- }
-
- setError(_error);
-
- if (_error.length === 0) {
- setBottleModal(true);
- }
- };
-
- const handleSubmit = async (
- // e: FormEvent,
- wantBottle: boolean
- ) => {
- const form = document.getElementById(
- 'register-form'
- ) as HTMLFormElement;
-
- const body = {
- allergy_food: form.foodAllergy.value as string,
- allergy_medicine: form.drugAllergy.value as string,
- disease: form.diseases.value as string,
- email: form.email.value as string,
- emer_phone: form.emergencyNo.value as string,
- emer_relation: form.emergencyRel.value as string,
- firstname: form.firstname.value as string,
- food_restriction: form.foodRestriction.value as string,
- line_id: form.lineId.value as string,
- lastname: form.surname.value as string,
- nickname: form.nickname.value as string,
- phone: form.phone.value as string,
- title: form.nametitle.value as string,
- want_bottle: wantBottle,
- id: user?.id ?? '',
- } satisfies RegisterDTO;
try {
await httpPatch(`/user`, body);
await refreshContext();
- router.push('/baan-selection');
+ router.push('/profile');
} catch (_error: any) {
- // TODO handle error
setBottleModal(false);
console.error(_error);
setError([_error]);
@@ -222,7 +58,7 @@ const Register = () => {
alt="Bottle"
/>
-
+
ต้องการรับกระบอกน้ำ
Chula Zero Waste
ในงานรับเพื่อนก้าวใหม่หรือไม่
@@ -256,271 +92,18 @@ const Register = () => {
setBottleModal(false)}
- className="fixed left-0 top-0 z-50 h-screen w-screen bg-black/25 backdrop-blur-md"
+ className="fixed left-0 top-0 z-50 h-screen w-full bg-black/25 backdrop-blur-md"
>
)}
-
+
);
};
diff --git a/src/pages/terms-conditions.tsx b/src/pages/terms-conditions.tsx
index 0555896..0251803 100644
--- a/src/pages/terms-conditions.tsx
+++ b/src/pages/terms-conditions.tsx
@@ -11,7 +11,7 @@ export async function getStaticProps() {
const PrivacyPolicy = ({ source }: { source: any }) => {
return (
diff --git a/src/pages/wait-baan-selection.tsx b/src/pages/wait-baan-selection.tsx
new file mode 100644
index 0000000..226beb3
--- /dev/null
+++ b/src/pages/wait-baan-selection.tsx
@@ -0,0 +1,31 @@
+import type { NextPage } from 'next';
+import Image from 'next/image';
+
+import Rocket from '@/public/images/rocket.svg';
+
+const WaitForBaanselection: NextPage = () => {
+ return (
+
+ );
+};
+export default WaitForBaanselection;
diff --git a/src/types/baan.ts b/src/types/baan.ts
index 8eda95e..bfc25ad 100644
--- a/src/types/baan.ts
+++ b/src/types/baan.ts
@@ -10,13 +10,13 @@ export enum BaanSize {
}
export interface IShortBaan {
- id: number;
+ id: string;
name: string;
imageUrl: string;
+ size: BaanSize;
}
export interface IBaan extends IShortBaan {
- size: BaanSize;
description: string;
facebook: string;
facebookUrl: string;
diff --git a/src/types/user.ts b/src/types/user.ts
index 083fb47..b6eef52 100644
--- a/src/types/user.ts
+++ b/src/types/user.ts
@@ -2,7 +2,7 @@ export interface IShortUser {
id: string;
firstname: string;
lastname: string;
- imageUrl: string;
+ image_url: string;
}
export interface IUser {
@@ -16,6 +16,8 @@ export interface IUser {
nickname: string;
email: string;
phone: string;
+ emerPhone: string;
+ emerRelation: string;
lineID: string;
disease: string;
allergyFood: string;
@@ -27,4 +29,5 @@ export interface IUser {
groupId: string;
isGotTicket: boolean;
baanId?: string;
+ wantbottle: boolean;
}
diff --git a/src/utils/baan-selection/types.tsx b/src/utils/baan-selection/types.tsx
new file mode 100644
index 0000000..768d14b
--- /dev/null
+++ b/src/utils/baan-selection/types.tsx
@@ -0,0 +1,7 @@
+import { BaanSize, IShortBaan } from '@/types/baan';
+
+export interface SelectedBaanRank extends IShortBaan {
+ //Interface for selected baans (3 baans)
+ size: BaanSize;
+ num: number;
+}
diff --git a/src/utils/baan-selection/utility.tsx b/src/utils/baan-selection/utility.tsx
new file mode 100644
index 0000000..151d6ef
--- /dev/null
+++ b/src/utils/baan-selection/utility.tsx
@@ -0,0 +1,19 @@
+import { BaanSize, IBaan } from '@/types/baan';
+import { SelectedBaanRank } from './types';
+
+export const isAdded = (selectedBaan: SelectedBaanRank[], other: IBaan) => {
+ //Check if the baan is selected and will not be visualized in Baan list
+ for (let i: number = 0; i < 3; i++) {
+ if (selectedBaan[i].id === other.id) return false;
+ }
+ return true;
+};
+
+export const convertSize: Map