Skip to content

Commit

Permalink
Feature #168 프론트 퍼블리싱 (#170)
Browse files Browse the repository at this point in the history
* style(#168):  배경색 변경, border shadow 변경

* feat(#168):  HistoryListEmpty Ui

* style(#168):  detail page 반응형 추가

* feat(#168):  온보딩 페이지 캐러셀
  • Loading branch information
ATeals authored Nov 27, 2024
1 parent 5bc8524 commit 36b63a9
Show file tree
Hide file tree
Showing 17 changed files with 130 additions and 25 deletions.
2 changes: 1 addition & 1 deletion apps/frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Froxy</title>
</head>
<body>
<body class="bg-zinc-100">
<div id="root"></div>
<script type="module" src="/src/app/main.tsx"></script>
</body>
Expand Down
1 change: 1 addition & 0 deletions apps/frontend/public/json/emptyHistoryAnimation.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion apps/frontend/src/app/style/github.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
font-size: 16px;
line-height: 1.6;
color: #24292e;
background-color: #ffffff;
}

/* Headings */
Expand Down
19 changes: 11 additions & 8 deletions apps/frontend/src/page/index.lazy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Button, Heading } from '@froxy/design/components';
import { createLazyFileRoute, getRouteApi } from '@tanstack/react-router';
import { FaGithub } from 'react-icons/fa';
import { LoginButton } from '@/widget/navigation/LoginButton';
import { OnBoardingCarousel } from '@/widget/onboarding/OnboardingCarousel';

const { useNavigate } = getRouteApi('/');

Expand All @@ -13,14 +14,16 @@ function RouteComponent() {
const navigate = useNavigate();

return (
<main className="mx-auto px-12 w-full max-w-screen-xl h-screen flex justify-center items-center">
<section className="flex-1 flex justify-center">
<img className="max-w-lg" src="/image/onboardingImage.svg" alt="frog" />
</section>
<section className="flex-1 flex flex-col items-center gap-6 pl-12">
<Heading size="sm" className="mb-4">
Gist clone과정을 폴짝! 건너뛰고 테스트 ⭐️
</Heading>
<main className="w-screen h-screen">
<OnBoardingCarousel />
<section className="bg-white w-full h-1/2 lg:h-1/3 lg:w-1/3 flex flex-col gap-5 justify-center items-center lg:items-start fixed top-1/2 lg:right-0 lg:m-10 transform -translate-y-1/2 p-10 rounded-lg shadow-lg">
<div className="flex gap-2">
<img src="/image/logoIcon.svg" className="rounded-lg w-6 h-6" />
<Heading size="sm" className="mb-4">
FROXY
</Heading>
</div>

<Button className="w-full max-w-lg" variant={'default'} onClick={() => navigate({ to: '/lotus' })}>
공개 프로젝트 보러가기
</Button>
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/widget/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function Header() {
const image = data?.profile || '/image/exampleImage.jpeg';

return (
<header className="flex justify-center mb-7 w-full shadow-md">
<header className="flex justify-center mb-7 w-full shadow-md bg-white">
<div className="w-full max-w-screen-xl py-5 px-4 sm:px-6 lg:px-8 flex justify-between items-center">
<Button className="flex items-center gap-4" variant={null} onClick={() => handleClick()}>
<img className="w-14 h-14" src="/image/logoIcon.svg" alt="로고" />
Expand Down
21 changes: 18 additions & 3 deletions apps/frontend/src/widget/history/SuspenseLotusHistoryList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
AccordionTrigger,
Button,
Heading,
Skeleton
Skeleton,
Text
} from '@froxy/design/components';
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
import { useQueryErrorResetBoundary, useSuspenseQuery } from '@tanstack/react-query';
Expand All @@ -22,12 +23,14 @@ export function SuspenseLotusHistoryList({ id, page = 1 }: { id: string; page?:
data: { list }
} = useSuspenseQuery(lotusHistoryQueryOptions.list({ id, page }));

if (list.length < 1) return <SuspenseLotusHistoryListEmpty />;

const pendingHistoriesId = HistoryModel.getPendingHistoriesId(list);

const firstPageFirstItem = page === 1 ? [list[0]?.id] : [];

return (
<div className="flex flex-col gap-5 min-h-[700px]">
<div className="min-h-[700px]">
{/* NOTE : key를 이용해 갱신해야 Pending 상태인 Content 고정 가능 */}
<Accordion
key={new Date().getTime()}
Expand All @@ -37,7 +40,7 @@ export function SuspenseLotusHistoryList({ id, page = 1 }: { id: string; page?:
{list.map((history) => (
<AccordionItem
key={history.id}
className="shadow-zinc-300 shadow-md rounded-md p-5 px-7 gap-7"
className="shadow-zinc-300 bg-white shadow-md rounded-md p-5 my-2 px-7 gap-7"
value={history.id}
>
<AccordionTrigger value={history.id} disabled={history.status === 'PENDING'}>
Expand All @@ -58,6 +61,18 @@ export function SuspenseLotusHistoryList({ id, page = 1 }: { id: string; page?:
);
}

export function SuspenseLotusHistoryListEmpty() {
return (
<div className="w-full h-full flex flex-col justify-center items-center">
<DotLottieReact src="/json/emptyHistoryAnimation.json" loop autoplay className="w-102" />
<Heading className="py-4" size="lg">
History가 없습니다.
</Heading>
<Text variant="muted">Lotus를 실행해보세요!</Text>
</div>
);
}

export function SkeletonLotusHistoryList() {
return (
<div className="flex flex-col gap-5 min-h-[700px]">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function SuspenseLotusDetail({ id }: { id: string }) {

function SkeletonLotusDetail() {
return (
<div className="flex justify-between items-start pb-4 border-b-2 border-slate-200">
<div className="flex justify-between items-start pb-4 border-slate-200">
<div>
<div className="mb-4">
<Skeleton className="font-bold mr-4 w-32 h-10" />
Expand Down
4 changes: 2 additions & 2 deletions apps/frontend/src/widget/lotusDetail/SuspenseLotusFiles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export function SuspenseLotusFiles({ id }: { id: string }) {

return (
<CodeView value={files} current={defaultFileIndex}>
<div className="flex github gap-4 w-full h-[600px] pb-10 px-2 overflow-hidden">
<CodeView.SideBar className="h-full min-w-48" />
<div className="flex github gap-4 w-full h-[600px] py-5 px-2 overflow-hidden rounded-lg">
<CodeView.SideBar className="h-full min-w-48 bg-white" />
<CodeView.Viewer className="block h-full px-2" />
</div>
</CodeView>
Expand Down
8 changes: 4 additions & 4 deletions apps/frontend/src/widget/lotusList/LotusSearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export function LotusSearchBar({ current = '' }: { current?: string }) {
};

return (
<form className="flex justify-between items-center w-full p-6 border-2 border-slate-200 rounded-xl shadow-sm mb-10">
<div>
<form className="block md:flex justify-between items-center w-full p-6 bg-white rounded-xl shadow-md mb-10">
<div className="mb-5 md:mb-0">
<Heading size="lg" variant="bold" className="pb-1">
Lotus
</Heading>
Expand All @@ -32,13 +32,13 @@ export function LotusSearchBar({ current = '' }: { current?: string }) {
<IoIosSearch />
</div>
<Input
className={'pl-9 min-w-[21rem]'}
className={'pl-9 md:min-w-[21rem]'}
value={keyword}
onChange={(e) => setKeyword(e.target.value.trim())}
placeholder="제목을 검색해주세요"
/>
</div>
<Button variant={'outline'} className={'px-8'} onClick={submit}>
<Button variant={'outline'} className={'px-8 hidden md:block'} onClick={submit}>
검색하기
</Button>
</div>
Expand Down
4 changes: 2 additions & 2 deletions apps/frontend/src/widget/lotusList/SuspenseLotusCardList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ export function SuspenseLotusList({ queryOptions }: { queryOptions: LotusLostQue
} = useSuspenseQuery(queryOptions);

return (
<div className="w-full grid grid-cols-3 gap-8">
<div className="w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 place-items-center">
{lotuses?.map(({ lotus, author }) => (
<Lotus lotus={lotus} key={lotus.id}>
<User user={author}>
<Lotus.Link className="max-w-96 p-5 shadow-md bg-white rounded-xl">
<Lotus.Link className="w-full h-full lg:w-82 p-5 shadow-md bg-white rounded-xl hover:shadow-lg hover:shadow-neutral-400 transition-shadow duration-200">
<Lotus.Title className="text-[#1C1D22]" />
<User.Name className="text-[rgba(28,29,34,0.5)]" />
<div className="w-full flex justify-between items-end">
Expand Down
58 changes: 58 additions & 0 deletions apps/frontend/src/widget/onboarding/OnBoardingCarousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useEffect, useRef, useState } from 'react';
import { AutoPlay, cn } from '@froxy/design';
import { OnBoardingItems } from './constant';
import { Carousel, CarouselApi, CarouselContent, CarouselItem, Heading } from '@/components';

export function OnBoardingCarousel() {
const [api, setApi] = useState<CarouselApi>();
const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
if (!api) {
return;
}

api.on('select', () => {
if (!ref.current) return;

ref.current.style.backgroundColor = `#${Math.floor(Math.random() * 16777215).toString(16)}`;
});
}, [api]);

return (
<Carousel
ref={ref}
opts={{ loop: true }}
plugins={[AutoPlay({ delay: 3000 })]}
setApi={setApi}
orientation="vertical"
className="transition-colors duration-500 ease-in-out hidden lg:flex"
>
<CarouselContent className="w-screen h-screen m-0">
{OnBoardingItems.map((item) => (
<CarouselItem className="min-h-full p-0" key={item.title}>
<div className={cn('w-full h-full flex flex-col items-start justify-center p-20')}>
<div className="w-1/2 flex flex-col justify-center items-center gap-10">
<div className="rounded-full bg-white shadow-lg p-5">{item.icon}</div>

<div className={cn('flex gap-5 w-full pr-10', item?.description ? 'justify-start' : 'justify-center')}>
<div className="rounded-lg p-5 bg-white shadow-lg">
<Heading size="sm">{item.title}</Heading>
</div>
</div>

<div className="pl-10">
{item?.description && (
<div className="rounded-lg p-5 bg-white shadow-lg">
<Heading size="sm">{item.description}</Heading>
</div>
)}
</div>
</div>
</div>
</CarouselItem>
))}
</CarouselContent>
</Carousel>
);
}
23 changes: 23 additions & 0 deletions apps/frontend/src/widget/onboarding/constant.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FaCheckCircle, FaGithub } from 'react-icons/fa';

export const OnBoardingItems = [
{
icon: <FaGithub size={80} />,
title: 'Gist clone과정을 폴짝! 건너뛰고 테스트',
description: '손쉽게 Gist를 실행하고, 공유하세요.'
},
{
icon: <div className="flex justify-center items-center w-20 h-20 p-2 text-5xl">⚡️</div>,
title: 'Gist 실행, Froxy와 함께라면 순식간에!',
description: 'Froxy는 당신의 시간과 노력을 아껴주는 완벽한 도우미입니다.'
},
{
icon: <FaCheckCircle size={80} />,
title: '하나하나 clone하기 힘들죠?',
description: 'Froxy는 Gist를 clone하고, 실행하는 과정을 간소화합니다.'
},
{
icon: <div className="flex justify-center items-center w-20 h-20 p-2 text-5xl">🔥</div>,
title: 'Froxy에 맡기고 코드에 집중하세요!'
}
];
1 change: 1 addition & 0 deletions apps/frontend/src/widget/onboarding/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './OnBoardingCarousel';
1 change: 1 addition & 0 deletions packages/design/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@radix-ui/react-tabs": "^1.1.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"embla-carousel-autoplay": "^8.5.1",
"embla-carousel-react": "^8.3.1",
"lucide-react": "^0.454.0",
"react": "^18.3.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/design/src/components/ui/pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ PaginationLink.displayName = 'PaginationLink';
const PaginationPrevious = ({ className, ...props }: React.ComponentProps<typeof PaginationLink>) => (
<PaginationLink aria-label="Go to previous page" size="default" className={cn('gap-1 pl-2.5', className)} {...props}>
<ChevronLeft className="h-4 w-4" />
<span>Previous</span>
<span>Prev</span>
</PaginationLink>
);
PaginationPrevious.displayName = 'PaginationPrevious';
Expand Down
2 changes: 1 addition & 1 deletion packages/design/src/components/ui/skeleton.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { cn } from '@/lib/utils';

function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
return <div className={cn('animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-800', className)} {...props} />;
return <div className={cn('animate-pulse rounded-md bg-neutral-200 dark:bg-neutral-800', className)} {...props} />;
}

export { Skeleton };
4 changes: 4 additions & 0 deletions packages/design/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import AutoPlay from 'embla-carousel-autoplay';

export * from '@/components';
export * from '@/lib/utils';
export * from '@radix-ui/react-slot';

export { AutoPlay };

0 comments on commit 36b63a9

Please sign in to comment.