Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #168 프론트 퍼블리싱 #170

Merged
merged 4 commits into from
Nov 27, 2024
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
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 };