router.push("/login")}
+ onClick={() => router.push("/onboarding")}
>
완료
diff --git a/src/assets/onboarding_profile.svg b/src/assets/onboarding_profile.svg
new file mode 100644
index 0000000..76a5642
--- /dev/null
+++ b/src/assets/onboarding_profile.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/assets/photo.svg b/src/assets/photo.svg
new file mode 100644
index 0000000..f4b7873
--- /dev/null
+++ b/src/assets/photo.svg
@@ -0,0 +1,18 @@
+
diff --git a/src/components/common/FullButton.tsx b/src/components/common/FullButton.tsx
index 0d39032..85f83d9 100644
--- a/src/components/common/FullButton.tsx
+++ b/src/components/common/FullButton.tsx
@@ -27,8 +27,8 @@ export const FullButton = ({
disabled={!isActive}
{...props}
>
-
-
{children}
+
+ {children}
);
diff --git a/src/components/common/AlertModal.tsx b/src/components/common/LoadingModal.tsx
similarity index 58%
rename from src/components/common/AlertModal.tsx
rename to src/components/common/LoadingModal.tsx
index bdb6b87..7bbc03a 100644
--- a/src/components/common/AlertModal.tsx
+++ b/src/components/common/LoadingModal.tsx
@@ -1,25 +1,33 @@
"use client";
-type AlertModalProps = {
+import { ALERT_BACKDROP_CLASS, AlertBackdrop } from "@/constants/alert";
+
+interface LoadingModalProps {
isOpen: boolean;
title: string;
- message: string;
+ message?: string;
confirmLabel?: string;
onClose: () => void;
-};
+ backdrop?: AlertBackdrop;
+ isLoading?: boolean;
+}
-export const AlertModal = ({
+const LoadingModal = ({
isOpen,
title,
message,
confirmLabel = "확인",
onClose,
-}: AlertModalProps) => {
+ backdrop = "default",
+ isLoading = false,
+}: LoadingModalProps) => {
if (!isOpen) return null;
return (
-
{message}
+ {isLoading ? (
+
+ ) : (
+ message && (
+
+ {message}
+
+ )
+ )}
@@ -47,3 +63,5 @@ export const AlertModal = ({
);
};
+
+export default LoadingModal;
diff --git a/src/components/common/NameInput.tsx b/src/components/common/NameInput.tsx
new file mode 100644
index 0000000..6d99d4c
--- /dev/null
+++ b/src/components/common/NameInput.tsx
@@ -0,0 +1,40 @@
+"use client";
+
+import { useEffect, useRef, useState } from "react";
+
+interface NameInputProps {
+ value: string;
+ onChange: (value: string) => void;
+}
+
+const PLACEHOLDER = "이름을 입력해주세요";
+const INITIAL_WIDTH = 204;
+
+export const NameInput = ({ value, onChange }: NameInputProps) => {
+ const spanRef = useRef
(null);
+ const [inputWidth, setInputWidth] = useState(INITIAL_WIDTH);
+
+ useEffect(() => {
+ if (!spanRef.current) return;
+
+ const spanWidth = spanRef.current.offsetWidth;
+ setInputWidth(spanWidth + 36);
+ }, [value]);
+
+ return (
+
+
+ {value || PLACEHOLDER}
+
+
+ onChange(e.target.value)}
+ placeholder={PLACEHOLDER}
+ style={{ width: inputWidth }}
+ className="border-mint-01 text-d3 text-neutral-01 placeholder:text-neutral-07 rounded-2xl border px-4 py-2 text-center transition-[width] duration-150 ease-out outline-none"
+ />
+
+ );
+};
diff --git a/src/components/dailyRecord/MissionFeed.tsx b/src/components/dailyRecord/MissionFeed.tsx
index c32df5d..393fc06 100644
--- a/src/components/dailyRecord/MissionFeed.tsx
+++ b/src/components/dailyRecord/MissionFeed.tsx
@@ -49,13 +49,13 @@ export const RecordMissionFeed = () => {
{otherRecords.map(item => (
-
+
diff --git a/src/components/onboarding/OnboardingProfile.tsx b/src/components/onboarding/OnboardingProfile.tsx
new file mode 100644
index 0000000..957640e
--- /dev/null
+++ b/src/components/onboarding/OnboardingProfile.tsx
@@ -0,0 +1,106 @@
+"use client";
+
+import { useRouter } from "next/navigation";
+
+import { useState } from "react";
+
+import { FullButton } from "@/components/common/FullButton";
+import LoadingModal from "@/components/common/LoadingModal";
+import { NameInput } from "@/components/common/NameInput";
+import ProfileImagePicker from "@/components/onboarding/ProfileImagePicker";
+import UploadButton from "@/components/onboarding/UploadButton";
+
+import { useProfileImageUpload } from "@/hooks/useProfileImageUpload";
+
+const OnboardingProfileClient = () => {
+ const router = useRouter();
+
+ const [name, setName] = useState("");
+ const [isUploadOpen, setIsUploadOpen] = useState(false);
+
+ const isNameValid = name.trim().length > 0;
+
+ const { profileImage, isLoading, uploadImage, resetImage, cancelUpload } =
+ useProfileImageUpload();
+
+ const handleCreateProfile = async () => {
+ if (!isNameValid) return;
+
+ // 1) 프로필 데이터 저장 (지금은 임시로 localStorage 예시)
+ const profile = {
+ name: name.trim(),
+ imageUrl: profileImage ?? null,
+ };
+ try {
+ // TODO: 실제 API로 교체
+ // await fetch("/api/profile", { method: "POST", body: JSON.stringify(profile) });
+ localStorage.setItem("onboardingProfile", JSON.stringify(profile));
+ } catch (e) {
+ // 에러 처리
+ console.error(e);
+ return;
+ }
+ // 2) 저장이 끝난 뒤에만 페이지 이동
+ router.replace("/login");
+ };
+
+ return (
+ <>
+
+
+
+
+ 가족들에게 보여줄{"\n"}내 프로필을 만들어주세요
+
+
+
+
+
setIsUploadOpen(true)}
+ />
+
+
+
+
+
+
+
+ {!isUploadOpen && (
+
+ 프로필생성하기
+
+ )}
+
+
+
+
setIsUploadOpen(false)}
+ onSelectAlbum={async file => {
+ try {
+ await uploadImage(file);
+ setIsUploadOpen(false);
+ } catch (error) {
+ console.error("이미지 업로드 실패:", error);
+ }
+ }}
+ onSelectDefault={() => {
+ resetImage();
+ setIsUploadOpen(false);
+ }}
+ />
+
+
+ >
+ );
+};
+
+export default OnboardingProfileClient;
diff --git a/src/components/onboarding/OnboardingStep.tsx b/src/components/onboarding/OnboardingStep.tsx
new file mode 100644
index 0000000..879cf52
--- /dev/null
+++ b/src/components/onboarding/OnboardingStep.tsx
@@ -0,0 +1,55 @@
+"use client";
+
+import Image from "next/image";
+
+import { FullButton } from "@/components/common/FullButton";
+
+import type { OnboardingStepName } from "@/constants/onboardingSteps";
+import { ONBOARDING_CONTENTS } from "@/constants/onboardingSteps";
+
+interface Props {
+ stepName: OnboardingStepName;
+ isLastStep: boolean;
+ onNext: () => void;
+}
+
+const OnboardingStep = ({ stepName, isLastStep, onNext }: Props) => {
+ const { title, background } = ONBOARDING_CONTENTS[stepName];
+ const [firstLine, secondLine] = title.split("\n");
+
+ return (
+
+ {background.type === "image" && (
+
+ )}
+
+ {background.type === "class" && (
+
+ )}
+
+
+
+
+ {firstLine}
+ {secondLine}
+
+
+
+ {isLastStep ? "시작하기" : "다음"}
+
+
+
+
+ );
+};
+
+export default OnboardingStep;
diff --git a/src/components/onboarding/ProfileImagePicker.tsx b/src/components/onboarding/ProfileImagePicker.tsx
new file mode 100644
index 0000000..6e3fb5e
--- /dev/null
+++ b/src/components/onboarding/ProfileImagePicker.tsx
@@ -0,0 +1,37 @@
+"use client";
+
+import ProfileIcon from "@/assets/onboarding_profile.svg";
+import PhotoIcon from "@/assets/photo.svg";
+
+type ProfileImagePickerProps = {
+ imageUrl: string | null;
+ onClick: () => void;
+};
+
+const ProfileImagePicker = ({ imageUrl, onClick }: ProfileImagePickerProps) => {
+ return (
+
+ {imageUrl ? (
+

+ ) : (
+
+ )}
+
+
+
+ );
+};
+
+export default ProfileImagePicker;
diff --git a/src/components/onboarding/ProgressDots.tsx b/src/components/onboarding/ProgressDots.tsx
new file mode 100644
index 0000000..71501a9
--- /dev/null
+++ b/src/components/onboarding/ProgressDots.tsx
@@ -0,0 +1,23 @@
+interface ProgressDotsProps {
+ total: number;
+ current: number;
+}
+
+export default function ProgressDots({ total, current }: ProgressDotsProps) {
+ return (
+
+
+ {Array.from({ length: total }).map((_, i) => {
+ const isActive = i <= current;
+
+ return (
+
+ );
+ })}
+
+
+ );
+}
diff --git a/src/components/onboarding/UploadButton.tsx b/src/components/onboarding/UploadButton.tsx
new file mode 100644
index 0000000..f5760d8
--- /dev/null
+++ b/src/components/onboarding/UploadButton.tsx
@@ -0,0 +1,116 @@
+"use client";
+
+import React, { useEffect, useRef } from "react";
+
+import { FullButton } from "@/components/common/FullButton";
+
+interface UploadButtonProps {
+ isOpen: boolean;
+ onClose: () => void;
+ onSelectAlbum: (file: File) => void;
+ onSelectDefault: () => void;
+}
+
+const UploadButton = ({
+ isOpen,
+ onClose,
+ onSelectAlbum,
+ onSelectDefault,
+}: UploadButtonProps) => {
+ const fileInputRef = useRef(null);
+ const modalRef = useRef(null);
+
+ useEffect(() => {
+ if (!isOpen) return;
+
+ const handleEscape = (e: KeyboardEvent) => {
+ if (e.key === "Escape") onClose();
+ };
+
+ document.addEventListener("keydown", handleEscape);
+ modalRef.current?.focus();
+
+ return () => {
+ document.removeEventListener("keydown", handleEscape);
+ };
+ }, [isOpen, onClose]);
+
+ if (!isOpen) return null;
+
+ const handleAlbumClick = () => {
+ if (fileInputRef.current) {
+ fileInputRef.current.value = "";
+ fileInputRef.current.click();
+ }
+ };
+
+ const handleFileChange = (e: React.ChangeEvent) => {
+ const file = e.target.files?.[0];
+ if (!file) return;
+
+ onSelectAlbum(file);
+ e.target.value = "";
+ onClose();
+ };
+
+ return (
+
+
e.stopPropagation()}
+ tabIndex={-1}
+ >
+
+
+ 프로필 사진 설정
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 취소하기
+
+
+
+
+ );
+};
+
+export default UploadButton;
diff --git a/src/components/password/PasswordForm.tsx b/src/components/password/PasswordForm.tsx
index 5a26f4f..453b786 100644
--- a/src/components/password/PasswordForm.tsx
+++ b/src/components/password/PasswordForm.tsx
@@ -7,8 +7,8 @@ import { useState } from "react";
import PhoneIcon from "@/assets/phone.svg";
import ProfileIcon from "@/assets/profile.svg";
-import { AlertModal } from "@/components/common/AlertModal";
import { FullButton } from "@/components/common/FullButton";
+import LoadingModal from "@/components/common/LoadingModal";
import { useCountdown } from "@/hooks/useCountdown";
import { usePhoneValidation } from "@/hooks/usePhoneValidation";
@@ -214,7 +214,7 @@ export const PasswordForm = () => {
{modalType && (
- {
? "인증이 완료되었습니다."
: "인증번호를 확인할 수 없습니다."
}
+ backdrop="default"
onClose={handleModalConfirm}
/>
)}
diff --git a/src/components/signup/ProfileForm.tsx b/src/components/signup/ProfileForm.tsx
index 89aedad..36fb778 100644
--- a/src/components/signup/ProfileForm.tsx
+++ b/src/components/signup/ProfileForm.tsx
@@ -8,8 +8,8 @@ import DateIcon from "@/assets/date.svg";
import PhoneIcon from "@/assets/phone.svg";
import ProfileIcon from "@/assets/profile.svg";
-import { AlertModal } from "@/components/common/AlertModal";
import { FullButton } from "@/components/common/FullButton";
+import LoadingModal from "@/components/common/LoadingModal";
import { useCountdown } from "@/hooks/useCountdown";
import { usePhoneValidation } from "@/hooks/usePhoneValidation";
@@ -245,7 +245,7 @@ export const ProfileForm = () => {
{modalType && (
-
= {
+ service: false,
+ finance: false,
+ personalRequired: false,
+ personalOption1: false,
+ personalOption2: false,
+ marketing: false,
+};
diff --git a/src/constants/alert.ts b/src/constants/alert.ts
new file mode 100644
index 0000000..99ba3d8
--- /dev/null
+++ b/src/constants/alert.ts
@@ -0,0 +1,7 @@
+export type AlertBackdrop = "default" | "light" | "blur";
+
+export const ALERT_BACKDROP_CLASS: Record = {
+ default: "bg-neutral-01/30",
+ light: "bg-neutral-01/50",
+ blur: "bg-neutral-01/50 backdrop-blur-[7px]",
+};
diff --git a/src/constants/onboardingSteps.ts b/src/constants/onboardingSteps.ts
new file mode 100644
index 0000000..b2021b5
--- /dev/null
+++ b/src/constants/onboardingSteps.ts
@@ -0,0 +1,43 @@
+export const ONBOARDING_STEPS = ["전체", "커뮤니티", "정원"] as const;
+
+export type OnboardingStepName = (typeof ONBOARDING_STEPS)[number];
+
+export type OnboardingFunnelSteps = {
+ 전체: object;
+ 커뮤니티: object;
+ 정원: object;
+};
+
+type OnboardingBackground =
+ | { type: "image"; src: string }
+ | { type: "class"; className: string };
+
+export const ONBOARDING_CONTENTS: Record<
+ OnboardingStepName,
+ {
+ title: string;
+ background: OnboardingBackground;
+ }
+> = {
+ 전체: {
+ title: "시니어와 가족이 조금 편하게\n연결될 수 있도록",
+ background: {
+ type: "image",
+ src: "/images/onboarding-step-1.svg",
+ },
+ },
+ 커뮤니티: {
+ title: "작은 순간도 반가운 소식이\n될 수 있도록",
+ background: {
+ type: "image",
+ src: "/images/onboarding-step-2.svg",
+ },
+ },
+ 정원: {
+ title: "소중한 마음을 모아 정원을\n꾸며볼까요?",
+ background: {
+ type: "image",
+ src: "/images/onboarding-step-3.svg",
+ },
+ },
+};
diff --git a/src/hooks/usePasswordValidation.ts b/src/hooks/usePasswordValidation.ts
index ed8a983..bc75ede 100644
--- a/src/hooks/usePasswordValidation.ts
+++ b/src/hooks/usePasswordValidation.ts
@@ -1,9 +1,11 @@
export const usePasswordValidation = () => {
+ // const isValidPassword = (pwd: string) => {
+ // const hasLetter = /[A-Za-z]/.test(pwd);
+ // const hasNumber = /\d/.test(pwd);
+ // const hasSpecial = /[^A-Za-z0-9]/.test(pwd);
+ // return pwd.length >= 8 && hasLetter && hasNumber && hasSpecial;
const isValidPassword = (pwd: string) => {
- const hasLetter = /[A-Za-z]/.test(pwd);
- const hasNumber = /\d/.test(pwd);
- const hasSpecial = /[^A-Za-z0-9]/.test(pwd);
- return pwd.length >= 8 && hasLetter && hasNumber && hasSpecial;
+ return pwd.length >= 8;
};
const getState = (value: string, isValid: boolean) => {
diff --git a/src/hooks/useProfileImageUpload.ts b/src/hooks/useProfileImageUpload.ts
new file mode 100644
index 0000000..ccc4285
--- /dev/null
+++ b/src/hooks/useProfileImageUpload.ts
@@ -0,0 +1,53 @@
+"use client";
+
+import { useState } from "react";
+
+//import { uploadImageFile } from "@/utils/upload";
+
+export const useProfileImageUpload = () => {
+ const [profileImage, setProfileImage] = useState(null);
+ const [isLoading, setIsLoading] = useState(false);
+
+ const uploadImage = async (file: File) => {
+ setIsLoading(true);
+
+ await new Promise(res => setTimeout(res, 2000));
+
+ const imageUrl = URL.createObjectURL(file);
+ setProfileImage(imageUrl);
+
+ setIsLoading(false);
+ };
+
+ const cancelUpload = () => {
+ setIsLoading(false);
+ };
+
+ // const uploadImage = async (file: File) => {
+ // try {
+ // setIsLoading(true);
+ // const { url } = await uploadImageFile(file);
+ // setProfileImage(url);
+ // } finally {
+ // setIsLoading(false);
+ // }
+ // };
+
+ const resetImage = () => {
+ setProfileImage(null);
+ };
+
+ // return {
+ // profileImage,
+ // isLoading,
+ // uploadImage,
+ // resetImage,
+ // };
+ return {
+ profileImage,
+ isLoading,
+ uploadImage,
+ resetImage,
+ cancelUpload,
+ } as const;
+};
diff --git a/src/styles/globals.css b/src/styles/globals.css
index c9b4367..788865a 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -40,8 +40,6 @@
--color-neutral-10: #f3f3f4;
--color-neutral-11: #f9f9fb;
--color-white: #fefefe;
-
- --color-dim-02: #242628D4;
}
@layer utilities {
@@ -66,13 +64,6 @@
);
}
- .bg-dim02-gradient {
- background: linear-gradient(
- 0deg,
- rgba(36, 38, 40, 0.83) 0%,
- rgba(36, 38, 40, 0.83) 100%
- )
- }
.bg-onboarding-circle-mint {
border-radius: 146px;
background: linear-gradient(
@@ -115,3 +106,24 @@
}
}
+@layer utilities{
+ .loader {
+ width: 48px;
+ height: 48px;
+ border: 5px solid var(--color-white);
+ border-bottom-color: var(--color-mint-01);
+ border-radius: 50%;
+ display: inline-block;
+ box-sizing: border-box;
+ animation: rotation 1s linear infinite;
+ }
+}
+@keyframes rotation {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
diff --git a/src/types/agreement.type.ts b/src/types/agreement.type.ts
new file mode 100644
index 0000000..d65639e
--- /dev/null
+++ b/src/types/agreement.type.ts
@@ -0,0 +1,7 @@
+export type AgreementKey =
+ | "service" // 심톡 이용약관 동의 (필수)
+ | "finance" // 전자금융거래 이용약관 동의 (필수)
+ | "personalRequired" // 개인정보 수집 이용 동의 (필수)
+ | "personalOption1" // 개인정보 수집 이용 동의 (선택)
+ | "personalOption2" // 개인정보 수집 이용 동의 (선택)
+ | "marketing"; // 마케팅 정보 수신 동의 (선택)
diff --git a/src/utils/upload.ts b/src/utils/upload.ts
new file mode 100644
index 0000000..75a0b65
--- /dev/null
+++ b/src/utils/upload.ts
@@ -0,0 +1,27 @@
+// export interface UploadImageResult {
+// url: string;
+// fileName: string;
+// }
+
+// export const uploadImageFile = async (
+// file: File,
+// ): Promise => {
+// const formData = new FormData();
+// formData.append("file", file);
+
+// const res = await fetch("/api/uploads/image", {
+// method: "POST",
+// body: formData,
+// });
+
+// if (!res.ok) {
+// throw new Error("이미지 업로드에 실패했습니다.");
+// }
+
+// const data = (await res.json()) as { url: string; fileName: string };
+
+// return {
+// url: data.url,
+// fileName: data.fileName,
+// };
+// };
diff --git a/yarn.lock b/yarn.lock
index 4a6fba9..552b8aa 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -847,7 +847,7 @@
"@babel/plugin-transform-modules-commonjs" "^7.27.1"
"@babel/plugin-transform-typescript" "^7.28.5"
-"@babel/runtime@^7.14.8", "@babel/runtime@^7.19.0", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.8", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2":
+"@babel/runtime@^7.23.8", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2":
version "7.28.4"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326"
integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==
@@ -1507,63 +1507,6 @@
postcss "^8.4.41"
tailwindcss "4.1.18"
-"@toss/assert@^1.2.2":
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/@toss/assert/-/assert-1.2.2.tgz#78a96586e134edd38947553b20a18bc24a692c52"
- integrity sha512-qK2G1LzI2ghY0aUOsz9mFiy2v/eNlMHG5qXdSogfGFLxHqFZ6KQWJQpnb9eN+dyHYIudBVWPZhbkljqnT8R3/g==
- dependencies:
- "@toss/utils" "^1.6.1"
-
-"@toss/react@^1.8.1":
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/@toss/react/-/react-1.8.1.tgz#d69d9e5dfed21c8f9fa791473293239e31ac5dda"
- integrity sha512-jH3oo/7yctexuutj/YgQrddaK1bU2s5659dkJIXOe23bEjkY+lbhvEz2FLEhRjSo6k6ktPagpxO4AcdhCi5k5A==
- dependencies:
- "@babel/runtime" "^7.14.8"
- "@toss/storage" "^1.4.1"
- "@toss/utils" "^1.6.1"
- classnames "^2.3.1"
- lodash.debounce "^4.0.8"
- lodash.throttle "^4.1.1"
-
-"@toss/storage@^1.4.1":
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/@toss/storage/-/storage-1.4.1.tgz#c7f03946244a35631dbd4f40a7c513c314750f86"
- integrity sha512-jvnBXAQ/Fqqdt+gqYKeHYk7SzR2LX/FC50JIoVI0RldG1mDh1tebOqD7XkrZ89q77t/RwTuh60+8fjZDgend/g==
- dependencies:
- "@babel/runtime" "^7.19.0"
-
-"@toss/use-funnel@^1.4.2":
- version "1.4.2"
- resolved "https://registry.yarnpkg.com/@toss/use-funnel/-/use-funnel-1.4.2.tgz#08e7d681e4f200fb83159100c037fb195dd43e8e"
- integrity sha512-qgfYhdoJh07D4+kyRgRE3Du5wEdecFOR9Ht3MjgFMYAJyGplNbD++hpD/FcXrGT5oa14KG0bB5bpp60KLmPkFw==
- dependencies:
- "@toss/assert" "^1.2.2"
- "@toss/react" "^1.8.1"
- "@toss/storage" "^1.4.1"
- "@toss/use-query-param" "^1.3.1"
- "@toss/utils" "^1.6.1"
- fast-deep-equal "^3.1.3"
-
-"@toss/use-query-param@^1.3.1":
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/@toss/use-query-param/-/use-query-param-1.3.1.tgz#a9bc67692972f300b8d011e00f0af17f6fa3d7d0"
- integrity sha512-GRA+6st46/88KgmP9PGx8mV9sxxkewwLMzBl25TpXPjnqHz+tiZdybVZMQ5UHj0Kzf7bZnHGF3kd5oko492vxA==
-
-"@toss/utility-types@^1.2.1":
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/@toss/utility-types/-/utility-types-1.2.1.tgz#3c67bea23b7aaffd4b4e7c2a518773ae22a496f6"
- integrity sha512-1y8s1bvmuhuMX/d6qR9mmvcgFZIKYIQqJbAIshlGArXkjk/ec67gXc5uByEV1Y7in9ZhrGNRmjD8DTH0988vpQ==
-
-"@toss/utils@^1.6.1":
- version "1.6.1"
- resolved "https://registry.yarnpkg.com/@toss/utils/-/utils-1.6.1.tgz#e1226b1274b3d7e04b5b648ef11accdc013568c3"
- integrity sha512-x6m8jLKWtAmCbxTLXbgTzJ5wZyRSUQPLpR/oLJP1ZK9ytXcRf03oA46W/+78kErUkEw/yQz2L+t2xFDHSeZ6IQ==
- dependencies:
- "@babel/runtime" "^7.14.8"
- "@toss/utility-types" "^1.2.1"
- date-fns "^2.25.0"
-
"@trivago/prettier-plugin-sort-imports@^6.0.0":
version "6.0.1"
resolved "https://registry.yarnpkg.com/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-6.0.1.tgz#b71c020c4069c0b7a75953227ad6c803cea3f568"
@@ -2345,11 +2288,6 @@ chrome-trace-event@^1.0.2:
resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b"
integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==
-classnames@^2.3.1:
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b"
- integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==
-
cli-cursor@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-5.0.0.tgz#24a4831ecf5a6b01ddeb32fb71a4b2088b0dce38"
@@ -2521,13 +2459,6 @@ data-view-byte-offset@^1.0.1:
es-errors "^1.3.0"
is-data-view "^1.0.1"
-date-fns@^2.25.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"
-
debug@^3.2.7:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
@@ -3875,11 +3806,6 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
-lodash.throttle@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
- integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==
-
log-update@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/log-update/-/log-update-6.1.0.tgz#1a04ff38166f94647ae1af562f4bd6a15b1b7cd4"