Skip to content

Commit

Permalink
feat: 회원가입 - 약관 동의, 인증, 입력(화면), 관리비 조회 default 변경(관리비 상세보기 -> 우리집 관리비)
Browse files Browse the repository at this point in the history
  • Loading branch information
alreadyme24 committed Jun 3, 2024
1 parent b412f9b commit 9eb0537
Show file tree
Hide file tree
Showing 10 changed files with 304 additions and 13 deletions.
22 changes: 18 additions & 4 deletions app/user/[category]/[item]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import AuthContent from "@/components/AuthContent"
import FindIdContent from "@/components/FindIdContent"
import FindPwdContent from "@/components/FindPwdContent"
import InputUserInfoContent from "@/components/InputUserInfoContent"
import TermsContent from "@/components/TermsContent"

export default async function Page({
export default function Page({
params
}: {
params: { category: string, item: string }
Expand All @@ -11,15 +14,26 @@ export default async function Page({
let contentComponent
let pageName

if(category === "find") {
pageName="아이디/비밀번호 찾기"
} else if(category === "join") {
pageName="회원가입"
} else {
pageName = "사용자"
}

if (item === "by-name-and-phone") {
contentComponent = <FindIdContent page={category}/>
pageName="아이디/비밀번호 찾기"
} else if (item === "by-id-and-phone") {
contentComponent = <FindPwdContent page={category}/>
pageName="아이디/비밀번호 찾기"
} else if(item === "terms") {
contentComponent = <TermsContent/>
} else if(item === "auth") {
contentComponent = <AuthContent/>
} else if(item === "signUp") {
contentComponent = <InputUserInfoContent/>
} else {
contentComponent = null
pageName="사용자"
}

return (
Expand Down
95 changes: 95 additions & 0 deletions components/AuthContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
"use client"

import agree_checkbox_icon from "@/public/icon/agree_false.svg"
import agree_checked_icon from "@/public/icon/agree_true.svg"

import { useRouter } from "next/navigation";
import { useState } from "react";

export default function AuthContent() {
const regularPhone = [["SKT", "KT", "LG U+"], ["SKT 알뜰폰", "KT 알뜰폰", "LG U+ 알뜰폰"]]

const [male, isMale] = useState(false)
const [female, isFemale] = useState(false)
const [btnClicked, setBtnClicked] = useState(0)

const router = useRouter();

const handleNextButton = () => {
router.push(`/user/join/signUp`)
}

return (
<>
<div className="max-w-[486px] flex flex-col gap-8">
<div className="inline-flex justify-between items-center">
<p className="w-[120px] h-10 text-grey_800 text-[22px]">본인인증</p>
<p className="h-5 text-right text-grey_250 text-sm border-b border-grey_250">본인인증없이 회원가입</p>
</div>
<div className="inline-flex items-center">
<p className="w-[120px] h-8 text-grey_500">이름</p>
<input className="grow shrink h-10 px-4 bg-grey_25 rounded-[7px] border border-grey_100"/>
</div>
<div className="inline-flex items-center">
<p className="w-[120px] h-8 text-grey_500">주민번호</p>
<span className="inline-flex gap-4">
<input required maxLength={6} minLength={6} className="w-[120px] h-10 px-4 bg-grey_25 rounded-[7px] border border-grey_100"/>
<p className="text-grey_250 text-base font-normal py-2">-</p>
<input required maxLength={1} minLength={1} className="w-[29px] h-10 px-4 bg-grey_25 rounded-[7px] border border-grey_100"/>
<p className="text-grey_250 text-base font-normal py-2">* * * * * *</p>
</span>

</div>
<div className="inline-flex items-center ">
<p className="w-[120px] h-8 text-grey_500">성별</p>
<div className="inline-flex h-5 items-center gap-6">
<input id="male" type="checkbox" className={`hidden`}
checked={male} onChange={() => {isMale(!male); isFemale(male)}}/>
<label htmlFor="male" className={`w-full justify-center items-center gap-2 inline-flex hover:cursor-pointer`}>
<img src={male == false ? agree_checkbox_icon.src : agree_checked_icon.src} />
<p>남자</p>
</label>
<input id="female" type="checkbox" className={`hidden`}
checked={female} onChange={() => {isFemale(!female); isMale(female)}}/>
<label htmlFor="female" className={`w-full justify-center items-center gap-2 inline-flex hover:cursor-pointer`}>
<img src={female == false ? agree_checkbox_icon.src : agree_checked_icon.src} />
<p>여자</p>
</label>
</div>
</div>
<div className="inline-flex items-center">
<p className="w-[120px] h-8 text-grey_500">통신사 선택</p>
<div className="flex flex-col gap-2 text-sm">
<span className="inline-flex gap-2">
{regularPhone[0].map((item, index) => (
<button className={`px-4 py-2.5 rounded-lg border border-grey_100 ${btnClicked === index ? "bg-main_color text-grey_50" : "bg-grey_25"}`}
onClick={() => setBtnClicked(index)}>{item}</button>
))}
</span>
<span className="inline-flex gap-2">
{regularPhone[1].map((item, index) => (
<button className={`px-4 py-2.5 rounded-lg border border-grey_100 ${btnClicked === index + 3? "bg-main_color text-grey_50" : "bg-grey_25"}`}
onClick={() => setBtnClicked(index + 3)}>{item}</button>
))}
</span>
</div>

</div>
<div className="inline-flex items-center">
<p className="w-[120px] h-8 text-grey_500">휴대폰 번호</p>
<div className="inline-flex gap-2">
<input className="grow shrink h-10 px-4 bg-grey_25 rounded-[7px] border border-grey_100"
placeholder="-없이 입력"/>
<button className="h-10 px-4 bg-grey_500 rounded-lg
text-grey_50 text-sm whitespace-nowrap">인증번호 요청</button>
</div>

</div>
<button className="w-full px-[200px] py-6 bg-main_color rounded
text-center text-white text-lg font-semibold"
onClick={handleNextButton}>다음</button>
</div>
</>

)
}
12 changes: 6 additions & 6 deletions components/FindIdContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ export default function FindIdContent({page} : {page: string}) {
return;
}

const response = await fetch(`http://localhost:3001/findId?name=${name}&phone=${phoneNumber}`)
const userData: User[] = await response.json()
// const response = await fetch(`http://localhost:3001/findId?name=${name}&phone=${phoneNumber}`)
// const userData: User[] = await response.json()

if(userData){
setFoundId(userData[0].id)
setMessage(`'${name}' 님의 아이디는 '${foundId}'입니다.`)
}
// if(userData){
// setFoundId(userData[0].id)
// setMessage(`'${name}' 님의 아이디는 '${foundId}'입니다.`)
// }
}

const buttonClassName = `px-4 py-6 grow shrink basis-0
Expand Down
4 changes: 2 additions & 2 deletions components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export default async function Header() {
<p>로그아웃</p>
</div> */}
<div className="flex gap-6">
<Link href="/join/terms">회원가입</Link>
<Link href="/user/join/terms">회원가입</Link>
<Link href="/login">로그인</Link>
</div>
</div>
Expand Down Expand Up @@ -128,7 +128,7 @@ export default async function Header() {
</li>
<li>
<Link
href={"/fee"}
href={"/myfee"}
className="text-grey_900 text-lg font-semibold">
관리비조회
</Link>
Expand Down
46 changes: 46 additions & 0 deletions components/InputUserInfoContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"use client"
import { useRouter } from "next/navigation";

export default function InputUserInfoContent() {
const router = useRouter();

const handleNextButton = () => {
alert("회원 가입 완료")
}

return (
<div className="flex flex-col gap-[50px]">
<div className="max-w-[486px] flex flex-col gap-8">
<div className="inline-flex items-center">
<p className="w-[120px] text-grey_500 py-1">이름</p>
<p className="font-semibold">김패캠</p>
</div>
<div className="inline-flex items-center">
<p className="w-[120px] text-grey_500 py-1">휴대폰 번호</p>
<p className="font-semibold">010-1234-1234</p>
</div>
<div className="inline-flex items-center">
<p className="w-[120px] text-grey_500">아이디</p>
<div className="flex flex-col grow shrink">
<input className="h-10 px-4 bg-grey_25 rounded-[7px] border border-grey_100"/>
<label className="text-grey_250 text-sm font-normal">6글자 이상의 영문, 숫자,_만 입력할 수 있습니다.</label>
</div>
</div>
<div className="inline-flex items-center">
<p className="w-[120px] text-grey_500">비밀번호</p>
<input className="grow shrink h-10 px-4 bg-grey_25 rounded-[7px] border border-grey_100"/>
</div>
<div className="inline-flex items-center">
<p className="w-[120px] text-grey_500">비밀번호 확인</p>
<div className="flex flex-col">
<input className="grow shrink h-10 px-4 bg-grey_25 rounded-[7px] border border-grey_100"/>
<label className="text-grey_250 text-sm font-normal">확인란에 입력할 비밀번호는 상단 내용과 동일해야 합니다.</label>
</div>
</div>
</div>
<button className="w-full px-[200px] py-6 bg-main_color rounded
text-center text-white text-lg font-semibold"
onClick={handleNextButton}>다음</button>
</div>
)
}
2 changes: 1 addition & 1 deletion components/LoginContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function LoginContent() {
const router = useRouter();

const onClickJoinButton = () => {
router.push("/join/terms")
router.push("/user/join/terms")
}

const width = 486;
Expand Down
133 changes: 133 additions & 0 deletions components/TermsContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@

"use client"

import agree_checkbox_icon from "@/public/icon/agree_false.svg"
import agree_checked_icon from "@/public/icon/agree_true.svg"
import { useRouter } from "next/navigation"
import { useEffect, useState } from "react"

export default function TermsContent() {
const router = useRouter()

const [service, setServiceChecked] = useState(false);
const [personal, setPersonalChecked] = useState(false);
const [marketing, setMarketingChecked] = useState(false);
const [all, setAllChecked] = useState(false);

const checkBoxClassName = "inline-flex w-full items-center gap-2 hover:cursor-pointer";
const checkBoxLabelClassName = "hover:cursor-pointer text-base font-medium";

const [serviceContent, setServiceContent] = useState<string>("")
const [personalContent, setPersonalContent] = useState<string>("")
const [marketingContent, setmarketingContent] = useState<string>("")

const handleNextButton = () => {
if(!service || !personal) {
alert("필수 약관에 동의하셔야 합니다.")
return
}
router.push(`/user/join/auth`)
}

useEffect(() => {
if(service && personal && marketing){
setAllChecked(true)
} else {
setAllChecked(false)
}
},[service, personal, marketing])


useEffect(() => {
const fetchServiceText = async() => {
try {
const response = await fetch("/service.txt");
const content = await response.text();
setServiceContent(content)
} catch (e) {
console.error(e)
}
}
const fetchPersonalText = async() => {
try {
const response = await fetch("/personal.txt");
const content = await response.text();
setPersonalContent(content)
} catch (e) {
console.error(e)
}
}
const fetchMarketingText = async() => {
try {
const response = await fetch("/marketing.txt");
const content = await response.text();
setmarketingContent(content)
} catch (e) {
console.error(e)
}
}
fetchServiceText()
fetchPersonalText()
fetchMarketingText()
})

return (
<>
<div className="max-w-[486px] flex flex-col gap-4">
<div className="flex flex-col gap-6">
<div className="flex flex-col gap-4">
<div className="px-4 py-2 bg-grey_25 rounded-lg border border-grey_100">
<div className="w-[440px] h-[124px] overflow-y-scroll">
<span className="text-sm font-normal ">{serviceContent}</span>
</div>
</div>
<input id="service" type="checkbox" className={`${checkBoxClassName} hidden`}
checked={service} onChange={() => {setServiceChecked(!service)}}/>
<label htmlFor="service" className={`${checkBoxLabelClassName} inline-flex gap-2`}>
<img src={service == false ? agree_checkbox_icon.src : agree_checked_icon.src} />
<p>서비스 이용 동의 (필수)</p>
</label>
</div>
<div className="flex flex-col gap-4">
<div className="px-4 py-2 bg-grey_25 rounded-lg border border-grey_100">
<div className="w-[440px] h-[124px] overflow-y-scroll">
<span className="text-sm font-normal">{personalContent}</span>
</div>
</div>

<input id="personal" type="checkbox" className={`${checkBoxClassName} hidden`}
checked={personal} onChange={() => {setPersonalChecked(!personal)}}/>
<label htmlFor="personal" className={`${checkBoxLabelClassName} inline-flex gap-2`}>
<img src={personal == false ? agree_checkbox_icon.src : agree_checked_icon.src} />
<p>개인정보 수집 (필수)</p>
</label>
</div>
<div className="flex flex-col gap-4">
<div className="px-4 py-2 bg-grey_25 rounded-lg border border-grey_100">
<div className="w-[440px] h-[124px] overflow-y-scroll">
<span className="text-sm font-normal">{marketingContent}</span>
</div>
</div>

<input id="marketing" type="checkbox" className={`${checkBoxClassName} hidden`}
checked={marketing} onChange={() => {setMarketingChecked(!marketing)}}/>
<label htmlFor="marketing" className={`${checkBoxLabelClassName} inline-flex gap-2`}>
<img src={marketing == false ? agree_checkbox_icon.src : agree_checked_icon.src} />
<p>마케팅 정보 수신 동의 (선택)</p>
</label>
</div>
</div>
<div className="w-full h-0 border border-grey_900"></div>
<input id="allChecked" type="checkbox" className={`${checkBoxClassName} hidden`}
checked={all} onChange={() => {setAllChecked(!all); setServiceChecked(!all); setPersonalChecked(!all); setMarketingChecked(!all)}}/>
<label htmlFor="allChecked" className={`${checkBoxLabelClassName} inline-flex gap-2`}>
<img src={all == false ? agree_checkbox_icon.src : agree_checked_icon.src} />
<p>전체 약관 동의</p>
</label>
<button className="w-full px-[200px] py-6 bg-main_color rounded
text-center text-white text-lg font-semibold"
onClick={handleNextButton}>다음</button>
</div>
</>
)
}
1 change: 1 addition & 0 deletions public/marketing.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
마케팅 정보 수신 동의 아파트너는 마케팅 정보 소식 및 이벤트 참여를 위해 개인정보를 수집, 이용합니다. 수집 목적수집 항목보유 기간이벤트 응모 및 혜택, 마케팅 활용 및 맞춤형 광고, 경품제공이름, 휴대폰번호, 생년월일, 주소, 성별회원 탈퇴 즉시 파기

부정이용 방지를 위해 90일 동안 보관(이름, 아이디) 후 파기

단, 관계 법령 위반에 따른 수사, 조사 등이 진행중인 경우에는 해당 수사, 종료시까지 보관 후 파기* 마케팅 정보 수신 동의(선택)을 거부하실 수 있습니다.
1 change: 1 addition & 0 deletions public/personal.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
개인정보 수집 개인정보를 수집할 경우에는 해당 개인정보 수집시점에서 이용자에게 수집하는 개인정보 항목, 개인정보의 수집 및 이용목적, 개인정보의 보관기간에 대해 안내 드리고 동의를 받고 있습니다. 수집 목적수집 항목보유 기간이용자 식별 및 본인 여부 확인이름, 아이디, 비밀번호, 휴대폰번호, 생년월일, 거주자정보, 기기정보회원 탈퇴 즉시 파기

부정이용 방지를 위해 90일 동안 보관(이름, 아이디) 후 파기

단, 관계 법령 위반에 따른 수사, 조사 등이 진행중인 경우에는 해당 수사, 종료시까지 보관 후 파기본인 인증CI, DI, 휴대폰번호, 생년월일, 성별, 통신사, 내/외국인 정보
1 change: 1 addition & 0 deletions public/service.txt

Large diffs are not rendered by default.

0 comments on commit 9eb0537

Please sign in to comment.