From 47946281c474359fe08f6c53dd27ba2b3322f97d Mon Sep 17 00:00:00 2001 From: benjytan45678 Date: Sun, 21 May 2023 00:23:41 +0800 Subject: [PATCH 001/223] add calendar functionality --- package.json | 5 + src/components/calendar/Meeting.tsx | 86 +++++++++++ src/components/calendar/SideCalendar.tsx | 179 +++++++++++++++++++++++ src/components/common/TopNavbar.tsx | 6 + src/pages/calendar/index.tsx | 89 +++++++++++ yarn.lock | 81 +++++++++- 6 files changed, 444 insertions(+), 2 deletions(-) create mode 100644 src/components/calendar/Meeting.tsx create mode 100644 src/components/calendar/SideCalendar.tsx create mode 100644 src/pages/calendar/index.tsx diff --git a/package.json b/package.json index a43c912b..d0be7664 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,9 @@ "@chakra-ui/react": "^2.6.1", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", + "@fullcalendar/react": "^6.1.7", + "@headlessui/react": "^1.7.14", + "@heroicons/react": "v1", "@hookform/resolvers": "^2.9.10", "@next-auth/prisma-adapter": "1.0.5", "@prisma/client": "^4.14.0", @@ -28,10 +31,12 @@ "@trpc/server": "^10.26.0", "bcryptjs": "^2.4.3", "clsx": "^1.2.1", + "date-fns": "^2.30.0", "dayjs": "^1.11.7", "flowbite": "^1.6.5", "flowbite-react": "^0.4.4", "framer-motion": "^9.0.4", + "fullcalendar": "^6.1.7", "next": "^13.1.6", "next-auth": "^4.22.1", "nodemailer": "^6.9.2", diff --git a/src/components/calendar/Meeting.tsx b/src/components/calendar/Meeting.tsx new file mode 100644 index 00000000..ff3018d1 --- /dev/null +++ b/src/components/calendar/Meeting.tsx @@ -0,0 +1,86 @@ +import { Menu} from '@headlessui/react' +import {format, parseISO} from 'date-fns' +import { DotsVerticalIcon } from '@heroicons/react/outline' + +export type Meeting = { + id: number + title: string | null + start: string + end: string +} +export type meeting = { + meeting: Meeting +} + +function combineClasses(classes: string[]) { + return classes.join('') +} + +export default function Meeting({meeting}: meeting) { + const startDateTime = parseISO(meeting.start) + const endDateTime = parseISO(meeting.end) + + return ( +
  • +
    +

    {meeting.title}

    +

    + {' '} + -{' '} + +

    +
    + +
    + + Open options + +
    + +
    + + {({ active }) => ( + + )} + + + {({ active }) => ( + + )} + +
    +
    +
    +
  • + ) + } + + \ No newline at end of file diff --git a/src/components/calendar/SideCalendar.tsx b/src/components/calendar/SideCalendar.tsx new file mode 100644 index 00000000..23d7be80 --- /dev/null +++ b/src/components/calendar/SideCalendar.tsx @@ -0,0 +1,179 @@ +import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/solid' +import { + add, + eachDayOfInterval, + endOfMonth, + getDay, + format, + parseISO, + isEqual, + isSameDay, + isSameMonth, + isToday, + parse, + startOfToday, +} from 'date-fns' +import { useState } from 'react' +import Meeting from './Meeting' + +export type Meeting = { + id: number + title: string | null + start: string + end: string +} + +export type Meetings = { + meetings: Meeting[] +} + +function classNames(...classes) { + return classes.filter(Boolean).join(' ') + } + +export default function SideCalendar({meetings}: Meetings) { + const today = startOfToday() + const [selectedDay, setSelectedDay] = useState(today) + const [currentMonth, setCurrentMonth] = useState(format(today, 'MMM-yyyy')) + const firstDayCurrentMonth = parse(currentMonth, 'MMM-yyyy', new Date()) + + const days = eachDayOfInterval({ + start: firstDayCurrentMonth, + end: endOfMonth(firstDayCurrentMonth), + }) + + function previousMonth() { + const firstDayNextMonth = add(firstDayCurrentMonth, { months: -1 }) + setCurrentMonth(format(firstDayNextMonth, 'MMM-yyyy')) + } + + function nextMonth() { + const firstDayNextMonth = add(firstDayCurrentMonth, { months: 1 }) + setCurrentMonth(format(firstDayNextMonth, 'MMM-yyyy')) + } + + const selectedDayMeetings = meetings?.filter((meeting) => + isSameDay(parseISO(meeting.start), selectedDay) + ) + + return ( +
    +
    +
    +
    +
    +

    + {format(firstDayCurrentMonth, 'MMMM yyyy')} +

    + + +
    +
    +
    S
    +
    M
    +
    T
    +
    W
    +
    T
    +
    F
    +
    S
    +
    +
    + {days.map((day, dayIdx) => ( +
    + + +
    + {meetings?.some((meeting) => + isSameDay(parseISO(meeting.start), day) + ) && ( +
    + )} +
    +
    + ))} +
    +
    +
    +

    + {isSameDay(today, selectedDay) + ?'TODAY ' + : '' + } + +

    +
      + {selectedDayMeetings?.length > 0 ? ( + selectedDayMeetings?.map((meeting) => ( + + )) + ) : ( +

      No meetings for today.

      + )} +
    +
    +
    +
    +
    + ) +} + + +const colStartClasses = [ + '', + 'col-start-2', + 'col-start-3', + 'col-start-4', + 'col-start-5', + 'col-start-6', + 'col-start-7', +] diff --git a/src/components/common/TopNavbar.tsx b/src/components/common/TopNavbar.tsx index a87e1ee2..340a808a 100644 --- a/src/components/common/TopNavbar.tsx +++ b/src/components/common/TopNavbar.tsx @@ -37,6 +37,9 @@ const TopNavbar: React.FC = ({ isAdmin }) => { Profile + + Calendar +
    Sign Out
    @@ -55,6 +58,9 @@ const TopNavbar: React.FC = ({ isAdmin }) => { Events + + Calendar + ) diff --git a/src/pages/calendar/index.tsx b/src/pages/calendar/index.tsx new file mode 100644 index 00000000..32a0eee9 --- /dev/null +++ b/src/pages/calendar/index.tsx @@ -0,0 +1,89 @@ +import Layout from '~/components/common/Layout' +import Head from 'next/head' +import TopNavbar from '~/components/common/TopNavbar' +import withAuth, {type BaseProps} from '~/utils/withAuth' +import FullCalendar from '@fullcalendar/react' // must go before plugins +import dayGridPlugin from '@fullcalendar/daygrid' +import interactionPlugin from '@fullcalendar/interaction' +import timeGridPlugin from '@fullcalendar/timegrid' +import styled from "@emotion/styled"; +import { useState } from 'react' +import SideCalendar from '~/components/calendar/sideCalendar' + +// add styles as css +export const StyleWrapper = styled.div` +` + +const meetings = [ + { + id: 1, + title: 'Meeting 1', + start: '2023-05-11T13:00', + end: '2023-05-11T14:30', + }, + { + id: 2, + title: 'Meeting 2', + start: '2023-05-20T09:00', + end: '2023-05-20T11:30', + }, + { + id: 3, + title: 'Meeting 3', + start: '2023-05-20T17:00', + end: '2023-05-20T18:30', + }, + { + id: 4, + title: 'Meeting 4', + start: '2023-06-09T13:00', + end: '2023-06-09T14:30', + }, + { + id: 5, + title: 'Meeting 5', + start: '2023-05-13T14:00', + end: '2023-05-13T14:30', + }, +] + +const CalendarPage: React.FC = ({session}) => { + const [events, useEvents] = useState( + [ + { title: 'event 1', start: '2023-05-01T15:30' ,end: '2023-05-01T16:30'}, + { title: 'event 2', start: '2023-05-02T06:00' , end: '2023-05-02T07:00'} + ] + ); + return ( + <> + + Atlas | Calendar + + + + +
    + + + { + alert('Event: ' + info.event.title); + }} + + /> + +
    + + ) +} + +export default withAuth(CalendarPage, true) \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index f0e0b271..105c91b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -163,7 +163,7 @@ dependencies: regenerator-runtime "^0.13.11" -"@babel/runtime@^7.20.13": +"@babel/runtime@^7.20.13", "@babel/runtime@^7.21.0": version "7.21.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== @@ -1184,6 +1184,59 @@ aria-hidden "^1.1.3" tabbable "^6.0.1" +"@fullcalendar/core@~6.1.7": + version "6.1.7" + resolved "https://registry.yarnpkg.com/@fullcalendar/core/-/core-6.1.7.tgz#83d8b109fbf0deb1d4c3262ca4b2d70e77a287c4" + integrity sha512-Hc63ARSyABlNo10B3NkA0z8ndaDmq5MKpcBB2iQsGQyn8N8cyn/x6V284Je1EwDoKsBlbrZAj+j+efBO+QQf5g== + dependencies: + preact "~10.12.1" + +"@fullcalendar/daygrid@~6.1.7": + version "6.1.7" + resolved "https://registry.yarnpkg.com/@fullcalendar/daygrid/-/daygrid-6.1.7.tgz#529d5f1989081c5ab9d129fcaf409111b31be976" + integrity sha512-IB+QdRcs+TeTlsK8qJFtYZ/2GugmXEFC0C00/n1aLT7GLgFn3ueV1GN0EKvXv9HJ5ai8My65mYbSyQizY/Ishw== + +"@fullcalendar/interaction@~6.1.7": + version "6.1.7" + resolved "https://registry.yarnpkg.com/@fullcalendar/interaction/-/interaction-6.1.7.tgz#f2d86312371b284b46caae8c74b303e1fc7bdd4c" + integrity sha512-C2KHSinc9cFUTcGYxRSIj7cBYNSroce+1d2Wa+HKVHguVv4kQuEvm/oPxJpTLXqFjNLfxyxVac7Zd4U0znjFtg== + +"@fullcalendar/list@~6.1.7": + version "6.1.7" + resolved "https://registry.yarnpkg.com/@fullcalendar/list/-/list-6.1.7.tgz#27d1b11984c9e4fc66da9a71b2429d38c427be94" + integrity sha512-Fl6jGKylhrk+g/RCISsv66vzpzjCFhd4r3nUDeHTAAE375OYGlVPKpH67YaKxpMrofj82JLIzS3JEzyQBZo0Cg== + +"@fullcalendar/multimonth@~6.1.7": + version "6.1.7" + resolved "https://registry.yarnpkg.com/@fullcalendar/multimonth/-/multimonth-6.1.7.tgz#bec09460746abd96b147306c4b5a342c56dbf049" + integrity sha512-x4Z8XjmjlXNElZsVYr+AdNYiGPrYdmG3nxDYjxIDPl1CvH/pAmZinaRlOmVP4wq7ES9RP/9xOlAhe2/RKpsh3w== + dependencies: + "@fullcalendar/daygrid" "~6.1.7" + +"@fullcalendar/react@^6.1.7": + version "6.1.7" + resolved "https://registry.yarnpkg.com/@fullcalendar/react/-/react-6.1.7.tgz#acdfaa84b0b12a9a70b26a6e8d494c14de0d3b44" + integrity sha512-Pwe88D4zXwP/XQsYWOa1foroF/OpHSLet5CiE4crnaKvngEtzt3SBDIO01agQOpo+yE1KM/n3yE5ePbdJtVJIQ== + +"@fullcalendar/timegrid@~6.1.7": + version "6.1.7" + resolved "https://registry.yarnpkg.com/@fullcalendar/timegrid/-/timegrid-6.1.7.tgz#1c2dac33a7870928359f17a5e142d26f08022f79" + integrity sha512-kVgJVswu96LrCozr+GyYzF+LUZjURC4HyDg11tCfrj2wMTsrYKqUxilTGXuD3daD4T7qp3CLCg5GdD6lbYHI7A== + dependencies: + "@fullcalendar/daygrid" "~6.1.7" + +"@headlessui/react@^1.7.14": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.14.tgz#75f19552c535113640fe8a3a40e71474f49e89c9" + integrity sha512-znzdq9PG8rkwcu9oQ2FwIy0ZFtP9Z7ycS+BAqJ3R5EIqC/0bJGvhT7193rFf+45i9nnPsYvCQVW4V/bB9Xc+gA== + dependencies: + client-only "^0.0.1" + +"@heroicons/react@v1": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-1.0.6.tgz#35dd26987228b39ef2316db3b1245c42eb19e324" + integrity sha512-JJCXydOFWMDpCP4q13iEplA503MQO3xLoZiKum+955ZCtHINWnx26CUxVxxFQu/uLb4LW3ge15ZpzIkXKkJ8oQ== + "@hookform/resolvers@^2.9.10": version "2.9.11" resolved "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-2.9.11.tgz" @@ -2010,7 +2063,7 @@ classnames@^2.2.6, classnames@^2.3.2: resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== -client-only@0.0.1: +client-only@0.0.1, client-only@^0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== @@ -2146,6 +2199,13 @@ damerau-levenshtein@^1.0.8: resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== +date-fns@^2.30.0: + version "2.30.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== + dependencies: + "@babel/runtime" "^7.21.0" + dayjs@^1.11.7: version "1.11.7" resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz" @@ -2793,6 +2853,18 @@ fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +fullcalendar@^6.1.7: + version "6.1.7" + resolved "https://registry.yarnpkg.com/fullcalendar/-/fullcalendar-6.1.7.tgz#f1ab71bd128a584359b4c823ac93646d01c6dd17" + integrity sha512-e4KF/wf0gOilgDRAhOOJZrAzzPqDDAGF0SogyM0rTrZvn4HgC3ZL9CfBttc4juMMnmKQGNcGt649+ZnG+zxUTA== + dependencies: + "@fullcalendar/core" "~6.1.7" + "@fullcalendar/daygrid" "~6.1.7" + "@fullcalendar/interaction" "~6.1.7" + "@fullcalendar/list" "~6.1.7" + "@fullcalendar/multimonth" "~6.1.7" + "@fullcalendar/timegrid" "~6.1.7" + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3840,6 +3912,11 @@ preact@^10.6.3: resolved "https://registry.yarnpkg.com/preact/-/preact-10.13.2.tgz#2c40c73d57248b57234c4ae6cd9ab9d8186ebc0a" integrity sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw== +preact@~10.12.1: + version "10.12.1" + resolved "https://registry.yarnpkg.com/preact/-/preact-10.12.1.tgz#8f9cb5442f560e532729b7d23d42fd1161354a21" + integrity sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" From cb71c79ef1c27047ffe2597533a42200d7a4fa8e Mon Sep 17 00:00:00 2001 From: woowenjun99 Date: Sun, 21 May 2023 18:26:46 +0800 Subject: [PATCH 002/223] Remove unused bottom navbar and layout --- src/components/calendar/SideCalendar.tsx | 2 +- src/components/common/BottomNavbar.tsx | 62 ------------------------ src/components/common/Layout.tsx | 14 ------ src/components/common/TopNavbar.tsx | 4 +- src/pages/calendar/index.tsx | 51 +++++++++---------- src/pages/users/index.tsx | 10 ++-- 6 files changed, 30 insertions(+), 113 deletions(-) delete mode 100644 src/components/common/BottomNavbar.tsx delete mode 100644 src/components/common/Layout.tsx diff --git a/src/components/calendar/SideCalendar.tsx b/src/components/calendar/SideCalendar.tsx index 23d7be80..341fa635 100644 --- a/src/components/calendar/SideCalendar.tsx +++ b/src/components/calendar/SideCalendar.tsx @@ -27,7 +27,7 @@ export type Meetings = { meetings: Meeting[] } -function classNames(...classes) { +function classNames(...classes: any[]) { return classes.filter(Boolean).join(' ') } diff --git a/src/components/common/BottomNavbar.tsx b/src/components/common/BottomNavbar.tsx deleted file mode 100644 index 3e895d01..00000000 --- a/src/components/common/BottomNavbar.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import Image from 'next/image' -import Link from 'next/link' - -const BottomNavBar = () => { - return ( -
    -
    - {TabConfig.map(({ href, src, title }, index) => ( - - ))} -
    -
    - ) -} - -export default BottomNavBar - -const TabButton = ({ href, src, title }: TabButtonProps) => { - return ( -
    - -
    - Home - {title} -
    - -
    - ) -} - -type TabButtonProps = { - href: string - src: string - title: string -} - -const TabConfig: TabButtonProps[] = [ - { - href: '/', - src: '/mobile/home.svg', - title: 'Home', - }, - { - href: '/event', - src: '/mobile/event.svg', - title: 'Event', - }, - { - href: '/profile', - src: '/mobile/profile.svg', - title: 'Profile', - }, -] diff --git a/src/components/common/Layout.tsx b/src/components/common/Layout.tsx deleted file mode 100644 index 4ffcd6c7..00000000 --- a/src/components/common/Layout.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import BottomNavBar from './BottomNavbar' - -const Layout = ({ children }: { children: JSX.Element[] | JSX.Element }) => { - return ( - <> -
    - {children} -
    - - - ) -} - -export default Layout diff --git a/src/components/common/TopNavbar.tsx b/src/components/common/TopNavbar.tsx index 340a808a..b66bc11b 100644 --- a/src/components/common/TopNavbar.tsx +++ b/src/components/common/TopNavbar.tsx @@ -37,7 +37,7 @@ const TopNavbar: React.FC = ({ isAdmin }) => { Profile - + Calendar @@ -59,7 +59,7 @@ const TopNavbar: React.FC = ({ isAdmin }) => { Events - Calendar + Recruitment diff --git a/src/pages/calendar/index.tsx b/src/pages/calendar/index.tsx index 32a0eee9..80fe7e0f 100644 --- a/src/pages/calendar/index.tsx +++ b/src/pages/calendar/index.tsx @@ -1,18 +1,16 @@ -import Layout from '~/components/common/Layout' import Head from 'next/head' import TopNavbar from '~/components/common/TopNavbar' -import withAuth, {type BaseProps} from '~/utils/withAuth' +import withAuth, { type BaseProps } from '~/utils/withAuth' import FullCalendar from '@fullcalendar/react' // must go before plugins import dayGridPlugin from '@fullcalendar/daygrid' import interactionPlugin from '@fullcalendar/interaction' import timeGridPlugin from '@fullcalendar/timegrid' -import styled from "@emotion/styled"; +import styled from '@emotion/styled' import { useState } from 'react' -import SideCalendar from '~/components/calendar/sideCalendar' +import SideCalendar from '~/components/calendar/SideCalendar' // add styles as css -export const StyleWrapper = styled.div` -` +export const StyleWrapper = styled.div`` const meetings = [ { @@ -47,13 +45,11 @@ const meetings = [ }, ] -const CalendarPage: React.FC = ({session}) => { - const [events, useEvents] = useState( - [ - { title: 'event 1', start: '2023-05-01T15:30' ,end: '2023-05-01T16:30'}, - { title: 'event 2', start: '2023-05-02T06:00' , end: '2023-05-02T07:00'} - ] - ); +const CalendarPage: React.FC = ({ session }) => { + const [events, useEvents] = useState([ + { title: 'event 1', start: '2023-05-01T15:30', end: '2023-05-01T16:30' }, + { title: 'event 2', start: '2023-05-02T06:00', end: '2023-05-02T07:00' }, + ]) return ( <> @@ -63,27 +59,26 @@ const CalendarPage: React.FC = ({session}) => {
    - - - + + { - alert('Event: ' + info.event.title); + alert('Event: ' + info.event.title) }} - - /> - -
    + /> + + ) } -export default withAuth(CalendarPage, true) \ No newline at end of file +export default withAuth(CalendarPage, true) diff --git a/src/pages/users/index.tsx b/src/pages/users/index.tsx index 3569e37d..448c0c30 100644 --- a/src/pages/users/index.tsx +++ b/src/pages/users/index.tsx @@ -1,10 +1,9 @@ -import Layout from '~/components/common/Layout' import Head from 'next/head' import DataTable from '~/components/users/Table' import TopNavbar from '~/components/common/TopNavbar' -import withAuth, {type BaseProps} from '~/utils/withAuth' +import withAuth, { type BaseProps } from '~/utils/withAuth' -const AdminUserPage: React.FC = ({session}) => { +const AdminUserPage: React.FC = ({ session }) => { return ( <> @@ -13,9 +12,8 @@ const AdminUserPage: React.FC = ({session}) => { - - - + + ) } From 601201aa03fecff47f75f0d7731f7a2498fdef90 Mon Sep 17 00:00:00 2001 From: woowenjun99 Date: Sun, 21 May 2023 18:33:46 +0800 Subject: [PATCH 003/223] Refactor out the MainCalendar --- src/components/calendar/MainCalendar.tsx | 36 ++++++ src/components/calendar/Meeting.tsx | 143 +++++++++++------------ src/components/calendar/SideCalendar.tsx | 51 ++++---- src/pages/calendar/index.tsx | 31 +---- 4 files changed, 133 insertions(+), 128 deletions(-) create mode 100644 src/components/calendar/MainCalendar.tsx diff --git a/src/components/calendar/MainCalendar.tsx b/src/components/calendar/MainCalendar.tsx new file mode 100644 index 00000000..c41863d1 --- /dev/null +++ b/src/components/calendar/MainCalendar.tsx @@ -0,0 +1,36 @@ +import FullCalendar from '@fullcalendar/react' // must go before plugins +import dayGridPlugin from '@fullcalendar/daygrid' +import interactionPlugin from '@fullcalendar/interaction' +import timeGridPlugin from '@fullcalendar/timegrid' +import styled from '@emotion/styled' +import { useState } from 'react' + +export const StyleWrapper = styled.div`` + +const MainCalendar = () => { + const [events, useEvents] = useState([ + { title: 'event 1', start: '2023-05-01T15:30', end: '2023-05-01T16:30' }, + { title: 'event 2', start: '2023-05-02T06:00', end: '2023-05-02T07:00' }, + ]) + + return ( + + { + alert('Event: ' + info.event.title) + }} + /> + + ) +} + +export default MainCalendar diff --git a/src/components/calendar/Meeting.tsx b/src/components/calendar/Meeting.tsx index ff3018d1..7ef3363c 100644 --- a/src/components/calendar/Meeting.tsx +++ b/src/components/calendar/Meeting.tsx @@ -1,86 +1,83 @@ -import { Menu} from '@headlessui/react' -import {format, parseISO} from 'date-fns' +import { Menu } from '@headlessui/react' +import { format, parseISO } from 'date-fns' import { DotsVerticalIcon } from '@heroicons/react/outline' export type Meeting = { - id: number - title: string | null - start: string - end: string + id: number + title: string | null + start: string + end: string } export type meeting = { - meeting: Meeting + meeting: Meeting } function combineClasses(classes: string[]) { - return classes.join('') + return classes.join('') } -export default function Meeting({meeting}: meeting) { - const startDateTime = parseISO(meeting.start) - const endDateTime = parseISO(meeting.end) - - return ( -
  • -
    -

    {meeting.title}

    -

    - {' '} - -{' '} - -

    +export default function Meeting({ meeting }: meeting) { + const startDateTime = parseISO(meeting.start) + const endDateTime = parseISO(meeting.end) + + return ( +
  • +
    +

    {meeting.title}

    +

    + {' '} + - +

    +
    + +
    + + Open options +
    - -
    - - Open options - -
    - -
    - - {({ active }) => ( - + +
    + + {({ active }) => ( + + onClick={() => { + alert('You want to edit meeting') + }} + > + Edit Meeting + + )} + + + {({ active }) => ( +
    -
    -
    -
  • - ) - } - - \ No newline at end of file + onClick={() => { + alert('You want to cancel meeting') + }} + > + Cancel Meeting + + )} + + + + + + ) +} diff --git a/src/components/calendar/SideCalendar.tsx b/src/components/calendar/SideCalendar.tsx index 341fa635..f5a4a7fe 100644 --- a/src/components/calendar/SideCalendar.tsx +++ b/src/components/calendar/SideCalendar.tsx @@ -17,21 +17,21 @@ import { useState } from 'react' import Meeting from './Meeting' export type Meeting = { - id: number - title: string | null - start: string - end: string + id: number + title: string | null + start: string + end: string } export type Meetings = { - meetings: Meeting[] + meetings: Meeting[] } function classNames(...classes: any[]) { - return classes.filter(Boolean).join(' ') - } + return classes.filter(Boolean).join(' ') +} -export default function SideCalendar({meetings}: Meetings) { +export default function SideCalendar({ meetings }: Meetings) { const today = startOfToday() const [selectedDay, setSelectedDay] = useState(today) const [currentMonth, setCurrentMonth] = useState(format(today, 'MMM-yyyy')) @@ -54,15 +54,15 @@ export default function SideCalendar({meetings}: Meetings) { const selectedDayMeetings = meetings?.filter((meeting) => isSameDay(parseISO(meeting.start), selectedDay) - ) + ) return ( -
    -
    +
    +
    -

    +

    {format(firstDayCurrentMonth, 'MMMM yyyy')}

    -
    +
    S
    M
    T
    @@ -91,7 +91,7 @@ export default function SideCalendar({meetings}: Meetings) {
    F
    S
    -
    +
    {days.map((day, dayIdx) => (
    -
    -

    - {isSameDay(today, selectedDay) - ?'TODAY ' - : '' - } +

    + {isSameDay(today, selectedDay) ? 'TODAY ' : ''} @@ -154,7 +154,7 @@ export default function SideCalendar({meetings}: Meetings) {
      {selectedDayMeetings?.length > 0 ? ( selectedDayMeetings?.map((meeting) => ( - + )) ) : (

      No meetings for today.

      @@ -167,7 +167,6 @@ export default function SideCalendar({meetings}: Meetings) { ) } - const colStartClasses = [ '', 'col-start-2', diff --git a/src/pages/calendar/index.tsx b/src/pages/calendar/index.tsx index 80fe7e0f..d995dd8a 100644 --- a/src/pages/calendar/index.tsx +++ b/src/pages/calendar/index.tsx @@ -1,16 +1,8 @@ import Head from 'next/head' import TopNavbar from '~/components/common/TopNavbar' import withAuth, { type BaseProps } from '~/utils/withAuth' -import FullCalendar from '@fullcalendar/react' // must go before plugins -import dayGridPlugin from '@fullcalendar/daygrid' -import interactionPlugin from '@fullcalendar/interaction' -import timeGridPlugin from '@fullcalendar/timegrid' -import styled from '@emotion/styled' -import { useState } from 'react' import SideCalendar from '~/components/calendar/SideCalendar' - -// add styles as css -export const StyleWrapper = styled.div`` +import MainCalendar from '~/components/calendar/MainCalendar' const meetings = [ { @@ -46,10 +38,6 @@ const meetings = [ ] const CalendarPage: React.FC = ({ session }) => { - const [events, useEvents] = useState([ - { title: 'event 1', start: '2023-05-01T15:30', end: '2023-05-01T16:30' }, - { title: 'event 2', start: '2023-05-02T06:00', end: '2023-05-02T07:00' }, - ]) return ( <> @@ -60,22 +48,7 @@ const CalendarPage: React.FC = ({ session }) => {
      - - { - alert('Event: ' + info.event.title) - }} - /> - +
      ) From b4dc271fd2ab00bcef721b6e34938d3693f99155 Mon Sep 17 00:00:00 2001 From: woowenjun99 Date: Thu, 25 May 2023 21:12:45 +0800 Subject: [PATCH 004/223] Remove the Announcement model --- prisma/schema.prisma | 33 ++++---------- src/server/trpc/router/_app.ts | 2 - .../trpc/router/admin/announcement/create.ts | 43 ------------------- .../trpc/router/admin/announcement/index.ts | 8 ---- .../trpc/router/admin/announcement/read.ts | 21 --------- 5 files changed, 9 insertions(+), 98 deletions(-) delete mode 100644 src/server/trpc/router/admin/announcement/create.ts delete mode 100644 src/server/trpc/router/admin/announcement/index.ts delete mode 100644 src/server/trpc/router/admin/announcement/read.ts diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 5f91e6d2..2d305286 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -21,37 +21,23 @@ model Projects { } model Departments { - department_id String @id + department_id String @id name String - announcements Announcements[] projects Projects[] } -model Announcements { - announcement_id String @id - content String - image String? - title String - updated_date DateTime - uploaded_date DateTime - department_id String? - userId String - Departments Departments? @relation(fields: [department_id], references: [department_id]) - created_by User @relation(fields: [userId], references: [id]) -} - model User { - attendance Int? @default(0) + attendance Int? @default(0) batch String? department String? diet String? discord String? - email String @unique + email String @unique faculty String? gender String? hashedPassword String hobbies String? - id String @id + id String @id image String? level String linkedin String? @@ -63,15 +49,14 @@ model User { roles String? shirt String? telegram String? - total_events Int? @default(0) + total_events Int? @default(0) wallet String? year String? date_of_birth DateTime? - isAdmin Boolean? @default(false) - announcements Announcements[] - events Event[] @relation("EventToUser") - projects Projects[] @relation("ProjectsToUser") - Attendance Attendance[] @relation("attendanceToUser") + isAdmin Boolean? @default(false) + events Event[] @relation("EventToUser") + projects Projects[] @relation("ProjectsToUser") + Attendance Attendance[] @relation("attendanceToUser") AttendanceTaken Attendance[] } diff --git a/src/server/trpc/router/_app.ts b/src/server/trpc/router/_app.ts index 35d6a63c..3bb29760 100644 --- a/src/server/trpc/router/_app.ts +++ b/src/server/trpc/router/_app.ts @@ -1,6 +1,5 @@ import { router } from '../trpc' import { authRouter } from './auth' -import { announcementRouter } from './admin/announcement' import { memberRouter } from './member' import { profileRouter } from './profile' import { userRouter } from './admin/users' @@ -9,7 +8,6 @@ import { attendanceRouter } from './admin/attendance' export const appRouter = router({ auth: authRouter, - announcement: announcementRouter, event: eventRouter, member: memberRouter, profile: profileRouter, diff --git a/src/server/trpc/router/admin/announcement/create.ts b/src/server/trpc/router/admin/announcement/create.ts deleted file mode 100644 index 27d7b11c..00000000 --- a/src/server/trpc/router/admin/announcement/create.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { protectedProcedure } from '~/server/trpc/trpc' -import { TRPCError } from '@trpc/server' -import { z } from 'zod' -import { randomUUID } from 'crypto' -import dayjs from 'dayjs' - -export default protectedProcedure - .input( - z.object({ - content: z.string(), - title: z.string(), - }) - ) - .mutation(async ({ ctx, input }) => { - try { - const user = await ctx.prisma.user.findUnique({ - where: { id: ctx.session.user.id }, - }) - - if (!user || user.level !== 'super') { - throw new TRPCError({ - code: 'UNAUTHORIZED', - message: 'You cannot create an event', - }) - } - - await ctx.prisma.announcements.create({ - data: { - announcement_id: randomUUID(), - content: input.content, - title: input.title, - updated_date: dayjs().toDate(), - uploaded_date: dayjs().toDate(), - userId: ctx.session.user.id, - }, - }) - } catch (e) { - throw new TRPCError({ - code: 'INTERNAL_SERVER_ERROR', - message: (e as Error).message, - }) - } - }) diff --git a/src/server/trpc/router/admin/announcement/index.ts b/src/server/trpc/router/admin/announcement/index.ts deleted file mode 100644 index 33c617e2..00000000 --- a/src/server/trpc/router/admin/announcement/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { router } from '~/server/trpc/trpc' -import createAnnouncements from './create' -import readAnnouncements from './read' - -export const announcementRouter = router({ - createAnnouncements, - readAnnouncements, -}) diff --git a/src/server/trpc/router/admin/announcement/read.ts b/src/server/trpc/router/admin/announcement/read.ts deleted file mode 100644 index a57a1f96..00000000 --- a/src/server/trpc/router/admin/announcement/read.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { protectedProcedure } from '~/server/trpc/trpc' -import { TRPCError } from '@trpc/server' - -export default protectedProcedure.query(async ({ ctx }) => { - try { - const announcements = await ctx.prisma.announcements.findMany({ - include: { - created_by: { - select: { name: true }, - }, - }, - }) - - return announcements - } catch (e) { - throw new TRPCError({ - code: 'INTERNAL_SERVER_ERROR', - message: (e as Error).message, - }) - } -}) From 98de923a3838985c68fe75c527faaafdb21897f1 Mon Sep 17 00:00:00 2001 From: woowenjun99 Date: Thu, 25 May 2023 22:10:04 +0800 Subject: [PATCH 005/223] Update the user schema --- prisma/schema.prisma | 9 +-------- src/components/attendance/DataTableModal.tsx | 9 ++------- src/components/events/DataTable.tsx | 4 ++-- src/components/profile/ProfileGrid.tsx | 2 +- src/components/users/CreateMultipleUsers.tsx | 4 +--- src/components/users/EditModal.tsx | 2 +- src/components/users/ProfileModal.tsx | 4 ++-- src/components/users/SingleUserForm.tsx | 12 ++++-------- src/components/users/Table.tsx | 4 ++-- src/components/users/UserTable.tsx | 2 +- src/server/trpc/router/admin/users/index.ts | 4 ++-- src/server/trpc/router/events/index.ts | 4 ++-- src/server/trpc/router/member/create.ts | 10 ++++------ src/server/trpc/router/member/helper.ts | 14 ++++---------- src/server/trpc/router/member/read.ts | 8 ++++---- src/server/trpc/router/member/update.ts | 4 ++-- src/types/admin.type.ts | 4 +--- src/types/event/event.type.ts | 2 +- 18 files changed, 37 insertions(+), 65 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 2d305286..b50480b7 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -27,32 +27,25 @@ model Departments { } model User { - attendance Int? @default(0) batch String? department String? - diet String? discord String? email String @unique faculty String? gender String? hashedPassword String - hobbies String? id String @id image String? - level String linkedin String? major String? name String? phone String? personal_email String? - race String? - roles String? - shirt String? + role String telegram String? total_events Int? @default(0) wallet String? year String? - date_of_birth DateTime? isAdmin Boolean? @default(false) events Event[] @relation("EventToUser") projects Projects[] @relation("ProjectsToUser") diff --git a/src/components/attendance/DataTableModal.tsx b/src/components/attendance/DataTableModal.tsx index 69c4d553..e0d0f805 100644 --- a/src/components/attendance/DataTableModal.tsx +++ b/src/components/attendance/DataTableModal.tsx @@ -63,12 +63,7 @@ const Body: React.FC<{ data: BodyProps | null | undefined }> = ({ data }) => { <> {data.qr_code && (
      - event-qr + event-qr
      )}

      Department:

      @@ -91,7 +86,7 @@ const Body: React.FC<{ data: BodyProps | null | undefined }> = ({ data }) => { {index + 1} {attendee.name} {attendee.department} - {attendee.roles} + {attendee.role} {data.attended.has(attendee.id) ? 'Yes' : 'No'} ) diff --git a/src/components/events/DataTable.tsx b/src/components/events/DataTable.tsx index b66a0af4..29986aae 100644 --- a/src/components/events/DataTable.tsx +++ b/src/components/events/DataTable.tsx @@ -31,7 +31,7 @@ import React, { useEffect, useRef, useState, type HTMLProps } from 'react' export type Attendees = { department: string | null - roles: string | null + role: string | null name: string | null id: string } @@ -94,7 +94,7 @@ export function DataTable({ data, setAttendees }: DataTableProps) { enableColumnFilter: true, filterFn: MultiSelectFilterFn, }), - columnHelper.accessor('roles', { + columnHelper.accessor('role', { cell: (info) => info.getValue(), header: 'Role', enableColumnFilter: true, diff --git a/src/components/profile/ProfileGrid.tsx b/src/components/profile/ProfileGrid.tsx index 7b9ea71c..c32f2a17 100644 --- a/src/components/profile/ProfileGrid.tsx +++ b/src/components/profile/ProfileGrid.tsx @@ -30,7 +30,7 @@ const ProfileGrid = ({ refetch={refetch} name={data.user.name} dept={data.user.department} - role={data.user.roles} + role={data.user.role} studentId={studentId} session={session} /> diff --git a/src/components/users/CreateMultipleUsers.tsx b/src/components/users/CreateMultipleUsers.tsx index 5fa74b87..af2bad68 100644 --- a/src/components/users/CreateMultipleUsers.tsx +++ b/src/components/users/CreateMultipleUsers.tsx @@ -30,7 +30,6 @@ const CreateMultipleUsers = () => { ], faculty: item['Faculty'] || '', gender: item['Gender '] || 'Male', - hobbies: item['Hobbies '] || '', linkedin: item['LinkedIn profile LINK (eg. www.linkedin.com/in/XXX)'], major: item['Major and Specialization (if any)'] || '', @@ -39,8 +38,7 @@ const CreateMultipleUsers = () => { personal_email: item['Gmail'], phone: item['Phone Number'], race: item['Race '] || '', - roles: item['Appointed Role '] || '', - shirt: item['Shirt size'] || '', + role: item['Appointed Role '] || '', student_id: item['Student ID (AXXXXXXXX)'] || '', telegram: item['Telegram Handle(@xxx)'] || '', year: item['Year of Study'] || '', diff --git a/src/components/users/EditModal.tsx b/src/components/users/EditModal.tsx index 4d6ce39c..f70cf516 100644 --- a/src/components/users/EditModal.tsx +++ b/src/components/users/EditModal.tsx @@ -38,7 +38,7 @@ const EditModal: React.FC = (props) => { name: data.name, email: data.email, department: data.department, - roles: data.roles, + role: data.roles, } await mutateAsync(projData) toast({ diff --git a/src/components/users/ProfileModal.tsx b/src/components/users/ProfileModal.tsx index 97cbd7e5..393d9616 100644 --- a/src/components/users/ProfileModal.tsx +++ b/src/components/users/ProfileModal.tsx @@ -252,7 +252,7 @@ const ProfileInfo = (props: ProfilePageType) => { ROLE - {props.roles} + {props.role} GENDER @@ -337,7 +337,7 @@ const PersonalInformationModal = ({ type ProfilePageType = { name: string | null - roles: string | null + role: string | null gender: string | null batch: string | null year: string | null diff --git a/src/components/users/SingleUserForm.tsx b/src/components/users/SingleUserForm.tsx index 5aec9bdd..902b6669 100644 --- a/src/components/users/SingleUserForm.tsx +++ b/src/components/users/SingleUserForm.tsx @@ -12,20 +12,18 @@ import { useState, type FormEvent } from 'react' const SingleUserForm = () => { const router = useRouter() - const { mutateAsync } = trpc.member.createSingleUser.useMutation() + const { mutateAsync, isLoading } = trpc.member.createSingleUser.useMutation() const toast = useToast() const [email, setEmail] = useState('') const [password, setPassword] = useState('') - const [level, setLevel] = useState('') + const [role, setRole] = useState('') const [id, setId] = useState('') - const [isLoading, setIsLoading] = useState(false) const [isAdmin, setIsAdmin] = useState(false) const handleSubmit = async (e: FormEvent) => { try { e.preventDefault() - setIsLoading(true) - await mutateAsync({ email, password, level, id, isAdmin }) + await mutateAsync({ email, password, id, isAdmin, role }) toast({ title: 'Successfully updated!', description: 'User successfully created', @@ -33,9 +31,7 @@ const SingleUserForm = () => { isClosable: true, duration: 9000, }) - setIsLoading(false) } catch (e) { - setIsLoading(false) toast({ title: 'Oops, something went wrong!', description: 'An error went wrong while creating the user', @@ -86,7 +82,7 @@ const SingleUserForm = () => { setSearchQuery(e.target.value)} + borderWidth="3px" + border="3px solid #004586" + borderColor="#004586" + borderRadius="20px" + > + + ) +} + +export default SearchBar diff --git a/src/pages/recruitment/applicants.tsx b/src/pages/recruitment/applicants.tsx new file mode 100644 index 00000000..66dbf9a9 --- /dev/null +++ b/src/pages/recruitment/applicants.tsx @@ -0,0 +1,28 @@ +import { Text } from '@chakra-ui/react' +import Head from 'next/head' +import Layout from '~/components/common/Layout' +import TopNavbar from '~/components/common/TopNavbar' +import SearchBar from '~/components/common/SearchBar' +import withAuth, { type BaseProps } from '~/utils/withAuth' + +const ApplicantsPage: React.FC = ({ session }) => { + return ( + <> + + Atlas | Applicants + + + + + + Applicants + + + + ) +} + +export default withAuth(ApplicantsPage, true) diff --git a/src/pages/recruitment/index.tsx b/src/pages/recruitment/index.tsx new file mode 100644 index 00000000..5567a9cc --- /dev/null +++ b/src/pages/recruitment/index.tsx @@ -0,0 +1,23 @@ +import Layout from '~/components/common/Layout' +import Head from 'next/head' +import TopNavbar from '~/components/common/TopNavbar' +import withAuth, { type BaseProps } from '~/utils/withAuth' +import { Text } from '@chakra-ui/react' + +const RecruitmentPage: React.FC = ({ session }) => { + return ( + <> + + Atlas | Recruitment + + + + + + Recruitment + + + ) +} + +export default withAuth(RecruitmentPage, true) From 78838ff33eee12d0443e85bcd3aec55828e88fa1 Mon Sep 17 00:00:00 2001 From: michaelseyo <76872115+michaelseyo@users.noreply.github.com> Date: Wed, 17 May 2023 22:39:32 +0800 Subject: [PATCH 008/223] create applicants directors page base components --- public/images/applicantcard_bg.svg | 7 ++ src/components/recruitment/ApplicantCard.tsx | 71 ++++++++++++++++ src/components/recruitment/ApplicantGrid.tsx | 16 ++++ src/components/recruitment/DocumentModal.tsx | 51 ++++++++++++ .../recruitment/DocumentModalAddButton.tsx | 21 +++++ .../recruitment/DocumentModalCard.tsx | 18 +++++ src/components/recruitment/EditModal.tsx | 80 +++++++++++++++++++ src/components/recruitment/InfoPopup.tsx | 80 +++++++++++++++++++ src/components/recruitment/NoteModal.tsx | 41 ++++++++++ src/pages/recruitment/applicants.tsx | 4 + 10 files changed, 389 insertions(+) create mode 100644 public/images/applicantcard_bg.svg create mode 100644 src/components/recruitment/ApplicantCard.tsx create mode 100644 src/components/recruitment/ApplicantGrid.tsx create mode 100644 src/components/recruitment/DocumentModal.tsx create mode 100644 src/components/recruitment/DocumentModalAddButton.tsx create mode 100644 src/components/recruitment/DocumentModalCard.tsx create mode 100644 src/components/recruitment/EditModal.tsx create mode 100644 src/components/recruitment/InfoPopup.tsx create mode 100644 src/components/recruitment/NoteModal.tsx diff --git a/public/images/applicantcard_bg.svg b/public/images/applicantcard_bg.svg new file mode 100644 index 00000000..db3821ed --- /dev/null +++ b/public/images/applicantcard_bg.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/components/recruitment/ApplicantCard.tsx b/src/components/recruitment/ApplicantCard.tsx new file mode 100644 index 00000000..5bfd27db --- /dev/null +++ b/src/components/recruitment/ApplicantCard.tsx @@ -0,0 +1,71 @@ +import { + Box, + Card, + CardBody, + CardHeader, + Heading, + Image, + ListIcon, + ListItem, + Stack, + Text, + UnorderedList, +} from '@chakra-ui/react' +import { Avatar } from 'flowbite-react' +import { BsCircleFill } from 'react-icons/bs' +import DocumentModal from './DocumentModal' +import EditModal from './EditModal' +import NoteModal from './NoteModal' + +const ApplicantCard = () => { + return ( + + + + Name + + + blue wave background + + + + + + + + + + + + + 1. SD - Software Engineer + + + + 2. ML - Role + + + + 3. IA - Director + + + + + + + ) +} + +export default ApplicantCard diff --git a/src/components/recruitment/ApplicantGrid.tsx b/src/components/recruitment/ApplicantGrid.tsx new file mode 100644 index 00000000..8306165a --- /dev/null +++ b/src/components/recruitment/ApplicantGrid.tsx @@ -0,0 +1,16 @@ +import ApplicantCard from './ApplicantCard' + +const ApplicantGrid = (data: any) => { + return ( +
      + + + + + + +
      + ) +} + +export default ApplicantGrid diff --git a/src/components/recruitment/DocumentModal.tsx b/src/components/recruitment/DocumentModal.tsx new file mode 100644 index 00000000..4c9477c3 --- /dev/null +++ b/src/components/recruitment/DocumentModal.tsx @@ -0,0 +1,51 @@ +import { + IconButton, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalHeader, + ModalOverlay, + useDisclosure, +} from '@chakra-ui/react' +import { BsFolder2Open } from 'react-icons/bs' +import DocumentModalAddButton from './DocumentModalAddButton' +import DocumentModalCard from './DocumentModalCard' + +const DocumentModal = () => { + const { isOpen, onOpen, onClose } = useDisclosure() + return ( + <> + } + bg="None" + _hover={{ background: 'None' }} + onClick={onOpen} + /> + + + + + [Username] Documents + + + +
      + + + +
      +
      +
      +
      + + ) +} + +export default DocumentModal diff --git a/src/components/recruitment/DocumentModalAddButton.tsx b/src/components/recruitment/DocumentModalAddButton.tsx new file mode 100644 index 00000000..b6a543ee --- /dev/null +++ b/src/components/recruitment/DocumentModalAddButton.tsx @@ -0,0 +1,21 @@ +import { AddIcon } from '@chakra-ui/icons' +import { IconButton } from '@chakra-ui/react' + +const DocumentModalAddButton = () => { + return ( + } + borderRadius="30px" + boxShadow="0px 8px 4px 2px rgba(0, 0, 0, 0.15)" + bg="white" + _hover={{ background: '#e4e8ff' }} + fontSize="40px" + p="12" + width="120px" + height="120px" + /> + ) +} + +export default DocumentModalAddButton diff --git a/src/components/recruitment/DocumentModalCard.tsx b/src/components/recruitment/DocumentModalCard.tsx new file mode 100644 index 00000000..2fe98acd --- /dev/null +++ b/src/components/recruitment/DocumentModalCard.tsx @@ -0,0 +1,18 @@ +import { Card, CardBody, Text } from '@chakra-ui/react' + +const DocumentModalCard = () => { + return ( + + + Transcript + + + ) +} + +export default DocumentModalCard diff --git a/src/components/recruitment/EditModal.tsx b/src/components/recruitment/EditModal.tsx new file mode 100644 index 00000000..299d1fba --- /dev/null +++ b/src/components/recruitment/EditModal.tsx @@ -0,0 +1,80 @@ +import { + Button, + FormControl, + FormLabel, + Grid, + GridItem, + IconButton, + Input, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Stack, + Text, + Textarea, + useDisclosure, +} from '@chakra-ui/react' +import { Avatar } from 'flowbite-react' +import { BsPencilSquare } from 'react-icons/bs' + +const EditModal = () => { + const { isOpen, onOpen, onClose } = useDisclosure() + return ( + <> + } + bg="None" + _hover={{ background: 'None' }} + onClick={onOpen} + /> + + + + Edit NAME + + + + + + + Application Status + + + + + Department + + + + + Interview Notes +