From be7d25739baa6f6ba30059713c701c4f5c631e54 Mon Sep 17 00:00:00 2001 From: Aaron Chan <42254254+aaronchan32@users.noreply.github.com> Date: Mon, 4 Nov 2024 00:39:41 -0800 Subject: [PATCH] feat: update register mobile --- .eslintrc.json | 1 + public/images/badge/vertical-bar.svg | 0 public/images/icons/newtab-icon.svg | 4 + public/images/icons/right-arrow-icon.svg | 3 + public/images/logos/stride-logo.svg | 18 +- src/app/badge/Badge.scss | 84 ++++++++ src/app/badge/page.tsx | 168 ++++++++++++++++ src/app/register/Register.scss | 112 +++++++++++ src/app/register/page.tsx | 91 ++++++++- src/app/styles/_var.scss | 7 +- src/components/Icons/BlockIcon.tsx | 6 +- src/components/Icons/CloseIcon.tsx | 33 ---- src/components/Icons/RightArrow.tsx | 12 +- .../MascotCircles/MascotCircles.scss | 42 ++++ .../MascotCircles/MascotCircles.tsx | 13 ++ src/components/Navbar/Navbar.scss | 2 + src/components/Register/FeeTag.tsx | 44 +++++ .../Register/FolderTabs/FolderTabs.scss | 40 +++- .../Register/FolderTabs/FolderTabs.tsx | 9 +- .../FormComponents/FormSelect/FormSelect.scss | 10 +- .../FormComponents/FormSelect/FormSelect.tsx | 9 +- .../FormComponents/FormText/FormText.scss | 9 +- .../FormComponents/FormText/FormText.tsx | 2 +- .../FormSteps/FormStep1/FormStep1.tsx | 13 +- .../FormSteps/FormStep2/FormStep2.tsx | 13 +- .../FormSteps/FormStep3/FormStep3.scss | 55 ++++-- .../FormSteps/FormStep3/FormStep3.tsx | 6 +- .../FormSteps/FormStep4/FormStep4.scss | 186 ++++++++++++++---- .../FormSteps/FormStep4/FormStep4.tsx | 68 +++++-- .../Register/Mascot/Hats/TestHat.tsx | 2 - src/components/Register/Mascot/Mascot.tsx | 2 +- .../Register/MascotBadge/HorizontalBar.tsx | 22 +++ .../Register/MascotBadge/VerticalBar.tsx | 22 +++ src/components/Register/Register.scss | 35 ---- src/components/Register/Register.tsx | 156 --------------- src/components/Register/StrideLogo.tsx | 46 +++++ src/components/Register/types.ts | 19 +- 37 files changed, 986 insertions(+), 378 deletions(-) create mode 100644 public/images/badge/vertical-bar.svg create mode 100644 public/images/icons/newtab-icon.svg create mode 100644 public/images/icons/right-arrow-icon.svg create mode 100644 src/app/badge/Badge.scss create mode 100644 src/app/badge/page.tsx create mode 100644 src/app/register/Register.scss delete mode 100644 src/components/Icons/CloseIcon.tsx create mode 100644 src/components/MascotCircles/MascotCircles.scss create mode 100644 src/components/MascotCircles/MascotCircles.tsx create mode 100644 src/components/Register/FeeTag.tsx create mode 100644 src/components/Register/MascotBadge/HorizontalBar.tsx create mode 100644 src/components/Register/MascotBadge/VerticalBar.tsx delete mode 100644 src/components/Register/Register.scss delete mode 100644 src/components/Register/Register.tsx create mode 100644 src/components/Register/StrideLogo.tsx diff --git a/.eslintrc.json b/.eslintrc.json index afa65d1..900918f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -12,6 +12,7 @@ "project": "./tsconfig.json" }, "rules": { + "react/no-unescaped-entities": "off", "react/jsx-props-no-spreading": "off", "jsx-a11y/label-has-associated-control": "off", "arrow-body-style": "off", diff --git a/public/images/badge/vertical-bar.svg b/public/images/badge/vertical-bar.svg new file mode 100644 index 0000000..e69de29 diff --git a/public/images/icons/newtab-icon.svg b/public/images/icons/newtab-icon.svg new file mode 100644 index 0000000..9eef9ff --- /dev/null +++ b/public/images/icons/newtab-icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/images/icons/right-arrow-icon.svg b/public/images/icons/right-arrow-icon.svg new file mode 100644 index 0000000..dfca9c5 --- /dev/null +++ b/public/images/icons/right-arrow-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/logos/stride-logo.svg b/public/images/logos/stride-logo.svg index 62f92c4..fd1ba36 100644 --- a/public/images/logos/stride-logo.svg +++ b/public/images/logos/stride-logo.svg @@ -1,10 +1,10 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/app/badge/Badge.scss b/src/app/badge/Badge.scss new file mode 100644 index 0000000..7ea44b1 --- /dev/null +++ b/src/app/badge/Badge.scss @@ -0,0 +1,84 @@ +#badge-page-container { + margin-top: $nav-height; + padding: $main-padding-mobile; + height: calc(100dvh - $nav-height); + font-family: $p-font; + display: flex; + flex-direction: column; + justify-content: space-between; + overflow: hidden; + + #badge-page-main-content { + height: 100%; + display: flex; + flex-direction: column; + @media (min-width: 580px) { + width: 30rem; + margin-inline: auto; + } + + form { + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100%; + } + + h1 { + margin-bottom: 2rem; + } + + #badge-form-body { + height: 100%; + } + } + + #badge-footer { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1.5rem; + + #current-step-small { + @media (min-width: 400px) { + display: none; + } + } + + #current-step-large { + display: none; + + @media (min-width: 400px) { + display: block; + } + } + + p { + font-size: 1.2rem; + } + + button { + border-radius: 22px; + padding: 0.5rem 1rem; + font-size: 1.2rem; + font-family: $p-font; + font-weight: 600; + display: flex; + gap: 0.5rem; + border: none; + align-items: center; + border: 2px solid $white; + cursor: pointer; + + .right-arrow { + transform: rotate(180deg); + color: white; + } + } + + .back-button { + background-color: transparent; + color: white; + } + } +} diff --git a/src/app/badge/page.tsx b/src/app/badge/page.tsx new file mode 100644 index 0000000..f7d0c1c --- /dev/null +++ b/src/app/badge/page.tsx @@ -0,0 +1,168 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { useForm } from 'react-hook-form'; +import { zodResolver } from '@hookform/resolvers/zod'; +import './Badge.scss'; +import FormStep1 from '@/components/Register/FormSteps/FormStep1/FormStep1'; +import { + RegistrationSchema, + TFormData, + ValidFieldNames +} from '@/components/Register/types'; +import RightArrow from '@/components/Icons/RightArrow'; +import FormStep2 from '@/components/Register/FormSteps/FormStep2/FormStep2'; +import FormStep3 from '@/components/Register/FormSteps/FormStep3/FormStep3'; +import FormStep4 from '@/components/Register/FormSteps/FormStep4/FormStep4'; +import Link from 'next/link'; + +export default function Register() { + const [nextButtonText, setNextButtonText] = useState('Next'); + const [currentFormStep, setCurrentFormStep] = useState(1); + const { + register, + control, + handleSubmit, + formState: { errors }, + trigger, + getValues + } = useForm({ + resolver: zodResolver(RegistrationSchema) + }); + + useEffect(() => { + if (currentFormStep === 4) { + setNextButtonText('Home'); + } else if (currentFormStep === 3) { + setNextButtonText('Finish'); + } else { + setNextButtonText('Next'); + } + }, [currentFormStep]); + + const onSubmit = async (data: TFormData) => { + try { + console.log(data); + } catch (e) { + console.error(e); + } + }; + + const handleFormNext = async () => { + // Input Validation for Steps 1 and 2 + if (currentFormStep <= 2) { + let fieldsToValidate: Array = [ + 'name', + 'pronouns', + 'year' + ]; + if (currentFormStep === 2) { + fieldsToValidate = ['email', 'link']; + } + + const isValid = await trigger(fieldsToValidate); + if (!isValid) return; + } + + if (currentFormStep === 3) { + handleSubmit(onSubmit)(); + } + + if (currentFormStep >= 4) { + // setOpen(false); + return; + } + setCurrentFormStep(currentFormStep + 1); + }; + + const handleFormPrev = () => { + if (currentFormStep <= 1) return; + setCurrentFormStep(currentFormStep - 1); + }; + + return ( + + + + {currentFormStep === 4 ? 'Badge Complete!' : 'Create Your Badge'} + + { + console.error('Validation errors:', validationError); + })} + className="modal-form" + > + + {currentFormStep === 1 && ( + + )} + {currentFormStep === 2 && ( + + )} + {currentFormStep === 3 && } + {currentFormStep === 4 && } + + + + + + ); +} diff --git a/src/app/register/Register.scss b/src/app/register/Register.scss new file mode 100644 index 0000000..41579af --- /dev/null +++ b/src/app/register/Register.scss @@ -0,0 +1,112 @@ +#register-page-container { + margin-top: $nav-height; + padding: $main-padding-mobile; + height: calc(100dvh - $nav-height); + display: flex; + flex-direction: column; + justify-content: space-between; + + #register-top { + #smaller-register-header { + font-size: 2.25rem; + text-align: center; + margin-bottom: 3rem; + + svg { + margin-top: 11px; + margin-inline: auto; + max-width: 13ch; + } + + @media (min-width: 400px) { + display: none; + } + } + + #larger-register-header { + display: none; + + @media (min-width: 400px) { + font-size: 4rem; + display: block; + width: fit-content; + margin-inline: auto; + + span { + display: flex; + align-items: center; + gap: 1rem; + margin-bottom: 1.25rem; + } + } + } + + @media (min-width: 400px) { + font-size: 1rem; + } + + > p { + margin-inline: auto; + max-width: 30ch; + + @media (min-width: 400px) { + max-width: 38ch; + } + } + } + + #register-bottom { + margin-top: auto; + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; + max-width: 17.5rem; + margin-inline: auto; + + a, + button { + width: 100%; + font-family: $p-font; + font-size: 1.25rem; + line-height: 100%; + text-decoration: none; + border-radius: 30px; + background: $white; + color: black; + border: 2px solid $white; + text-align: center; + display: flex; + align-items: center; + justify-content: center; + gap: 1rem; + padding: 0.5rem 1rem; + + @media (min-width: 400px) { + padding: 1rem 2rem; + } + } + + #luma-button-container { + width: 100%; + position: relative; + svg { + pointer-events: none; + position: absolute; + top: -30%; + right: -8%; + } + } + + #create-badge-button { + background-color: transparent; + color: white; + cursor: pointer; + } + + p { + font-size: 0.875rem; + text-align: center; + } + } +} diff --git a/src/app/register/page.tsx b/src/app/register/page.tsx index 824f781..ce8d0e2 100644 --- a/src/app/register/page.tsx +++ b/src/app/register/page.tsx @@ -1,9 +1,92 @@ -import Register from '@/components/Register/Register'; +'use client'; + +import Image from 'next/image'; +import './Register.scss'; +import { useEffect, useState } from 'react'; +import Link from 'next/link'; +import StrideLogo from '@/components/Register/StrideLogo'; +import FeeTag from '@/components/Register/FeeTag'; export default function RegisterPage() { + // This is to ensure users don't click on register button before the script is loaded + const [scriptLoaded, setScriptLoaded] = useState(false); + + useEffect(() => { + const script = document.createElement('script'); + script.src = 'https://embed.lu.ma/checkout-button.js'; + script.async = true; + document.body.appendChild(script); + setScriptLoaded(true); + + return () => { + document.body.removeChild(script); + }; + }, []); + return ( - - - + + + + Register For + + + + Register + + For + + + + Lorem Ipsum Dolor Sit Amet Include something about the $5 fee? + + + + + + + + {scriptLoaded ? 'Register On Luma' : 'Loading...'} + + + + + + Create Your Badge{' '} + + + + + + contact designatucsd@gmail.com for inquiries about financial + assistance + + + ); } diff --git a/src/app/styles/_var.scss b/src/app/styles/_var.scss index b1a2162..982cbab 100644 --- a/src/app/styles/_var.scss +++ b/src/app/styles/_var.scss @@ -3,10 +3,15 @@ $heading-font: var(--font-iosevka); $mono-font: var(--font-iosevka); $light-green: #68dea3; +$dark-green: #58c988; $white: #fbfefc; +$dark-gray: #565656; $mobile-breakpoint: 768px; -$tablet-breakpoint: 1366px; +$tablet-breakpoint: 1024px; + +// Stride Logo + DCo Logo + Logo Gap + padding +$nav-height: calc(60px + 12px + 10px + 2 * 3.75rem); $nav-padding-mobile: 24px; $nav-padding-desktop: 36px; diff --git a/src/components/Icons/BlockIcon.tsx b/src/components/Icons/BlockIcon.tsx index d684410..55881e5 100644 --- a/src/components/Icons/BlockIcon.tsx +++ b/src/components/Icons/BlockIcon.tsx @@ -17,9 +17,9 @@ export default function BlockIcon({ onClick }: BlockIconProps) { ); diff --git a/src/components/Icons/CloseIcon.tsx b/src/components/Icons/CloseIcon.tsx deleted file mode 100644 index f4f4956..0000000 --- a/src/components/Icons/CloseIcon.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { SVGProps } from 'react'; - -export function CloseIcon(props: SVGProps) { - return ( - - - - - - ); -} diff --git a/src/components/Icons/RightArrow.tsx b/src/components/Icons/RightArrow.tsx index fca8a3c..99a92ad 100644 --- a/src/components/Icons/RightArrow.tsx +++ b/src/components/Icons/RightArrow.tsx @@ -4,18 +4,16 @@ export default function RightArrow(props: SVGProps) { return ( ); diff --git a/src/components/MascotCircles/MascotCircles.scss b/src/components/MascotCircles/MascotCircles.scss new file mode 100644 index 0000000..08a8c79 --- /dev/null +++ b/src/components/MascotCircles/MascotCircles.scss @@ -0,0 +1,42 @@ +.mascot-circles-container { + display: grid; + place-items: center; + position: relative; + height: 100%; + bottom: -35%; + + .mascot-container { + position: absolute; + transform-origin: bottom; + margin-inline: auto; + width: 35%; + left: 0; + right: 0; + z-index: 1; + bottom: 15%; + } + + .half-badge-circle { + aspect-ratio: 1; + background-color: $white; + border-radius: 50%; + left: 0; + right: 0; + margin-inline: auto; + position: absolute; + z-index: 0; + + &.outer { + width: 100%; + background-color: #16643d; + } + &.middle { + width: 62.5%; + background-color: #68dea3; + } + &.inner { + width: 42.5%; + background-color: $white; + } + } +} diff --git a/src/components/MascotCircles/MascotCircles.tsx b/src/components/MascotCircles/MascotCircles.tsx new file mode 100644 index 0000000..9b66663 --- /dev/null +++ b/src/components/MascotCircles/MascotCircles.tsx @@ -0,0 +1,13 @@ +import Mascot from '../Register/Mascot/Mascot'; +import './MascotCircles.scss'; + +export default function MascotCircles() { + return ( + + + + + + + ); +} diff --git a/src/components/Navbar/Navbar.scss b/src/components/Navbar/Navbar.scss index 73aa0fd..937ee2f 100644 --- a/src/components/Navbar/Navbar.scss +++ b/src/components/Navbar/Navbar.scss @@ -1,5 +1,6 @@ #navbar { position: absolute; + top: 0; z-index: 1; padding: 3.5rem 3.75rem; display: flex; @@ -26,6 +27,7 @@ border: 2px solid $white; background: black; padding: 0.5rem 0.75rem; + padding-left: 8px; display: flex; align-items: center; gap: 0.5rem; diff --git a/src/components/Register/FeeTag.tsx b/src/components/Register/FeeTag.tsx new file mode 100644 index 0000000..f552e86 --- /dev/null +++ b/src/components/Register/FeeTag.tsx @@ -0,0 +1,44 @@ +import { SVGProps } from 'react'; + +export default function FeeTag(props: SVGProps) { + return ( + + + + + + + + ); +} diff --git a/src/components/Register/FolderTabs/FolderTabs.scss b/src/components/Register/FolderTabs/FolderTabs.scss index 5532186..2b35bb6 100644 --- a/src/components/Register/FolderTabs/FolderTabs.scss +++ b/src/components/Register/FolderTabs/FolderTabs.scss @@ -7,14 +7,23 @@ position: relative; padding: 0; margin: 0; - padding: 0.5rem 1.5rem; border: none; background: none; color: white; cursor: pointer; + padding: 0.5rem 1.25rem; + margin-left: 0.5rem; + + @media (min-width: 300px) { + margin-left: 1rem; + } + + @media (min-width: 400px) { + padding: 0.75rem 1.75rem; + } &:not(:first-child) { - margin-left: -10px; + margin-left: -12px; .active-line3 { display: none; } @@ -23,7 +32,20 @@ span { position: relative; z-index: 2; - font-size: 1.2rem; + font-family: $p-font; + font-size: 0.85rem; + + @media (min-width: 325px) { + font-size: 1rem; + } + + @media (min-width: 400px) { + font-size: 1rem; + } + + @media (min-width: 480px) { + font-size: 1.2rem; + } } &::before, @@ -40,19 +62,19 @@ } &::before { - border-radius: 10px 0 0 0; + border-radius: 8px 0 0 0; border-right: 0; left: 0; transform-origin: bottom; - transform: skew(-20deg); + transform: skew(-15deg); } &::after { - border-radius: 0 10px 0 0; + border-radius: 0 8px 0 0; border-left: 0; right: 0; transform-origin: bottom; - transform: skew(20deg); + transform: skew(15deg); } } @@ -77,7 +99,7 @@ border-right: 0; left: 0; transform-origin: bottom; - transform: skew(-20deg); + transform: skew(-15deg); } &::after { @@ -85,7 +107,7 @@ border-left: 0; right: 0; transform-origin: bottom; - transform: skew(20deg); + transform: skew(15deg); } } diff --git a/src/components/Register/FolderTabs/FolderTabs.tsx b/src/components/Register/FolderTabs/FolderTabs.tsx index 6a21113..63201f7 100644 --- a/src/components/Register/FolderTabs/FolderTabs.tsx +++ b/src/components/Register/FolderTabs/FolderTabs.tsx @@ -36,12 +36,9 @@ function FolderTab({ {label} {activeTab && ( - <> - - - - - > + + + )} ); diff --git a/src/components/Register/FormComponents/FormSelect/FormSelect.scss b/src/components/Register/FormComponents/FormSelect/FormSelect.scss index 0fc89e7..607c75d 100644 --- a/src/components/Register/FormComponents/FormSelect/FormSelect.scss +++ b/src/components/Register/FormComponents/FormSelect/FormSelect.scss @@ -1,14 +1,18 @@ @use '@/app/styles/_var' as *; -.registration-textfield { +.registration-textfield-container { + &.registration-select-container { + gap: 1rem; + } .other-field { margin-top: 1rem; } } + .register-select { button { font-family: $p-font; - font-size: 1.2rem; + font-size: 1.25rem; display: flex; align-items: center; background: transparent; @@ -28,7 +32,7 @@ border: 2px solid #68dea3; border-radius: 22px; font-family: $p-font; - font-size: 1.2rem; + font-size: 1.25rem; overflow-y: auto; background-color: black; padding: 0 1rem; diff --git a/src/components/Register/FormComponents/FormSelect/FormSelect.tsx b/src/components/Register/FormComponents/FormSelect/FormSelect.tsx index 9b8af8f..65904b8 100644 --- a/src/components/Register/FormComponents/FormSelect/FormSelect.tsx +++ b/src/components/Register/FormComponents/FormSelect/FormSelect.tsx @@ -20,6 +20,7 @@ export default function FormSelect({ control, options = [], defaultValue, + defaultLabel, hasOtherOption = false, width = 'auto', error @@ -37,7 +38,7 @@ export default function FormSelect({ }; return ( - + {label} - + + {({ defaultChildren, isPlaceholder }) => { + return isPlaceholder ? defaultLabel : defaultChildren; + }} + diff --git a/src/components/Register/FormComponents/FormText/FormText.scss b/src/components/Register/FormComponents/FormText/FormText.scss index cc176b4..d18454a 100644 --- a/src/components/Register/FormComponents/FormText/FormText.scss +++ b/src/components/Register/FormComponents/FormText/FormText.scss @@ -1,8 +1,7 @@ -.registration-textfield { - --temp-fontsize: 1.2rem; +.registration-textfield-container { display: grid; gap: 0.5rem; - font-size: var(--temp-fontsize); + font-size: 1.5rem; .error-message { height: var(--temp-fontsize); @@ -27,6 +26,10 @@ outline: none; transition: border-bottom 0.3s; + &::placeholder { + color: $dark-gray; + } + &:focus { border-bottom: 1px solid $light-green; } diff --git a/src/components/Register/FormComponents/FormText/FormText.tsx b/src/components/Register/FormComponents/FormText/FormText.tsx index 817ed19..28507db 100644 --- a/src/components/Register/FormComponents/FormText/FormText.tsx +++ b/src/components/Register/FormComponents/FormText/FormText.tsx @@ -13,7 +13,7 @@ export default function FormText({ const inputId = useId(); return ( - + {label} diff --git a/src/components/Register/FormSteps/FormStep1/FormStep1.tsx b/src/components/Register/FormSteps/FormStep1/FormStep1.tsx index 876c006..833e8c1 100644 --- a/src/components/Register/FormSteps/FormStep1/FormStep1.tsx +++ b/src/components/Register/FormSteps/FormStep1/FormStep1.tsx @@ -20,24 +20,25 @@ export default function FormStep1({ diff --git a/src/components/Register/FormSteps/FormStep2/FormStep2.tsx b/src/components/Register/FormSteps/FormStep2/FormStep2.tsx index e430333..c058547 100644 --- a/src/components/Register/FormSteps/FormStep2/FormStep2.tsx +++ b/src/components/Register/FormSteps/FormStep2/FormStep2.tsx @@ -21,20 +21,21 @@ export default function FormStep2({ register={register} name="email" label="UCSD Email" - placeholder="duck@ucsd.edu" + placeholder="e.g. duck@ucsd.edu" error={errors.email} /> - + /> */} ); } diff --git a/src/components/Register/FormSteps/FormStep3/FormStep3.scss b/src/components/Register/FormSteps/FormStep3/FormStep3.scss index 26c37cc..41f0382 100644 --- a/src/components/Register/FormSteps/FormStep3/FormStep3.scss +++ b/src/components/Register/FormSteps/FormStep3/FormStep3.scss @@ -2,37 +2,50 @@ @use '../form_var' as *; .form-step3 { - display: grid; - gap: 1rem; + display: flex; + flex-direction: column; + gap: 2.5rem; + height: 100%; - &-mascot { - display: grid; - place-items: center; - width: 5rem; + #half-badge { + aspect-ratio: 402/268; margin-inline: auto; - } - - .customization-container { + border: 2px solid $white; + border-top: none; + border-radius: 0 0 26px 26px; + overflow: hidden; position: relative; + margin-top: -1.5rem; + // height: 100%; + width: 100%; - // This is to account for the overflow from the above element - .active-line3 { + @media (min-width: 400px) { + width: auto; + height: 40%; + max-height: 15rem; + } + + &::before { + content: ''; + width: 100%; + height: 100%; + background-color: transparent; + margin-inline: auto; + border: 0.5rem solid rgb(0, 0, 0); + border-radius: 0 0 24px 24px; + border-top: none; position: absolute; - left: 0; - top: calc(0.5rem + 1.2rem + (2 * $border-width) + 0.45rem); - height: 50px; - left: 0px; - border-left: $border-width solid rgb(255, 255, 255); - border-top: 0; - border-radius: 20px 20px 0 0; - margin-top: -$border-width; - z-index: 3; + z-index: 1; } + } + + .customization-container { + position: relative; .customization-box { width: 100%; height: calc(12rem + $border-width); - border-radius: 3px 10px 10px 10px; + border-radius: 12px; border: $border-width solid rgb(255, 255, 255); margin-top: -$border-width; position: relative; diff --git a/src/components/Register/FormSteps/FormStep3/FormStep3.tsx b/src/components/Register/FormSteps/FormStep3/FormStep3.tsx index 4f2df70..3406bd9 100644 --- a/src/components/Register/FormSteps/FormStep3/FormStep3.tsx +++ b/src/components/Register/FormSteps/FormStep3/FormStep3.tsx @@ -1,7 +1,7 @@ -import Mascot from '@/components/Register/Mascot/Mascot'; import './FormStep3.scss'; import { useState } from 'react'; import BlockIcon from '@/components/Icons/BlockIcon'; +import MascotCircles from '@/components/MascotCircles/MascotCircles'; import { COLOR_THEMES } from '../../constants'; import { MascotBreeds, MascotHats } from '../../types'; import FolderTabs from '../../FolderTabs/FolderTabs'; @@ -22,8 +22,8 @@ export default function FormStep3() { return ( - - + + diff --git a/src/components/Register/FormSteps/FormStep4/FormStep4.scss b/src/components/Register/FormSteps/FormStep4/FormStep4.scss index f54f0b9..10a99cf 100644 --- a/src/components/Register/FormSteps/FormStep4/FormStep4.scss +++ b/src/components/Register/FormSteps/FormStep4/FormStep4.scss @@ -1,61 +1,169 @@ @use '../form_var' as *; -.form-step4 { +#form-step4 { height: 100%; - $padding: 2rem; + width: 100%; + overflow: hidden; + display: flex; + flex-direction: column; - .badge { - width: 90%; - max-width: 300px; + &-text { + opacity: 0; + animation: FadeIn 0.8s 0.9s forwards; + + @keyframes FadeIn { + 100% { + opacity: 1; + } + } + + p:first-child { + margin-bottom: 1rem; + } + + align-self: start; + + span { + color: $dark-green; + } + } + + #mascot-badge-container { + position: relative; height: 100%; - border: $border-width solid white; - border-radius: 24px; - margin-inline: auto; - .badge-top { + .mascot-badge { + position: absolute; + left: 0; + right: 0; + z-index: 1; + aspect-ratio: 252/378; + height: 100%; + border: 2px solid white; + border-radius: 25px; + overflow: hidden; display: flex; - justify-content: space-between; + flex-direction: column; + scale: 1; + animation: + SlideUp 0.8s, + ScaleDown 0.8s 0.8s forwards; margin-inline: auto; - padding: 1rem; - padding-inline: $padding; - border-bottom: 3px solid white; - - .long-hole { - width: 2.5rem; - height: 1rem; - border-radius: 24px; - border: $border-width solid white; + transform: scale(1.05); + + @keyframes SlideUp { + 0% { + transform: translateY(100%) scale(1.05); + } + 100% { + transform: translateY(-15%) scale(1.05); + } } - .short-hole { - width: 1rem; - aspect-ratio: 1; - border-radius: 50%; - border: $border-width solid white; + @keyframes ScaleDown { + 0% { + transform: translateY(-15%) scale(1.05); + } + 100% { + transform: scale(0.9) translateY(0); + } } - } - .badge-center { - padding: $padding; + &::before { + content: ''; + width: 100%; + height: 50%; + bottom: 0; + background-color: transparent; + margin-inline: auto; + border: 0.5rem solid rgb(0, 0, 0); + border-radius: 0 0 23px 23px; + border-top: none; + position: absolute; + z-index: 1; + } - &-top { + .badge-top { display: flex; - gap: 1rem; + justify-content: space-around; + align-items: center; + padding: 1rem; + padding-inline: 1rem; + border-bottom: 3px solid white; + + .long-hole { + width: 2.75rem; + height: 1rem; + border-radius: 24px; + border: 2px solid white; + } + + .short-hole { + width: 1rem; + aspect-ratio: 1; + border-radius: 50%; + border: 2px solid white; + } } - .badge-code { - svg { - width: 5rem; - height: auto; + .badge-center { + padding: 1rem; + + &-top { + display: flex; + justify-content: space-between; + padding-block: 1rem; + position: relative; + + h2 { + display: grid; + font-size: 1.5rem; + // font-size: 25px; + font-style: italic; + font-weight: 600; + // gap: 1rem; + } + + #vertical-dotted-bar { + position: absolute; + left: 0; + } + + #horizontal-dotted-bar { + position: absolute; + bottom: 0; + } + + p { + position: relative; + display: grid; + padding-inline: 1.5rem; + } + } + + &-center { + display: flex; + justify-content: space-between; + padding-block: 1rem; + + p { + font-size: 1rem; + font-weight: 400; + } + } + + .badge-code { + svg { + width: 4.5rem; + height: auto; + } } } - .badge-mascot { - width: fit-content; - height: fit-content; - padding: 0.5rem; - border: $border-width solid white; - border-radius: 24px; + .badge-bottom { + height: 100%; + z-index: -1; + position: relative; } } } diff --git a/src/components/Register/FormSteps/FormStep4/FormStep4.tsx b/src/components/Register/FormSteps/FormStep4/FormStep4.tsx index 66250c8..53236dd 100644 --- a/src/components/Register/FormSteps/FormStep4/FormStep4.tsx +++ b/src/components/Register/FormSteps/FormStep4/FormStep4.tsx @@ -1,36 +1,66 @@ -import QRCode from 'react-qr-code'; -import Mascot from '../../Mascot/Mascot'; import './FormStep4.scss'; +import Image from 'next/image'; +import QRCode from 'react-qr-code'; +import MascotCircles from '@/components/MascotCircles/MascotCircles'; import { TFormData } from '../../types'; +import VerticalBar from '../../MascotBadge/VerticalBar'; +import HorizontalBar from '../../MascotBadge/HorizontalBar'; type FormStep4Props = { formData: TFormData; }; export default function FormStep4({ formData }: FormStep4Props) { + const firstName = formData.name.split(' ')[0]; + const lastName = formData.name.split(' ')[1]; + const firstPronoun = formData.pronouns.split('/')[0]; + const secondPronoun = formData.pronouns.split('/')[1]; + return ( - - - - - - - - - - - + + + Thanks a bunch! + We've sent the Badge URL + + to {formData.email} + + + + + + + + + + + + + {firstName} + {lastName} + + + + {firstPronoun}/ + {secondPronoun} + + - - + + + + + Class of {formData.year} - - {formData.name} - {formData.pronouns} + + - ); diff --git a/src/components/Register/Mascot/Hats/TestHat.tsx b/src/components/Register/Mascot/Hats/TestHat.tsx index 1776bab..a106824 100644 --- a/src/components/Register/Mascot/Hats/TestHat.tsx +++ b/src/components/Register/Mascot/Hats/TestHat.tsx @@ -10,8 +10,6 @@ function InnerSVG() { ); } diff --git a/src/components/Register/Mascot/Mascot.tsx b/src/components/Register/Mascot/Mascot.tsx index ac6fbc4..a3c9ea6 100644 --- a/src/components/Register/Mascot/Mascot.tsx +++ b/src/components/Register/Mascot/Mascot.tsx @@ -113,7 +113,7 @@ export default function Mascot() { d="M138.741 549.532C122.037 549.651 119 531.4 118.54 521.859V483.338C118.813 481.539 121.167 477.158 136.745 474.917C116.885 471.505 98.611 463.865 83.0333 453V516.121C83.0333 543.777 17.2589 549.515 17.2589 549.515C15.4503 549.515 14 550.975 14 552.757C14 554.54 15.4673 556 17.2589 556H138.741C140.55 556 142 554.54 142 552.757C142 550.975 140.533 549.515 138.741 549.515V549.532Z" fill="#F7941D" /> - + {hat === 'test' && } diff --git a/src/components/Register/MascotBadge/HorizontalBar.tsx b/src/components/Register/MascotBadge/HorizontalBar.tsx new file mode 100644 index 0000000..5e7d94f --- /dev/null +++ b/src/components/Register/MascotBadge/HorizontalBar.tsx @@ -0,0 +1,22 @@ +import { SVGProps } from 'react'; + +export default function HorizontalBar(props: SVGProps) { + return ( + + + + ); +} diff --git a/src/components/Register/MascotBadge/VerticalBar.tsx b/src/components/Register/MascotBadge/VerticalBar.tsx new file mode 100644 index 0000000..b17ec27 --- /dev/null +++ b/src/components/Register/MascotBadge/VerticalBar.tsx @@ -0,0 +1,22 @@ +import { SVGProps } from 'react'; + +export default function VerticalBar(props: SVGProps) { + return ( + + + + ); +} diff --git a/src/components/Register/Register.scss b/src/components/Register/Register.scss deleted file mode 100644 index 70e2bd6..0000000 --- a/src/components/Register/Register.scss +++ /dev/null @@ -1,35 +0,0 @@ -.register-container { - .color-palette-container { - padding-left: 0; - list-style-type: none; - display: grid; - max-width: 500px; - // grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); - - .color-grouping { - border: none; - background-color: inherit; - transition: background-color 0.3s; - padding: 10px 20px; - border-radius: 8px; - cursor: pointer; - - &:hover { - background-color: rgb(243, 243, 243); - } - - ul { - padding-left: 0; - list-style-type: none; - display: flex; - gap: 10px; - - li { - width: 25px; - height: 25px; - border-radius: 50%; - } - } - } - } -} diff --git a/src/components/Register/Register.tsx b/src/components/Register/Register.tsx deleted file mode 100644 index 7d5f250..0000000 --- a/src/components/Register/Register.tsx +++ /dev/null @@ -1,156 +0,0 @@ -'use client'; - -import { Dialog, Heading, Modal } from 'react-aria-components'; -import { useEffect, useState } from 'react'; -import { useForm } from 'react-hook-form'; -import { zodResolver } from '@hookform/resolvers/zod'; -import './Register.scss'; -import './Modal.scss'; -import { CloseIcon } from '../Icons/CloseIcon'; -import FormStep1 from './FormSteps/FormStep1/FormStep1'; -import { RegistrationSchema, TFormData, ValidFieldNames } from './types'; -import RightArrow from '../Icons/RightArrow'; -import FormStep2 from './FormSteps/FormStep2/FormStep2'; -import FormStep3 from './FormSteps/FormStep3/FormStep3'; -import FormStep4 from './FormSteps/FormStep4/FormStep4'; - -export default function Register() { - const [isOpen, setOpen] = useState(false); - const [nextButtonText, setNextButtonText] = useState('Next'); - const [currentFormStep, setCurrentFormStep] = useState(1); - const { - register, - control, - handleSubmit, - formState: { errors }, - trigger, - getValues - } = useForm({ - resolver: zodResolver(RegistrationSchema) - }); - - useEffect(() => { - if (currentFormStep === 4) { - setNextButtonText('Close'); - } else if (currentFormStep === 3) { - setNextButtonText('Finish'); - } else { - setNextButtonText('Next'); - } - }, [currentFormStep]); - - const onSubmit = async (data: TFormData) => { - try { - console.log(data); - } catch (e) { - console.error(e); - } - }; - - const handleFormNext = async () => { - // Input Validation for Steps 1 and 2 - if (currentFormStep <= 2) { - let fieldsToValidate: Array = [ - 'name', - 'pronouns', - 'year' - ]; - if (currentFormStep === 2) { - fieldsToValidate = ['email', 'link']; - } - - const isValid = await trigger(fieldsToValidate); - if (!isValid) return; - } - - if (currentFormStep === 3) { - handleSubmit(onSubmit)(); - } - - if (currentFormStep >= 4) { - setOpen(false); - return; - } - setCurrentFormStep(currentFormStep + 1); - }; - - const handleFormPrev = () => { - if (currentFormStep <= 1) return; - setCurrentFormStep(currentFormStep - 1); - }; - - return ( - - setOpen(true)}>Register - - - { - console.error('Validation errors:', validationError); - })} - className="modal-form" - > - - Registration - { - setOpen(false); - }} - className="close-icon" - > - - - - - {currentFormStep === 1 && ( - - )} - {currentFormStep === 2 && ( - - )} - {currentFormStep === 3 && } - {currentFormStep === 4 && } - - - - {/* {`${currentFormStep} of 4`} */} - {currentFormStep > 1 && ( - - - - {' '} - Back - - )} - - {nextButtonText}{' '} - {currentFormStep < 4 && ( - - - - )} - - - - - - - ); -} diff --git a/src/components/Register/StrideLogo.tsx b/src/components/Register/StrideLogo.tsx new file mode 100644 index 0000000..636cd0f --- /dev/null +++ b/src/components/Register/StrideLogo.tsx @@ -0,0 +1,46 @@ +import { SVGProps } from 'react'; + +export default function StrideLogo(props: SVGProps) { + return ( + + + + + + + + + + + ); +} diff --git a/src/components/Register/types.ts b/src/components/Register/types.ts index d8e769c..46cb3fc 100644 --- a/src/components/Register/types.ts +++ b/src/components/Register/types.ts @@ -17,8 +17,8 @@ export type TFormData = { name: string; pronouns: string; year: string; - interest: string; - interest_other?: string; + // interest: string; + // interest_other?: string; email: string; link: string; }; @@ -41,7 +41,8 @@ export type FormSelectProps = { name: keyof TFormData; control: Control; options: Array; - defaultValue: string; + defaultValue?: string; + defaultLabel?: string; hasOtherOption?: boolean; error?: FieldError; width?: string; @@ -66,12 +67,12 @@ export const RegistrationSchema: ZodType = z.object({ }, { message: 'Year must be between 2022 and 2029' } ), - interest: z.string().min(2, { message: 'Interest is too short' }), - interest_other: z - .string() - .min(2, { message: 'Interest is too short' }) - .max(50, { message: 'Interest needs to be under 30 characters.' }) - .optional(), + // interest: z.string().min(2, { message: 'Interest is too short' }), + // interest_other: z + // .string() + // .min(2, { message: 'Interest is too short' }) + // .max(50, { message: 'Interest needs to be under 30 characters.' }) + // .optional(), link: z .string() .includes('linkedin.com', { message: 'Invalid LinkedIn URL' }),
Lorem Ipsum Dolor Sit Amet Include something about the $5 fee?
+ contact designatucsd@gmail.com for inquiries about financial + assistance +
Thanks a bunch!
We've sent the Badge URL
+ to {formData.email} +
+ + {firstPronoun}/ + {secondPronoun} +
Class of {formData.year}
{formData.pronouns}
{`${currentFormStep} of 4`}