로그인페이지

This commit is contained in:
2025-11-17 22:51:23 +09:00
parent eca3e76c72
commit 78b7cc2d3c
5 changed files with 673 additions and 43 deletions

9
memo.txt Normal file
View File

@@ -0,0 +1,9 @@
font-100 : font-thin
font-200 : font-extralight
font-300 : font-light
font-400 : font-normal
font-500 : font-medium
font-600 : font-semibold
font-700 : font-bold
font-800 : font-extrabold
font-900 : font-black

View File

@@ -12,21 +12,20 @@ export default function LoginPage() {
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
// TODO: 실제 인증 연동 시 이곳에서 처리
// 현재는 UI만 구현
/* todo */
console.log({ userId, password, rememberId, autoLogin });
}
return (
<div className="min-h-screen w-full flex flex-col items-center justify-center">
{/* 카드 컨테이너 */}
<div className="w-[480px] rounded-xl bg-white p-8 ">
<div className="min-h-screen w-full flex flex-col items-center justify-between">
<div></div>
<div className="rounded-xl bg-white max-w-[560px] px-[40px] w-full">
{/* 로고 영역 */}
<div className="mb-10 flex flex-col items-center">
<div className="my-10 flex flex-col items-center">
<div className="mb-[7px]">
<MainLogo/>
</div>
<div className="text-[28.8px] font-[800] leading-[145%] text-neutral-700" >
<div className="text-[28.8px] font-extrabold leading-[145%] text-neutral-700" >
XR LMS
</div>
</div>
@@ -45,13 +44,12 @@ export default function LoginPage() {
value={userId}
onChange={(e) => setUserId(e.target.value)}
placeholder="아이디 (이메일)"
className="w-[480px] h-[56px] px-[12px] py-[7px] rounded-[8px] border border-neutral-40
className="
h-[56px] px-[12px] py-[7px] w-full rounded-[8px] border border-neutral-40
focus:outline-none focus:ring-0 focus:ring-offset-0 focus:shadow-none
focus:appearance-none focus:border-neutral-700
text-[18px] text-neutral-700 font-[400] leading-[150%] placeholder:text-input-placeholder-text "
text-[18px] text-neutral-700 font-normal leading-[150%] placeholder:text-input-placeholder-text
"
/>
</div>
{/* 비밀번호 */}
@@ -66,38 +64,35 @@ export default function LoginPage() {
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="비밀번호"
className="h-14 w-full rounded-lg border px-4 text-[15px] outline-none transition-shadow"
className="
h-[56px] px-[12px] py-[7px] rounded-[8px] w-full border border-neutral-40
focus:outline-none focus:ring-0 focus:ring-offset-0 focus:shadow-none
focus:appearance-none focus:border-neutral-700
text-[18px] text-neutral-700 font-normal leading-[150%] placeholder:text-input-placeholder-text
"
/>
</div>
</div>
{/* 체크박스들 */}
<div className="flex items-center justify-start gap-6">
<label className="flex cursor-pointer select-none items-center gap-2 text-[15px]"
style={{ color: "var(--color-basic-text)" }}>
<label className="flex cursor-pointer select-none items-center gap-2 text-[15px] font-normal text-basic-text">
<input
type="checkbox"
checked={rememberId}
onChange={(e) => setRememberId(e.target.checked)}
className="h-[18px] w-[18px] cursor-pointer rounded border"
style={{
accentColor: "var(--color-input-border-select)",
borderColor: "var(--color-inactive-checkbox)",
}}
className="h-[18px] w-[18px] cursor-pointer rounded border
accent-input-border-select border-inactive-checkbox"
/>
</label>
<label className="flex cursor-pointer select-none items-center gap-2 text-[15px]"
style={{ color: "var(--color-basic-text)" }}>
<label className="flex cursor-pointer select-none items-center gap-2 text-[15px] font-normal text-basic-text">
<input
type="checkbox"
checked={autoLogin}
onChange={(e) => setAutoLogin(e.target.checked)}
className="h-[18px] w-[18px] cursor-pointer rounded border"
style={{
accentColor: "var(--color-input-border-select)",
borderColor: "var(--color-inactive-checkbox)",
}}
className="h-[18px] w-[18px] cursor-pointer rounded border
accent-input-border-select border-inactive-checkbox"
/>
</label>
@@ -106,8 +101,7 @@ export default function LoginPage() {
{/* 로그인 버튼 */}
<button
type="submit"
className="h-14 w-full rounded-lg text-[16px] font-semibold text-white transition-opacity cursor-pointer"
style={{ backgroundColor: "var(--color-active-button)" }}
className="h-14 w-full rounded-lg text-[16px] font-semibold text-white transition-opacity cursor-pointer bg-inactive-button"
>
</button>
@@ -115,33 +109,27 @@ export default function LoginPage() {
{/* 하단 링크들 */}
<div className="flex items-center justify-between text-[15px]">
<Link
href="#"
className="underline-offset-2 hover:underline"
style={{ color: "var(--color-basic-text)" }}
href="/register"
className="underline-offset-2 text-basic-text"
>
</Link>
<div
className="flex items-center gap-3"
style={{ color: "var(--color-basic-text)" }}
className="flex items-center gap-3 text-basic-text"
>
<Link href="#" className="underline-offset-2 hover:underline">
<Link href="#" className="underline-offset-2">
</Link>
<span className="h-3 w-px bg-[var(--color-input-border)]" />
<Link href="#" className="underline-offset-2 hover:underline">
<span className="h-3 w-px bg-input-border" />
<Link href="#" className="underline-offset-2">
</Link>
</div>
</div>
</form>
</div>
{/* 카피라이트 */}
<p
className="mt-10 text-center text-[15px]"
style={{ color: "var(--color-basic-text)" }}
>
<div></div>
<p className="text-center py-[40px] text-[15px] text-basic-text">
Copyright 2025 XL LMS. All rights reserved
</p>
</div>

613
src/app/register/page.tsx Normal file
View File

@@ -0,0 +1,613 @@
\"use client\";
import { useState } from \"react\";
import Link from \"next/link\";
import MainLogo from \"@/app/svgs/mainlogosvg\";
export default function RegisterPage() {
const [name, setName] = useState(\"\");
const [phone, setPhone] = useState(\"\");
const [email, setEmail] = useState(\"\");
const [password, setPassword] = useState(\"\");
const [confirmPassword, setConfirmPassword] = useState(\"\");
const [gender, setGender] = useState<\"male\" | \"female\" | \"\">(\"\");
const [birth, setBirth] = useState(\"\");
const [agreeAll, setAgreeAll] = useState(false);
const [agreeAge, setAgreeAge] = useState(false);
const [agreeTos, setAgreeTos] = useState(false);
const [agreePrivacy, setAgreePrivacy] = useState(false);
function syncAgreeAll(nextAll: boolean) {
setAgreeAll(nextAll);
setAgreeAge(nextAll);
setAgreeTos(nextAll);
setAgreePrivacy(nextAll);
}
function handleIndividualAgree(next: { age?: boolean; tos?: boolean; privacy?: boolean }) {
const nextAge = next.age ?? agreeAge;
const nextTos = next.tos ?? agreeTos;
const nextPrivacy = next.privacy ?? agreePrivacy;
setAgreeAge(nextAge);
setAgreeTos(nextTos);
setAgreePrivacy(nextPrivacy);
setAgreeAll(nextAge && nextTos && nextPrivacy);
}
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
// TODO: 서버 연동 시 실제 제출 로직으로 교체
console.log({
name,
phone,
email,
password,
confirmPassword,
gender,
birth,
agree: { all: agreeAll, age: agreeAge, tos: agreeTos, privacy: agreePrivacy },
});
}
return (
<div className=\"min-h-screen w-full flex flex-col items-center justify-between\">
<div></div>
<div className=\"rounded-xl bg-white max-w-[480px] w-full\">
{/* 로고/타이틀 */}
<div className=\"mb-10 flex flex-col items-center\">
<div className=\"mb-[7px]\">
<MainLogo />
</div>
<div className=\"text-[24px] font-[700] leading-[150%] text-neutral-700\">회원가입</div>
</div>
<form onSubmit={handleSubmit} className=\"space-y-6\">
<div className=\"space-y-4\">
{/* 이름 */}
<div className=\"space-y-2\">
<label className=\"text-[15px] font-[600] text-[var(--color-basic-text)]\">이름</label>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder=\"이름을 입력해 주세요.\"
className=\"h-[40px] px-[12px] py-[8px] w-full rounded-[8px] border border-neutral-40 text-[16px] text-neutral-700 placeholder:text-input-placeholder-text focus:outline-none focus:border-neutral-700\"
/>
</div>
{/* 휴대폰 번호 */}
<div className=\"space-y-2\">
<label className=\"text-[15px] font-[600] text-[var(--color-basic-text)]\">휴대폰 번호</label>
<input
value={phone}
onChange={(e) => setPhone(e.target.value)}
placeholder=\"-없이 입력해 주세요.\"
className=\"h-[40px] px-[12px] py-[8px] w-full rounded-[8px] border border-neutral-40 text-[16px] text-neutral-700 placeholder:text-input-placeholder-text focus:outline-none focus:border-neutral-700\"
/>
</div>
{/* 아이디(이메일) + 인증번호 전송 */}
<div className=\"space-y-2\">
<label className=\"text-[15px] font-[600] text-[var(--color-basic-text)]\">아이디 (이메일)</label>
<div className=\"flex gap-2\">
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder=\"이메일을 입력해 주세요.\"
className=\"h-[40px] px-[12px] py-[8px] w-full rounded-[8px] border border-neutral-40 text-[16px] text-neutral-700 placeholder:text-input-placeholder-text focus:outline-none focus:border-neutral-700\"
/>
<button
type=\"button\"
className=\"h-[40px] px-[12px] rounded-[8px] bg-[#f1f3f5] text-[16px] font-[600] text-[#4c5561]\"
>
인증번호 전송
</button>
</div>
</div>
{/* 비밀번호 */}
<div className=\"space-y-2\">
<label className=\"text-[15px] font-[600] text-[var(--color-basic-text)]\">비밀번호</label>
<input
type=\"password\"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder=\"8~16자의 영문/숫자/특수문자를 조합해서 입력해 주세요.\"
className=\"h-[40px] px-[12px] py-[8px] w-full rounded-[8px] border border-neutral-40 text-[16px] text-neutral-700 placeholder:text-input-placeholder-text focus:outline-none focus:border-neutral-700\"
/>
</div>
{/* 비밀번호 확인 */}
<div className=\"space-y-2\">
<label className=\"text-[15px] font-[600] text-[var(--color-basic-text)]\">비밀번호 확인</label>
<input
type=\"password\"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
placeholder=\"비밀번호를 다시 입력해 주세요.\"
className=\"h-[40px] px-[12px] py-[8px] w-full rounded-[8px] border border-neutral-40 text-[16px] text-neutral-700 placeholder:text-input-placeholder-text focus:outline-none focus:border-neutral-700\"
/>
</div>
{/* 성별 */}
<div className=\"space-y-2\">
<label className=\"text-[15px] font-[600] text-[var(--color-basic-text)]\">성별</label>
<div className=\"flex items-center gap-5 h-[40px]\">
<label className=\"flex items-center gap-2 text-[15px] text-neutral-700\">
<input
type=\"radio\"
name=\"gender\"
checked={gender === \"male\"}
onChange={() => setGender(\"male\")}
className=\"h-[18px] w-[18px] cursor-pointer\"
style={{ accentColor: \"var(--color-input-border-select)\" }}
/>
남성
</label>
<label className=\"flex items-center gap-2 text-[15px] text-neutral-700\">
<input
type=\"radio\"
name=\"gender\"
checked={gender === \"female\"}
onChange={() => setGender(\"female\")}
className=\"h-[18px] w-[18px] cursor-pointer\"
style={{ accentColor: \"var(--color-input-border-select)\" }}
/>
여성
</label>
</div>
</div>
{/* 생년월일 */}
<div className=\"space-y-2\">
<label className=\"text-[15px] font-[600] text-[var(--color-basic-text)]\">생년월일</label>
<input
type=\"date\"
value={birth}
onChange={(e) => setBirth(e.target.value)}
className=\"h-[40px] px-[12px] py-[8px] w-full rounded-[8px] border border-neutral-40 text-[16px] text-neutral-700 focus:outline-none focus:border-neutral-700\"
/>
</div>
</div>
{/* 약관 */}
<div className=\"space-y-4\">
<label className=\"flex items-center gap-2 text-[18px] font-[600] text-neutral-700 cursor-pointer\">
<input
type=\"checkbox\"
checked={agreeAll}
onChange={(e) => syncAgreeAll(e.target.checked)}
className=\"h-[20px] w-[20px] cursor-pointer rounded border\"
style={{ accentColor: \"var(--color-input-border-select)\", borderColor: \"var(--color-inactive-checkbox)\" }}
/>
모든 항목에 동의합니다.
</label>
<div className=\"h-px w-full bg-[var(--color-input-border)]\" />
<div className=\"space-y-3\">
<label className=\"flex items-center justify-between text-[15px]\">
<span className=\"flex items-center gap-2 text-neutral-700\">
<input
type=\"checkbox\"
checked={agreeAge}
onChange={(e) => handleIndividualAgree({ age: e.target.checked })}
className=\"h-[18px] w-[18px] cursor-pointer rounded border\"
style={{ accentColor: \"var(--color-input-border-select)\", borderColor: \"var(--color-inactive-checkbox)\" }}
/>
<span>
만 14세 이상입니다. <span className=\"text-[#384fbf]\">(필수)</span>
</span>
</span>
</label>
<label className=\"flex items-center justify-between text-[15px]\">
<span className=\"flex items-center gap-2 text-neutral-700\">
<input
type=\"checkbox\"
checked={agreeTos}
onChange={(e) => handleIndividualAgree({ tos: e.target.checked })}
className=\"h-[18px] w-[18px] cursor-pointer rounded border\"
style={{ accentColor: \"var(--color-input-border-select)\", borderColor: \"var(--color-inactive-checkbox)\" }}
/>
<span>
이용 약관 동의 <span className=\"text-[#384fbf]\">(필수)</span>
</span>
</span>
</label>
<label className=\"flex items-center justify-between text-[15px]\">
<span className=\"flex items-center gap-2 text-neutral-700\">
<input
type=\"checkbox\"
checked={agreePrivacy}
onChange={(e) => handleIndividualAgree({ privacy: e.target.checked })}
className=\"h-[18px] w-[18px] cursor-pointer rounded border\"
style={{ accentColor: \"var(--color-input-border-select)\", borderColor: \"var(--color-inactive-checkbox)\" }}
/>
<span>
개인정보 수집 및 이용 동의 <span className=\"text-[#384fbf]\">(필수)</span>
</span>
</span>
</label>
</div>
</div>
{/* 버튼들 */}
<div className=\"flex gap-3\">
<Link
href=\"/login\"
className=\"h-14 flex-1 rounded-[12px] bg-[#f1f3f5] text-center grid place-items-center text-[18px] font-[600] text-[#4c5561]\"
>
돌아가기
</Link>
<button
type=\"submit\"
className=\"h-14 flex-1 rounded-[12px] text-[18px] font-[600] text-white\"
style={{ backgroundColor: \"var(--color-active-button)\" }}
disabled={!(agreeAge && agreeTos && agreePrivacy)}
>
회원 가입 완료
</button>
</div>
</form>
</div>
<div></div>
<p className=\"text-center text-[15px] text-basic-text\">
Copyright ⓒ 2025 XL LMS. All rights reserved
</p>
</div>
);
}
"use client";
import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
export default function RegisterPage() {
// form states
const [name, setName] = useState("");
const [phone, setPhone] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [passwordConfirm, setPasswordConfirm] = useState("");
const [gender, setGender] = useState<"male" | "female">("male");
const [birth, setBirth] = useState("");
// agreements
const [agreeAge, setAgreeAge] = useState(false);
const [agreeTos, setAgreeTos] = useState(false);
const [agreePrivacy, setAgreePrivacy] = useState(false);
const agreeAll = useMemo(
() => agreeAge && agreeTos && agreePrivacy,
[agreeAge, agreeTos, agreePrivacy],
);
function handleToggleAll(next: boolean) {
setAgreeAge(next);
setAgreeTos(next);
setAgreePrivacy(next);
}
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
if (!agreeAge || !agreeTos || !agreePrivacy) {
alert(" .");
return;
}
if (password.length < 8 || password.length > 16) {
alert(" 8~16 .");
return;
}
if (password !== passwordConfirm) {
alert(" .");
return;
}
// TODO: 실제 API 연동
console.log({
name,
phone,
email,
password,
gender,
birth,
agreements: { agreeAge, agreeTos, agreePrivacy },
});
alert(" . ()");
}
return (
<div className="min-h-screen w-full flex flex-col items-center justify-between">
<div></div>
<div className="rounded-xl bg-white max-w-[480px] w-full">
{/* 헤더 타이틀 */}
<div className="mb-10 flex flex-col items-center">
<div className="text-[24px] font-[700] leading-[150%] text-neutral-700">
회원가입
</div>
</div>
{/* 폼 */}
<form onSubmit={handleSubmit} className="space-y-6">
<div className="space-y-4">
{/* 이름 */}
<div className="space-y-2">
<label
htmlFor="name"
className="text-[15px] font-[600]"
style={{ color: "var(--color-basic-text)" }}
>
이름
</label>
<input
id="name"
name="name"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder=" ."
className="
h-10 px-[12px] py-[8px] w-full rounded-[8px] border border-neutral-40
focus:outline-none focus:ring-0 focus:ring-offset-0 focus:shadow-none
focus:appearance-none focus:border-neutral-700
text-[16px] text-neutral-700 font-[400] leading-[150%] placeholder:text-input-placeholder-text
"
/>
</div>
{/* 휴대폰 번호 */}
<div className="space-y-2">
<label
htmlFor="phone"
className="text-[15px] font-[600]"
style={{ color: "var(--color-basic-text)" }}
>
휴대폰 번호
</label>
<input
id="phone"
name="phone"
value={phone}
onChange={(e) => setPhone(e.target.value)}
placeholder="- ."
className="
h-10 px-[12px] py-[8px] w-full rounded-[8px] border border-neutral-40
focus:outline-none focus:ring-0 focus:ring-offset-0 focus:shadow-none
focus:appearance-none focus:border-neutral-700
text-[16px] text-neutral-700 font-[400] leading-[150%] placeholder:text-input-placeholder-text
"
/>
</div>
{/* 아이디(이메일) + 인증번호 전송 */}
<div className="space-y-2">
<label
htmlFor="email"
className="text-[15px] font-[600]"
style={{ color: "var(--color-basic-text)" }}
>
아이디 (이메일)
</label>
<div className="flex items-center gap-2">
<input
id="email"
name="email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder=" ."
className="
h-10 px-[12px] py-[8px] rounded-[8px] w-full border border-neutral-40
focus:outline-none focus:ring-0 focus:ring-offset-0 focus:shadow-none
focus:appearance-none focus:border-neutral-700
text-[16px] text-neutral-700 font-[400] leading-[150%] placeholder:text-input-placeholder-text
"
/>
<button
type="button"
className="h-10 w-[136px] rounded-[8px] text-[16px] font-[600] bg-[#f9fafb] text-[#b1b8c0]"
>
인증번호 전송
</button>
</div>
</div>
{/* 비밀번호 */}
<div className="space-y-2">
<label
htmlFor="password"
className="text-[15px] font-[600]"
style={{ color: "var(--color-basic-text)" }}
>
비밀번호
</label>
<input
id="password"
name="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="8~16 // ."
className="
h-10 px-[12px] py-[8px] w-full rounded-[8px] border border-neutral-40
focus:outline-none focus:ring-0 focus:ring-offset-0 focus:shadow-none
focus:appearance-none focus:border-neutral-700
text-[16px] text-neutral-700 font-[400] leading-[150%] placeholder:text-input-placeholder-text
"
/>
</div>
{/* 비밀번호 확인 */}
<div className="space-y-2">
<label
htmlFor="passwordConfirm"
className="text-[15px] font-[600]"
style={{ color: "var(--color-basic-text)" }}
>
비밀번호 확인
</label>
<input
id="passwordConfirm"
name="passwordConfirm"
type="password"
value={passwordConfirm}
onChange={(e) => setPasswordConfirm(e.target.value)}
placeholder=" ."
className="
h-10 px-[12px] py-[8px] w-full rounded-[8px] border border-neutral-40
focus:outline-none focus:ring-0 focus:ring-offset-0 focus:shadow-none
focus:appearance-none focus:border-neutral-700
text-[16px] text-neutral-700 font-[400] leading-[150%] placeholder:text-input-placeholder-text
"
/>
</div>
{/* 성별 */}
<div className="space-y-2">
div className="text-[15px] font-[600]" style={{ color: "var(--color-basic-text)" }}>
성별
</div>
<div className="flex items-center gap-5 h-10">
<label className="flex items-center gap-2 text-[15px] text-neutral-700">
<input
type="radio"
name="gender"
checked={gender === "male"}
onChange={() => setGender("male")}
className="h-[18px] w-[18px] rounded-full"
style={{ accentColor: "var(--color-active-button)" }}
/>
남성
</label>
<label className="flex items-center gap-2 text-[15px] text-neutral-700">
<input
type="radio"
name="gender"
checked={gender === "female"}
onChange={() => setGender("female")}
className="h-[18px] w-[18px] rounded-full"
style={{ accentColor: "var(--color-input-border)" }}
/>
여성
</label>
</div>
</div>
{/* 생년월일 */}
<div className="space-y-2">
<label
htmlFor="birth"
className="text-[15px] font-[600]"
style={{ color: "var(--color-basic-text)" }}
>
생년월일
</label>
<input
id="birth"
name="birth"
type="date"
value={birth}
onChange={(e) => setBirth(e.target.value)}
className="
h-10 px-[12px] py-[8px] w-full rounded-[8px] border border-neutral-40
focus:outline-none focus:ring-0 focus:ring-offset-0 focus:shadow-none
focus:appearance-none focus:border-neutral-700
text-[16px] text-neutral-700 font-[400] leading-[150%]
"
/>
</div>
</div>
{/* 약관 동의 */}
<div className="space-y-4">
<label className="flex cursor-pointer select-none items-center gap-2">
<input
type="checkbox"
checked={agreeAll}
onChange={(e) => handleToggleAll(e.target.checked)}
className="h-[20px] w-[20px] cursor-pointer rounded border"
style={{
accentColor: "var(--color-input-border-select)",
borderColor: "var(--color-inactive-checkbox)",
}}
/>
<span className="text-[18px] font-[600] text-neutral-700">모든 항목에 동의합니다.</span>
</label>
<div className="h-px w-full bg-neutral-200" />
<div className="space-y-3">
<label className="flex cursor-pointer select-none items-center justify-between">
<span className="flex items-center gap-2 text-[15px]" style={{ color: "var(--color-basic-text)" }}>
<input
type="checkbox"
checked={agreeAge}
onChange={(e) => setAgreeAge(e.target.checked)}
className="h-[20px] w-[20px] cursor-pointer rounded border"
style={{
accentColor: "var(--color-input-border-select)",
borderColor: "var(--color-inactive-checkbox)",
}}
/>
만 14세 이상입니다. <span className="text-[#384fbf]">(필수)</span>
</span>
</label>
<label className="flex cursor-pointer select-none items-center justify-between">
<span className="flex items-center gap-2 text-[15px]" style={{ color: "var(--color-basic-text)" }}>
<input
type="checkbox"
checked={agreeTos}
onChange={(e) => setAgreeTos(e.target.checked)}
className="h-[20px] w-[20px] cursor-pointer rounded border"
style={{
accentColor: "var(--color-input-border-select)",
borderColor: "var(--color-inactive-checkbox)",
}}
/>
이용 약관 동의 <span className="text-[#384fbf]">(필수)</span>
</span>
</label>
<label className="flex cursor-pointer select-none items-center justify-between">
<span className="flex items-center gap-2 text-[15px]" style={{ color: "var(--color-basic-text)" }}>
<input
type="checkbox"
checked={agreePrivacy}
onChange={(e) => setAgreePrivacy(e.target.checked)}
className="h-[20px] w-[20px] cursor-pointer rounded border"
style={{
accentColor: "var(--color-input-border-select)",
borderColor: "var(--color-inactive-checkbox)",
}}
/>
개인정보 수집 및 이용 동의 <span className="text-[#384fbf]">(필수)</span>
</span>
</label>
</div>
</div>
{/* 하단 버튼 */}
<div className="grid grid-cols-2 gap-3">
<Link
href="/login"
className="h-14 rounded-[12px] bg-[#f1f3f5] text-[18px] font-[600] text-center flex items-center justify-center"
style={{ color: "var(--color-basic-text)" }}
>
돌아가기
</Link>
<button
type="submit"
className="h-14 rounded-[12px] text-[18px] font-[600] text-white"
style={{ backgroundColor: "var(--color-inactive-button)" }}
>
회원 가입 완료
</button>
</div>
</form>
</div>
<div></div>
<p className="text-center text-[15px] text-basic-text">
Copyright 2025 XL LMS. All rights reserved
</p>
</div>
);
}

View File

@@ -0,0 +1,9 @@
import React from "react";
export default function LoginCheckboxActiveSvg() {
return (
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.1719 0C16.7343 0.000217172 18 1.26658 18 2.8291V15.1719C17.9998 16.7342 16.7342 17.9998 15.1719 18H2.8291C1.26658 18 0.000217172 16.7343 0 15.1719V2.8291C0 1.26645 1.26645 0 2.8291 0H15.1719ZM13.7695 6.28906C13.4081 5.92762 12.8215 5.92776 12.46 6.28906L7.97168 10.7783L5.54004 8.34668C5.17861 7.98543 4.59294 7.98554 4.23145 8.34668C3.87012 8.70822 3.86999 9.2948 4.23145 9.65625L7.31641 12.7422C7.67782 13.1034 8.26449 13.1033 8.62598 12.7422L13.7695 7.59863C14.1308 7.23716 14.1308 6.65053 13.7695 6.28906Z" fill="#1F2B91"/>
</svg>
);
}

View File

@@ -0,0 +1,11 @@
import React from "react";
export default function LoginCheckboxInactiveSvg() {
return (
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="18" height="18" fill="white" />
<path d="M15.1719 0C16.7343 0.000217172 18 1.26658 18 2.8291V15.1719L17.9854 15.4609C17.8503 16.7925 16.7925 17.8503 15.4609 17.9854L15.1719 18H2.8291L2.54004 17.9854C1.11332 17.8407 0.000203611 16.6368 0 15.1719V2.8291C0 1.36402 1.11319 0.159369 2.54004 0.0146484L2.8291 0H15.1719ZM2.8291 1.125C1.88777 1.125 1.125 1.88777 1.125 2.8291V15.1719C1.12513 16.1127 1.88743 16.875 2.8291 16.875H15.1719C16.113 16.8749 16.8749 16.113 16.875 15.1719V2.8291C16.875 1.94613 16.2049 1.22087 15.3457 1.13379L15.1719 1.125H2.8291Z" fill="#C2C8CF"/>
<path d="M12.4604 6.2896C12.8219 5.92827 13.408 5.92814 13.7694 6.2896C14.1307 6.65107 14.1307 7.23717 13.7694 7.59864L8.62608 12.742C8.26461 13.1033 7.6785 13.1033 7.31703 12.742L4.23125 9.65623C3.86979 9.29478 3.86993 8.70872 4.23125 8.34719C4.59277 7.98566 5.17877 7.98566 5.54029 8.34719L7.97155 10.7784L12.4604 6.2896Z" fill="#C2C8CF"/>
</svg>
);
}