Skip to content

Commit

Permalink
Merge pull request #187 from JohnsonMao/feature/signin-page-success-m…
Browse files Browse the repository at this point in the history
…odal

feature: signin page success modal
  • Loading branch information
JohnsonMao authored Dec 21, 2024
2 parents 2b52233 + ddbffec commit 22771cf
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 169 deletions.
106 changes: 0 additions & 106 deletions components/Signin/Interest/TipModal/index.jsx

This file was deleted.

60 changes: 60 additions & 0 deletions components/Signin/TipModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useId } from "react";
import Image from "@/shared/components/Image";
import Modal from "@/shared/components/Modal";

interface TipModalProps {
isOpen: boolean;
onClose: () => void;
onOk: () => void;
}

function TipModal({ isOpen, onClose, onOk }: Readonly<TipModalProps>) {
const id = useId();
const describedby = `tip-modal-${id}`;

return (
<Modal
keepMounted
isOpen={isOpen}
onClose={onClose}
className="sm:max-w-[440px]"
title="帳號註冊成功!"
describedby={describedby}
>
<p
id={describedby}
className="mt-2 mb-6 text-center text-basic-400 body-sm"
>
記得到信箱確認收到帳號驗證信件,並點選驗證Email按鈕,如果沒有看到信件,可以到垃圾桶確認。
</p>
<Image
src="/assets/partner-popup.png"
alt="dao-dao-island"
width="360"
height="280"
/>
<p className="my-6 text-center text-basic-400 body-sm">
我們會公開你的<strong className="font-bold">個人檔案</strong>
,填寫完整的資料,才能讓其他夥伴們更了解你喔!
</p>
<div className="flex gap-2">
<button
type="button"
className="flex-1 py-2 shadow-lg transition-colors rounded-full bg-white text-primary-darker hover:bg-basic-100"
onClick={onClose}
>
暫時不需要
</button>
<button
type="button"
className="flex-1 py-2 shadow-lg transition-colors rounded-full bg-primary-base text-white hover:bg-primary-darker"
onClick={onOk}
>
想,填寫資料
</button>
</div>
</Modal>
);
}

export default TipModal;
41 changes: 10 additions & 31 deletions pages/signin/index.jsx → pages/signin/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import Navigation from '@/shared/components/Navigation_v2';
import Footer from '@/shared/components/Footer_v2';
import { HomePageWrapper } from '@/components/Signin/Signin.styled';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import toast from 'react-hot-toast';
import useProfileValidation from '@/components/Signin/useValidation';
import { useAuth, useAuthDispatch } from '@/contexts/Auth';
import { ProtectedComponent, useAuthDispatch } from '@/contexts/Auth';
import Step1 from '@/components/Signin/Step1';
import Step2 from '@/components/Signin/Step2';
import TipModal from '@/components/Signin/Interest/TipModal';
import TipModal from '@/components/Signin/TipModal';

function SignInPage() {
const router = useRouter();
Expand All @@ -16,7 +14,6 @@ function SignInPage() {
const { errors, onChangeHandler, userState, validateFields } =
useProfileValidation();

const { isLoggedIn, token } = useAuth();
const { updateUser } = useAuthDispatch();

const handleSubmit = async () => {
Expand All @@ -28,22 +25,14 @@ function SignInPage() {
};
try {
await updateUser(payload);
} catch (error) {
console.error(error);
} catch {
toast.error('伺服器異常,請稍後再試');
}
}
};

useEffect(() => {
if (isLoggedIn) {
setOpen(true);
} else if (!token) {
router.push('/');
}
}, [isLoggedIn, token]);

return (
<>
<ProtectedComponent onlyCheckToken redirectOnCancel='/'>
{step === 1 && (
<Step1
errors={errors}
Expand All @@ -69,7 +58,7 @@ function SignInPage() {
/>
)}
<TipModal
open={open}
isOpen={open}
onClose={() => {
setOpen(false);
router.replace('/');
Expand All @@ -79,18 +68,8 @@ function SignInPage() {
router.replace('/profile');
}}
/>
</>
</ProtectedComponent>
);
}

SignInPage.getLayout = ({ children }) => {
return (
<HomePageWrapper>
<Navigation />
{children}
<Footer />
</HomePageWrapper>
);
};

export default SignInPage;
30 changes: 23 additions & 7 deletions shared/components/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useState, useEffect } from "react";
import { useState, useEffect, useId } from "react";
import { cn } from "@/utils/cn";
import Portal from "./Portal";

interface ModalProps {
isOpen: boolean;
title: string;
children: React.ReactNode;
describedby?: string;
className?: string;
keepMounted?: boolean;
onClose: () => void;
Expand All @@ -16,12 +17,16 @@ function Modal({
isOpen,
title,
children,
describedby,
className,
keepMounted = false,
onClose,
onRemovedDOM,
}: ModalProps) {
const id = useId();
const modalId = `modal-${id}`;
const [removeDOM, setRemoveDOM] = useState(true);
const [isInitialized, setIsInitialized] = useState(false);

const handleKeyUp: React.KeyboardEventHandler<HTMLButtonElement> = (e) => {
if (e.key === "Enter") {
Expand All @@ -35,6 +40,7 @@ function Modal({
if (isOpen) {
document.body.classList.add("overflow-y-hidden");
setRemoveDOM(false);
setIsInitialized(true);
} else {
timer = setTimeout(() => {
setRemoveDOM(true);
Expand All @@ -61,12 +67,16 @@ function Modal({

return (
(!removeDOM || keepMounted) && (
<Portal>
<Portal rootId={modalId}>
<div
className={cn(
"fixed inset-0 z-[9999] flex items-center justify-center",
"transition-opacity opacity-0 pointer-events-none ease-in duration-200",
isOpen && "opacity-100 pointer-events-auto animate-fade-in"
isInitialized && [
isOpen
? "pointer-events-auto animate-fade-in"
: "animate-fade-out",
]
)}
>
<button
Expand All @@ -75,19 +85,25 @@ function Modal({
onClick={onClose}
onKeyUp={handleKeyUp}
/>
<div
<dialog
open={!removeDOM}
className={cn(
"fixed -bottom-4 sm:bottom-auto p-10 w-full sm:max-w-96 rounded-lg bg-white",
"transition-transform translate-y-full ease-in duration-200",
isOpen && "translate-y-0 animate-slide-y-in",
isOpen ? "animate-slide-y-in" : "animate-slide-y-out",
className
)}
aria-labelledby={modalId}
aria-describedby={describedby}
>
<header className="text-center text-2xl font-bold text-basic-400">
<header
id={modalId}
className="text-center heading-md text-basic-400"
>
{title}
</header>
{children}
</div>
</dialog>
</div>
</Portal>
)
Expand Down
4 changes: 2 additions & 2 deletions shared/components/Portal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { createPortal } from "react-dom";

interface PortalProps {
children: React.ReactNode;
rootId?: string;
rootId: string;
}

function Portal({ children, rootId = "portal-root" }: PortalProps) {
function Portal({ children, rootId }: PortalProps) {
const [targetRoot, setTargetRoot] = useState<HTMLElement | null>(null);

useEffect(() => {
Expand Down
17 changes: 17 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ const typography = require('@tailwindcss/typography');

/** @type {import('tailwindcss').Config} */
module.exports = {
future: {
hoverOnlyWhenSupported: true,
},
content: [
"./components/**/*.{jsx,tsx}",
"./contexts/**/*.{jsx,tsx}",
Expand Down Expand Up @@ -103,6 +106,13 @@ module.exports = {
'100%': { opacity: 1 },
},
},
[`.animate-fade-out`]: {
animation: 'fade-out var(--animation-duration, 200ms) var(--animation-delay, 0ms) forwards ease-in-out',
'@keyframes fade-out': {
'0%': { opacity: 1 },
'100%': { opacity: 0 },
},
},
});
addUtilities({
[`.animate-slide-y-in`]: {
Expand All @@ -112,6 +122,13 @@ module.exports = {
'100%': { transform: 'translateY(0)' },
},
},
[`.animate-slide-y-out`]: {
animation: 'slide-y-out var(--animation-duration, 200ms) var(--animation-delay, 0ms) forwards ease-in-out',
'@keyframes slide-y-out': {
'0%': { transform: 'translateY(0)' },
'100%': { transform: 'translateY(var(--animation-distance, 100%))' },
},
},
});
addUtilities({
[`.animate-slide-x-in`]: {
Expand Down
Loading

0 comments on commit 22771cf

Please sign in to comment.