Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: event registerstion page #18

Merged
merged 17 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/components/Background.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type React from "react";

import bg from "@/assets/background.svg";

interface Props {
withJigsaw?: boolean;
}

const Background = ({ withJigsaw = true }: Props) => {
const Background: React.FC<Props> = ({ withJigsaw = true }) => {
return (
// eslint-disable-next-line tailwindcss/migration-from-tailwind-2
<div className="absolute left-1/2 top-0 -z-50 h-full w-full -translate-x-1/2 overflow-clip bg-pink-400">
Expand Down
4 changes: 2 additions & 2 deletions src/components/CheckBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ interface Props {
isShowError?: boolean;
}

const CheckBox = ({
const CheckBox: React.FC<Props> = ({
name,
value,
id,
setValue,
isShowError = false,
}: Props) => {
}) => {
const [isChecked, setIsChecked] = useState<boolean>(false);
const handleClickButton = (e: React.MouseEvent<HTMLInputElement>) => {
e.preventDefault();
Expand Down
8 changes: 5 additions & 3 deletions src/components/DropDown.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type React from "react";

interface Props {
options: string[];
defaultVal: string;
Expand All @@ -8,18 +10,18 @@ interface Props {
isSelectable?: boolean;
}

const DropDown = ({
const DropDown: React.FC<Props> = ({
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"
className="h-full w-full appearance-none rounded-2xl py-3 pl-2 pr-6 text-xs text-pink-400 md:text-sm"
onChange={(e) => setValue(e.target.value)}
disabled={!isSelectable}
value={value}
Expand Down
8 changes: 5 additions & 3 deletions src/components/Event/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { Event } from "@/types/event";
import { motion } from "framer-motion";
import type React from "react";

import type { Event } from "@/types/event";

export const EnrollBox: React.FC<{
walkIn: boolean;
Expand Down Expand Up @@ -29,7 +31,7 @@ const Card: React.FC<Event> = ({
}) => {
return (
<motion.a
className="w-72 rounded-2xl border-2 border-white bg-pink-500 shadow-inner shadow-white ring-4 ring-white/10"
className="w-72 rounded-2xl border-2 border-white bg-pink-500 shadow-inner shadow-white ring-4 ring-white/10 backdrop-blur-2xl"
href={"/events/" + id}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
Expand All @@ -40,7 +42,7 @@ const Card: React.FC<Event> = ({
duration: 0.3,
}}
>
<div className="flex flex-col gap-2 rounded-t-2xl bg-gradient-to-r from-indigo-900 to-pink-550 p-4 shadow-inner shadow-white">
<div className="flex flex-col gap-2 rounded-t-2xl bg-gradient-to-r from-indigo-900 to-pink-550 p-4 shadow-inner shadow-white backdrop-blur-2xl">
<p className="text-xl font-bold uppercase text-white">
{name.en ? name.en : name.th}
</p>
Expand Down
27 changes: 22 additions & 5 deletions src/components/Event/Container.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
import clsx from "clsx";
import { AnimatePresence, motion } from "framer-motion";
import { useState } from "react";
import { useEffect, useState } from "react";

import Card from "./Card";

import { FACULTIES } from "@/data/faculties";
import type { Event } from "@/types/event";
import clsx from "clsx";
import Card from "./Card";

interface Props {
events: Event[];
faculty: string | null;
}

const Container: React.FC<Props> = ({ events }) => {
const Container: React.FC<Props> = ({ events, faculty }) => {
const [selectedFaculty, setSelectedFaculty] = useState<number>(0);
const [currEvents, setCurrEvents] = useState<Event[]>(events);
const [searchQuery, setSearchQuery] = useState<string>("");

useEffect(() => {
if (faculty) {
const facultyCode = FACULTIES.find(
(facultyObj) => facultyObj.nameEN === faculty
)?.id;
if (facultyCode) {
setSelectedFaculty(parseInt(facultyCode));
const filteredEvents = events.filter(
(event) => parseInt(event.faculty.code) === parseInt(facultyCode)
);
setCurrEvents(filteredEvents);
}
}
}, [faculty]);

const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newSearchQuery = e.target.value;
setSearchQuery(newSearchQuery);
Expand Down Expand Up @@ -69,7 +86,7 @@ const Container: React.FC<Props> = ({ events }) => {
</div>
<motion.input
type="text"
className="w-full flex-1 appearance-none rounded-r-2xl border-2 border-white bg-transparent px-4 text-white shadow-inner shadow-white placeholder:text-white"
className="w-full flex-1 appearance-none rounded-r-2xl border-2 border-white bg-transparent px-4 text-white shadow-inner shadow-white backdrop-blur-2xl placeholder:text-white"
placeholder="ค้นหา/search"
value={searchQuery}
onChange={handleSearchChange}
Expand Down
9 changes: 7 additions & 2 deletions src/components/Event/CurrentAttendee.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { useEffect, useState } from "react";

import type { Event } from "@/types/event";
import { useEffect, useState, type FC } from "react";

interface Props {
eventId: string;
scheduleId: number;
maxCapacity: number;
}

const CurrentAttendee: FC<Props> = ({ eventId, scheduleId, maxCapacity }) => {
const CurrentAttendee: React.FC<Props> = ({
eventId,
scheduleId,
maxCapacity,
}) => {
const [currentAttendee, setCurrentAttendee] = useState<number>(0);

useEffect(() => {
Expand Down
55 changes: 0 additions & 55 deletions src/components/Event/EventRegisterComplete/EventBox.astro

This file was deleted.

60 changes: 60 additions & 0 deletions src/components/Event/Register/ConfirmModule.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import type React from "react";

interface Props {
date: string;
time: string;
name: string;
faculty: { th: string; en: string };
setIsShowConfirm: React.Dispatch<React.SetStateAction<boolean>>;
}

const ConfirmModule: React.FC<Props> = ({
date,
time,
name,
faculty: { th, en },
setIsShowConfirm,
}) => {
return (
<div className="fixed left-0 top-0 z-50 flex h-screen w-screen items-center justify-center bg-black/20 px-4 backdrop-blur-2xl">
<div className="flex w-96 max-w-full flex-col items-center justify-between gap-4 rounded-2xl bg-white px-6 py-8 text-center text-pink-550 md:gap-8">
<div className="flex w-full flex-col gap-1">
<h1 className="text-2xl font-bold">ยืนยันการเข้าร่วมกิจกรรม</h1>
<h2>You will be attending</h2>
</div>
<div className="flex w-full flex-col justify-between gap-2 rounded-2xl border-2 border-pink-550 p-4 text-left text-sm font-medium text-pink-550">
<h2 className="text-lg font-bold">{name}</h2>
<div className="flex flex-col">
<h3 className="font-medium">{th}</h3>
<h4 className="text-sm font-medium">{en}</h4>
</div>
<div className="grid grid-cols-[24px_minmax(0,1fr)] gap-2">
<i className="icon-[mdi--calendar-blank-outline] text-2xl"></i>
<p>{date}</p>
</div>
<div className="grid grid-cols-[24px_minmax(0,1fr)] gap-2">
<i className="icon-[mdi--alarm-clock] text-2xl"></i>
<p>{time}</p>
</div>
</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;
72 changes: 72 additions & 0 deletions src/components/Event/Register/Form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { useState } from "react";

import ErrorBox from "@/components/Registration/ErrorBox";
import EventConfirmModule from "./ConfirmModule";
import SourceOfNewsBox from "./SourceOfNewsBox";

interface Props {
date: string;
time: string;
name: string;
faculty: { th: string; en: string };
}

const Form: React.FC<Props> = ({ date, time, name, faculty }) => {
const [sourceOfNews, setSourceOfNews] = useState<string[]>([]);
const [isShowError, setIsShowError] = useState<boolean>(false);
const [isShowConfirm, setIsShowConfirm] = useState<boolean>(false);

const validateData = () => {
if (sourceOfNews.length === 0) {
setIsShowError(true);
} else {
setIsShowError(false);
setIsShowConfirm(true);
}
};

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
};

return (
<form
id="form"
className="flex w-full flex-col items-center gap-12"
onSubmit={handleSubmit}
>
<SourceOfNewsBox
setSourceOfNews={setSourceOfNews}
isShowError={isShowError}
/>

{isShowError && <ErrorBox />}
{isShowConfirm && (
<EventConfirmModule
date={date}
name={name}
faculty={faculty}
time={time}
setIsShowConfirm={setIsShowConfirm}
/>
)}
<div className="flex w-full flex-col items-center justify-center gap-4 text-center">
<button
className="flex items-center justify-center gap-2 px-2 py-1 text-center hover:underline hover:underline-offset-4"
onClick={() => window.history.back()}
>
<i className="icon-[mdi--arrow-back-circle] text-white"></i>
<p className="text-base text-white">กลับ / Back</p>
</button>
<button
type="button"
className="rounded-2xl border-2 border-white bg-transparent px-4 py-2 font-bold text-white shadow-inner shadow-white backdrop-blur-2xl"
onClick={validateData}
>
ลงทะเบียน / Register
</button>
</div>
</form>
);
};
export default Form;
Loading