Skip to content

Commit

Permalink
Feature/oph24 16 registration page (#10)
Browse files Browse the repository at this point in the history
* feat: overall structure

* feat: add button for box5 and box6

* refactor: attribute name for TextBox RadioBox DropDownBox and CheckBox

* feat: data retrieves from checkboxes

* feat: customize checkbox

* fix: font problem

* fix: font problem

* fi

* fix: font problem

* fix: git doesnt add files

* fix: checkbox

* refactor: change checkbox eventListener to checkBox files

* feat: customize radioBox

* fix: incorrect question

* feat: create name for dropdown box5,6

* feat: customize dropdown arrow

* fix: box size

* feat: responsive

* feat: responsive

* fix: dropdown arrow for 3rd box in box5,6

* fix: change interactive pages from astro to react

* fix: textbox prettier

* fix: dropdown

* fix: adjust ui for box3

* fix: change from svg to mdi

* fix: font-weight

* feat: validate must fill data

* refactor: changed files name from numbers to words

* feat: change from .astro to .tsx

* fix: remove unnecessary local variable

* fix: removed unused variable in Checkbox

* feat: add interface

* feat: add interface for props

* style(border): border-4 to border-2

* feat: countries and provinces data

* style(register): heading

* style(register): adjust personal info box

* refactor(register): refactoring base components

* refactor(registeration): refactoring page

* feat(registeration): confirm box

* chore: remove unused file

---------

Co-authored-by: shalluv <[email protected]>
  • Loading branch information
VorraphanT and shalluv authored Jan 7, 2024
1 parent 9926f06 commit 58446c7
Show file tree
Hide file tree
Showing 21 changed files with 1,528 additions and 12 deletions.
58 changes: 58 additions & 0 deletions src/components/CheckBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import clsx from "clsx";
import React, { useState } from "react";
interface Props {
name: string;
value: string;
id: string;
setValue: React.Dispatch<React.SetStateAction<string[]>>;
isShowError?: boolean;
}

const CheckBox = ({
name,
value,
id,
setValue,
isShowError = false,
}: Props) => {
const [isChecked, setIsChecked] = useState<boolean>(false);
const handleClickButton = (e: React.MouseEvent<HTMLInputElement>) => {
e.preventDefault();

if (!isChecked) {
setValue((prev) => [...prev, value]);
} else {
setValue((prev) => prev.filter((item) => item !== value));
}
setIsChecked(!isChecked);
};
return (
<div
className={clsx(
"relative flex aspect-square w-4 items-center justify-center bg-white",
isShowError && "ring-4 ring-[#F55572]"
)}
>
<input
value={value}
name={name}
id={id}
onClick={handleClickButton}
type="checkbox"
className="absolute aspect-square w-full appearance-none"
/>
<label
htmlFor={name}
className="pointer-events-none absolute aspect-square w-full bg-white"
>
<div
className={clsx(
"pointer-events-none absolute left-1/2 top-1/2 aspect-square w-2/3 -translate-x-1/2 -translate-y-1/2 bg-pink-500",
!isChecked && "hidden"
)}
></div>
</label>
</div>
);
};
export default CheckBox;
39 changes: 39 additions & 0 deletions src/components/DropDown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
interface Props {
options: string[];
defaultVal: string;
value: string;
setValue:
| React.Dispatch<React.SetStateAction<string>>
| ((s: string) => void);
isSelectable?: boolean;
}

const DropDown = ({
options = [],
defaultVal,
value,
setValue,
isSelectable = true,
}: Props) => {
return (
<div className="relative inline-block h-full w-full">
<i className="icon-[mdi--chevron-down] pointer-events-none absolute right-0 top-1/2 flex -translate-y-1/2 items-center text-xl text-pink-400"></i>
<select
className="h-full w-full appearance-none rounded-2xl py-3 pl-2 pr-6 text-xs text-pink-400"
onChange={(e) => setValue(e.target.value)}
disabled={!isSelectable}
value={value}
>
<option value="" className="text-pink-400">
{defaultVal}
</option>
{options.map((option) => (
<option value={option} className="text-pink-550" key={option}>
{option}
</option>
))}
</select>
</div>
);
};
export default DropDown;
2 changes: 1 addition & 1 deletion src/components/Faculties/FacultiesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const options = FACULTIES.map((faculty) => {
});

const FacultiesList = () => {
const [facultySelected, setFacultySelected] = useState(0);
const [facultySelected, setFacultySelected] = useState<number>(0);

return (
<>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Faculties/Selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { FC } from "react";

interface Props {
facultySelected: number;
setFacultySelected: (faculty: number) => void;
setFacultySelected: React.Dispatch<React.SetStateAction<number>>;
options: { id: number; name: string }[];
}

Expand Down
10 changes: 1 addition & 9 deletions src/components/Landing/Register.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
const Register = () => {
//const { useAuth } = useAuth();
// const [user, setUser] = useState("");
// eslint-disable-next-line no-constant-condition
return 1 == 1 ? (
return (
<a
href="/register"
className="flex w-64 justify-center rounded-2xl border-2 bg-transparent bg-gradient-to-t from-pink-400/50 to-white/5 px-5 py-2 font-bold shadow-inner shadow-white duration-200 hover:py-3 md:ml-10"
>
ลงทะเบียน / Register
</a>
) : (
<div className="ml-7 px-5 py-2 font-libre text-2xl font-bold">
<p>Welcome!</p>
<p>Test</p>
</div>
);
};
export default Register;
51 changes: 51 additions & 0 deletions src/components/RadioBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import clsx from "clsx";
import type React from "react";

interface Props {
name: string;
value: string;
setValue:
| React.Dispatch<React.SetStateAction<string>>
| React.Dispatch<React.SetStateAction<string | undefined>>;
isSelectable?: boolean;
isBeingChecked: boolean;
}

const RadioBox = ({
name,
value,
setValue,
isSelectable = true,
isBeingChecked,
}: Props) => {
const handleClick = (e: React.MouseEvent<HTMLInputElement>) => {
e.preventDefault();

setValue(value);
};

return (
<div className="relative flex aspect-square w-5 items-center justify-center">
<input
type="radio"
name={name}
disabled={!isSelectable}
className="absolute aspect-square w-full appearance-none"
onClick={handleClick}
/>
<label
htmlFor={name}
className="pointer-events-none absolute aspect-square w-full rounded-full bg-white"
>
<div
className={clsx(
"pointer-events-none absolute left-1/2 top-1/2 aspect-square w-2/3 -translate-x-1/2 -translate-y-1/2 rounded-full bg-pink-500",
!isBeingChecked && "hidden"
)}
></div>
</label>
</div>
);
};

export default RadioBox;
34 changes: 34 additions & 0 deletions src/components/Registration/ConfirmModule.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type React from "react";

interface Props {
setIsShowConfirm: React.Dispatch<React.SetStateAction<boolean>>;
}

const ConfirmModule: React.FC<Props> = ({ setIsShowConfirm }) => {
return (
<div className="fixed left-0 top-0 flex h-screen w-screen items-center justify-center bg-black/20 px-4 backdrop-blur-lg">
<div className="flex h-72 min-h-fit w-80 max-w-full flex-col items-center justify-between rounded-2xl bg-white px-6 py-8 text-center text-pink-550">
<div className="flex w-full flex-col gap-1">
<p className="text-2xl font-bold">ยืนยันข้อมูลถูกต้อง</p>
<p>I hereby confirm that all information provided is correct.</p>
</div>
<div className="flex flex-col gap-2">
<button
className="flex w-full items-center justify-center gap-2"
onClick={() => setIsShowConfirm(false)}
>
<div className="icon-[mdi--arrow-back-circle] text-2xl"></div>
<p className="text-base">กลับ / Back</p>
</button>
<button
className="rounded-2xl border-2 border-pink-550 p-3 text-2xl font-bold"
type="submit"
>
ยืนยัน / Confirm
</button>
</div>
</div>
</div>
);
};
export default ConfirmModule;
9 changes: 9 additions & 0 deletions src/components/Registration/ErrorBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const ErrorBox = () => {
return (
<div className="flex w-full flex-col rounded-2xl bg-[#F55572] px-4 py-2 text-center">
<p className="font-bold">กรุณากรอกข้อมูลที่จำเป็นให้ครบถ้วน</p>
<p className="text-sm font-medium">Please fill out all required fields</p>
</div>
);
};
export default ErrorBox;
151 changes: 151 additions & 0 deletions src/components/Registration/FacultyDetailBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { useEffect, useState } from "react";

import { FACULTIES } from "@/data/faculties.ts";
import type { FacultyInterested } from "@/types/form.ts";
import DropDown from "../DropDown.tsx";

interface Props {
onlyFaculty?: boolean;
number: string;
setValues: React.Dispatch<React.SetStateAction<FacultyInterested[]>>;
faculties: FacultyInterested[];
}
const FacultyDetailBox = ({
onlyFaculty = true,
number,
setValues,
faculties,
}: Props) => {
const setFacultyDetail = (s: string) => {
setValues((prevArray) =>
prevArray.map((e) => (e.number === number ? { ...e, faculty: s } : e))
);
};
const setDepartmentDetail = (s: string) => {
setValues((prevArray) =>
prevArray.map((e) => (e.number === number ? { ...e, department: s } : e))
);
};
const setSectionDetail = (s: string) => {
setValues((prevArray) =>
prevArray.map((e) => (e.number === number ? { ...e, section: s } : e))
);
};

const [departmentOptions, setDepartmentOptions] = useState<string[]>(
[] as string[]
);
const [sectionOptions, setSectionOptions] = useState<string[]>(
[] as string[]
);

useEffect(() => {
if (!faculties || !faculties[parseInt(number) - 1].faculty) return;

setDepartmentOptions(
FACULTIES.find(
(e) =>
e.nameTH + " / " + e.nameEN ===
faculties[parseInt(number) - 1].faculty
)?.departments.map((e) => e.nameTH + " / " + e.nameEN) ?? []
);

if (!faculties || !faculties[parseInt(number) - 1].department) return;

setSectionOptions(
FACULTIES.find(
(e) =>
e.nameTH + " / " + e.nameEN ===
faculties[parseInt(number) - 1].faculty
)
?.departments.find(
(e) =>
e.nameTH + " / " + e.nameEN ===
faculties[parseInt(number) - 1].department
)
?.sections.map((e) => e.nameTH + " / " + e.nameEN) ?? []
);
}, [faculties]);

return (
<div className="flex h-fit w-full flex-col items-center gap-2 rounded-2xl border-2 border-white p-6 px-5 text-sm font-medium text-white">
<p className="text-3xl font-bold">{number}</p>
<div className="flex flex-col gap-4">
<div className="flex h-fit flex-col">
<label className="text-base text-white">คณะ / Faculty</label>
<div className="w-full">
<DropDown
defaultVal="คณะ / Faculty"
options={FACULTIES.map((e) => e.nameTH + " / " + e.nameEN)}
setValue={setFacultyDetail}
value={faculties ? faculties[parseInt(number) - 1].faculty : ""}
/>
</div>
</div>

{!onlyFaculty &&
faculties &&
faculties[parseInt(number) - 1].faculty &&
departmentOptions.length > 0 && (
<div className="flex h-fit flex-col">
<label className="text-base text-white">สาขา / Department</label>
<div className="w-full">
<DropDown
defaultVal="สาขา / Department"
options={
faculties
? FACULTIES.find(
(e) =>
e.nameTH + " / " + e.nameEN ===
faculties[parseInt(number) - 1].faculty
)?.departments.map(
(e) => e.nameTH + " / " + e.nameEN
) ?? []
: []
}
setValue={setDepartmentDetail}
value={
faculties ? faculties[parseInt(number) - 1].department : ""
}
/>
</div>
</div>
)}
{!onlyFaculty &&
faculties &&
faculties[parseInt(number) - 1].department &&
sectionOptions.length > 0 && (
<div className="flex h-fit flex-col">
<label className="text-base text-white">สาขา / Department</label>
<div className="w-full">
<DropDown
defaultVal="สาขา / Department"
options={
faculties
? FACULTIES.find(
(e) =>
e.nameTH + " / " + e.nameEN ===
faculties[parseInt(number) - 1].faculty
)
?.departments.find(
(e) =>
e.nameTH + " / " + e.nameEN ===
faculties[parseInt(number) - 1].department
)
?.sections.map((e) => e.nameTH + " / " + e.nameEN) ??
[]
: []
}
setValue={setSectionDetail}
value={
faculties ? faculties[parseInt(number) - 1].section : ""
}
/>
</div>
</div>
)}
</div>
</div>
);
};
export default FacultyDetailBox;
Loading

0 comments on commit 58446c7

Please sign in to comment.