Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/components/auth/skeleton/AuthFormSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Skeleton } from "@/components/common/skeleton/Skeleton";

export default function AuthFormSkeleton() {
return (
<div className="flex w-full flex-col items-center bg-white">
<div className="w-full max-w-[360px]">
<div className="mb-10 flex flex-col gap-2">
<Skeleton className="h-8 w-40" />
<Skeleton className="h-8 w-56" />
</div>

<div className="flex flex-col gap-6">
<div className="flex gap-2">
<Skeleton className="h-14 flex-1 rounded-2xl" />
<Skeleton className="h-14 w-28 rounded-2xl" />
</div>

<Skeleton className="h-14 w-full rounded-2xl" />

<div className="mt-4">
<Skeleton className="h-14 w-full rounded-2xl" />
</div>
</div>
</div>
</div>
);
}
53 changes: 53 additions & 0 deletions src/components/auth/skeleton/LoginSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {
Skeleton,
SkeletonCircle,
} from "@/components/common/skeleton/Skeleton";

export default function LoginSkeleton() {
return (
<div className="flex min-h-screen w-full items-center justify-center bg-white">
<div className="w-full max-w-130 px-6 pt-30 pb-12">
<div className="mb-10 flex justify-center">
<Skeleton className="h-8 w-32" />
</div>

<div className="flex flex-col gap-7">
<div className="flex flex-col gap-2">
<Skeleton className="h-5 w-16" />
<Skeleton className="h-12 w-full rounded-2xl" />
</div>
<div className="flex flex-col gap-2">
<Skeleton className="h-5 w-20" />
<Skeleton className="h-12 w-full rounded-2xl" />
</div>

<div className="mt-3 flex justify-center">
<Skeleton className="h-4 w-48" />
</div>

<div className="mt-10">
<Skeleton className="h-14 w-full rounded-2xl" />
</div>
</div>

<div className="mt-12 flex flex-col items-center">
<div className="flex items-center gap-12">
<SkeletonCircle className="h-14 w-14" />
<SkeletonCircle className="h-14 w-14" />
<SkeletonCircle className="h-14 w-14" />
</div>

<div className="mt-12 flex w-full items-center gap-4 px-10">
<Skeleton className="h-px flex-1" />
<Skeleton className="h-4 w-8 bg-transparent" />
<Skeleton className="h-px flex-1" />
</div>

<div className="mt-6">
<Skeleton className="h-4 w-32" />
</div>
</div>
</div>
</div>
);
}
18 changes: 18 additions & 0 deletions src/components/auth/skeleton/SignupSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Skeleton } from "@/components/common/skeleton/Skeleton";

export default function SignupSkeleton() {
return (
<div className="flex w-full flex-col items-center">
<div className="flex w-full flex-col gap-10">
<Skeleton className="h-16 w-full rounded-2xl" />
<Skeleton className="h-16 w-full rounded-2xl" />
<Skeleton className="h-16 w-full rounded-2xl" />
<Skeleton className="h-16 w-full rounded-2xl" />
</div>

<div className="mt-15 flex justify-center gap-2">
<Skeleton className="h-4 w-40" />
</div>
</div>
);
}
31 changes: 31 additions & 0 deletions src/components/auth/skeleton/SignupStep01Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Skeleton } from "@/components/common/skeleton/Skeleton";

export default function SignupStep01Skeleton() {
return (
<div className="flex w-full flex-col items-center">
<div className="w-full max-w-90">
<div className="mb-10 flex flex-col gap-2">
<Skeleton className="h-8 w-48" />
<Skeleton className="h-8 w-56" />
</div>

<div className="flex flex-col gap-6">
<div className="flex gap-2">
<div className="flex-1 flex flex-col gap-2">
<Skeleton className="h-14 w-full rounded-2xl" />
</div>
<Skeleton className="h-14 w-24 rounded-2xl" />
</div>

<div className="flex flex-col gap-2">
<Skeleton className="h-14 w-full rounded-2xl" />
</div>

<div className="mt-4">
<Skeleton className="h-14 w-full rounded-2xl" />
</div>
</div>
</div>
</div>
);
}
24 changes: 24 additions & 0 deletions src/components/common/skeleton/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { HTMLAttributes } from "react";
import cx from "clsx";

interface ISkeletonProps extends HTMLAttributes<HTMLDivElement> {
className?: string;
}

export function Skeleton({ className, ...props }: ISkeletonProps) {
return (
<div
className={cx("animate-shimmer rounded bg-gray-200", className)}
{...props}
/>
);
}

export function SkeletonCircle({ className, ...props }: ISkeletonProps) {
return (
<div
className={cx("animate-shimmer rounded-full bg-gray-200", className)}
{...props}
/>
);
}
36 changes: 27 additions & 9 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ button {
--color-chart-3: #1485ff;
--color-chart-4: #00aeef;
--color-chart-5: #4fc3f7;
--color-chart-inactive: #F2F4F6;
--color-chart-inactive: #f2f4f6;

/* Status */
--color-status-red: #ff2a4b;
Expand All @@ -57,14 +57,14 @@ button {
--color-text-auth-sub: #546171;
--color-text-sub: #8b8b8f;
--color-text-placeholder: #c3c3c3;
--color-text-disabled: #B0B8C1;
--color-bg-disabled: #E5E8EB;
--color-text-disabled: #b0b8c1;
--color-bg-disabled: #e5e8eb;

/* Social */
--color-social-kakao: #FEE500;
--color-social-naver: #03C75A;
--color-social-kakao: #fee500;
--color-social-naver: #03c75a;
--color-social-google: #ffffff;
--color-social-text-kakao: #3A1D1D;
--color-social-text-kakao: #3a1d1d;
}

@font-face {
Expand Down Expand Up @@ -117,7 +117,7 @@ button {
line-height: 130%;
}

/* CommonAuthInput 위 폰트 */
/* CommonAuthInput 위 폰트 */
.font-label {
font-size: 14px;
font-weight: 700;
Expand Down Expand Up @@ -181,10 +181,12 @@ button {
width: 24px;
height: 24px;
border-radius: 50%;
background-color: #E5E8EB;
background-color: #e5e8eb;
cursor: pointer;
position: relative;
transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
transition:
background-color 0.2s ease-in-out,
border-color 0.2s ease-in-out;
flex-shrink: 0;
}
.checkbox:checked {
Expand Down Expand Up @@ -232,4 +234,20 @@ button {
.animate-fade-in-up {
animation: fade-in-up 0.8s ease-out forwards;
}

/* Shimmer */
@keyframes shimmer {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}

.animate-shimmer {
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite linear;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Toaster } from "sonner";

import ModalProvider from "@/components/modal/ModalProvider";

export default function DefaultLayout() {
export default function GlobalLayout() {
return (
<>
<Outlet />
Expand Down
5 changes: 1 addition & 4 deletions src/layout/auth/AuthLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Suspense } from "react";
import { Outlet } from "react-router-dom";

import OnboardingIntro from "@/components/auth/common/OnboardingIntro";
Expand All @@ -12,9 +11,7 @@ export default function AuthLayout() {

<div className="flex w-full items-center justify-center bg-white 2xl:w-[65%]">
<div className="w-full max-w-md px-6">
<Suspense fallback={<div>Loading...</div>}>
<Outlet />
</Suspense>
<Outlet />
</div>
</div>
</div>
Expand Down
5 changes: 1 addition & 4 deletions src/layout/main/MainLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { Suspense } from "react";
import { Outlet } from "react-router-dom";

export default function MainLayout() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<Outlet />
</Suspense>
<Outlet />
</div>
);
}
43 changes: 37 additions & 6 deletions src/routes/AuthRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,46 @@
import { lazy } from "react";
import type { RouteObject } from "react-router-dom";
import { lazy, Suspense } from "react";
import { type RouteObject, useLocation } from "react-router-dom";

const FindEmail = lazy(() => import("@/pages/auth/FindEmail"));
const FindPw = lazy(() => import("@/pages/auth/FindPw"));
const Login = lazy(() => import("@/pages/auth/Login"));
import { loadable } from "@/utils/loadable";

import AuthFormSkeleton from "@/components/auth/skeleton/AuthFormSkeleton";
import LoginSkeleton from "@/components/auth/skeleton/LoginSkeleton";
import SignupSkeleton from "@/components/auth/skeleton/SignupSkeleton";
import SignupStep01Skeleton from "@/components/auth/skeleton/SignupStep01Skeleton";

const FindEmail = loadable(
lazy(() => import("@/pages/auth/FindEmail")),
<AuthFormSkeleton />,
);
const FindPw = loadable(
lazy(() => import("@/pages/auth/FindPw")),
<AuthFormSkeleton />,
);
const Login = loadable(
lazy(() => import("@/pages/auth/Login")),
<LoginSkeleton />,
);

// Signup은 Fallback이 달라짐 -> raw lazy 컴포넌트 사용
const Signup = lazy(() => import("@/pages/auth/Signup"));

function SignupPage() {
const location = useLocation();
const step = location.state?.step;

return (
<Suspense
fallback={step === 1 ? <SignupStep01Skeleton /> : <SignupSkeleton />}
>
<Signup />
</Suspense>
);
}

const AuthRoutes: RouteObject[] = [
{
path: "signup",
element: <Signup />,
element: <SignupPage />,
},
{
path: "login",
Expand Down
32 changes: 25 additions & 7 deletions src/routes/MainRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
import { lazy } from "react";
import type { RouteObject } from "react-router-dom";

const OverviewDashboard = lazy(
() => import("@/pages/dashboard/overview/OverviewDashboard"),
import { loadable } from "@/utils/loadable";

const OverviewDashboard = loadable(
lazy(() => import("@/pages/dashboard/overview/OverviewDashboard")),
);
const PlatformDashboard = loadable(
lazy(() => import("@/pages/dashboard/platform/PlatformDashboard")),
);
const Timeline = loadable(
lazy(() => import("@/pages/dashboard/timeline/Timeline")),
);
const AdsListPage = loadable(
lazy(() => import("@/pages/ads/list/AdsListPage")),
);
const PlatformDashboard = lazy(
() => import("@/pages/dashboard/platform/PlatformDashboard"),
const AdsCreatePage = loadable(
lazy(() => import("@/pages/ads/new/AdsCreatePage")),
);
const Timeline = lazy(() => import("@/pages/dashboard/timeline/Timeline"));
const AdsListPage = lazy(() => import("@/pages/ads/list/AdsListPage"));
const AdsCreatePage = lazy(() => import("@/pages/ads/new/AdsCreatePage"));
const Setting = loadable(lazy(() => import("@/pages/setting/Setting")));
const Workspace = loadable(lazy(() => import("@/pages/workspace/Workspace")));

const MainRoutes: RouteObject[] = [
{
Expand All @@ -32,6 +42,14 @@ const MainRoutes: RouteObject[] = [
path: "ads/create",
element: <AdsCreatePage />,
},
{
path: "setting",
element: <Setting />,
},
{
path: "workspace",
element: <Workspace />,
},
];

export default MainRoutes;
Loading