8000 Feature/ux 3 by guesung · Pull Request #109 · guesung/Web-Memo · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Feature/ux 3 #109

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

Merged
merged 12 commits into from
Nov 29, 2024
2 changes: 1 addition & 1 deletion packages/shared/src/hooks/supabase/useMemosQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ export default function useMemosQuery({ supabaseClient, ...useQueryProps }: UseM

return {
...query,
memos: query.data?.data,
memos: query.data?.data ?? [],
};
}
1 change: 1 addition & 0 deletions packages/ui/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"@/*": ["./src/*"]
},
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"moduleResolution": "node"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default async function LoginSection({ lng }: LoginSectionProps) {
const { t } = await useTranslation(lng);

return (
<section className="relative flex w-96 flex-col items-center justify-center rounded-md bg-zinc-100 py-12 opacity-80 shadow-xl dark:bg-zinc-900">
<section className="relative flex flex-col items-center justify-center rounded-md bg-zinc-100 px-8 py-12 opacity-80 shadow-xl dark:bg-zinc-900">
<p className="text-center text-2xl">{t('login.welcomeTitle')}</p>
<p className="text-md text-center">{t('login.welcomeDescription')}</p>
<div className="h-8" />
Expand All @@ -21,8 +21,8 @@ export default async function LoginSection({ lng }: LoginSectionProps) {
<Button
formAction={signInWithOAuth.bind(null, 'kakao')}
className="h-12 bg-[rgb(247,228,76)] text-black hover:bg-[rgb(247,228,76)]">
{t('login.kakaoLogin')}
<Image src="/images/svgs/kakao.svg" width={16} height={16} alt="kakao" />
{t('login.kakaoLogin')}
</Button>
{/* 'use server' 함수를 사용하기 위해 bind 사용 */}
<Button formAction={signInWithOAuth.bind(null, 'google')} className="h-12 bg-white text-black hover:bg-white">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use server';

import { PATHS } from '@extension/shared/constants';
import { checkUserLogin, getUser } from '@extension/shared/utils';
import { ToggleTheme } from '@src/components';
import { Avatar, AvatarFallback, AvatarImage } from '@src/components/ui/avatar';
Expand All @@ -9,7 +10,6 @@ import {
DropdownMenuLabel,
DropdownMenuTrigger,
} from '@src/components/ui/dropdown-menu';
import { PATHS } from '@extension/shared/constants';
import { LanguageType } from '@src/modules/i18n';
import useTranslation from '@src/modules/i18n/server';
import { getSupabaseClient, signout } from '@src/modules/supabase/util.server';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export default function MemoOption({ lng, memoId }: MemoOptionProps) {

const handleDeleteMemo: MouseEventHandler<HTMLDivElement> = event => {
event.stopPropagation();

mutateDeleteMemo(memoId, {
onSuccess: ({ data }) => {
if (!data) return;
Expand Down Expand Up @@ -101,7 +102,7 @@ export default function MemoOption({ lng, memoId }: MemoOptionProps) {
return (
<DropdownMenu open={isOpen} modal={false}>
<DropdownMenuTrigger asChild>
<Button variant="link" size="sm">
<Button variant="ghost" size="icon" => e.stopPropagation()}>
<EllipsisVerticalIcon size={16} />
</Button>
</DropdownMenuTrigger>
Expand All @@ -110,15 +111,19 @@ export default function MemoOption({ lng, memoId }: MemoOptionProps) {
<DropdownMenuItem className="cursor-pointer">
{t('option.deleteMemo')}
</DropdownMenuItem>
<DropdownMenuItem className="cursor-pointer">
<DropdownMenuItem>
<Select defaultValue={String(memoData?.category_id)}>
<SelectTrigger>
<SelectValue placeholder={t('option.changeCategory')} />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{categories?.map(category => (
<SelectItem key={category.id} value={String(category.id)} id={String(category.id)}>
<SelectItem
key={category.id}
value={String(category.id)}
id={String(category.id)}
className="cursor-pointer">
{category.name}
</SelectItem>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useMemoPatchMutation } from '@extension/shared/hooks';
import { useSearchParams } from '@extension/shared/modules/search-params';
import { GetMemoResponse } from '@extension/shared/utils';
import { Badge } from '@src/components/ui/badge';
import { Button } from '@src/components/ui/button';
import { CardFooter } from '@src/components/ui/card';
import { ToastAction } from '@src/components/ui/toast';
import { useSupabaseClient } from '@src/hooks';
Expand All @@ -11,7 +12,7 @@ import useTranslation from '@src/modules/i18n/client';
import { cn } from '@src/utils';
import { HeartIcon } from 'lucide-react';
import { useRouter } from 'next/navigation';
import { MouseEvent, MouseEventHandler, PropsWithChildren } from 'react';
import { MouseEvent, PropsWithChildren } from 'react';

import MemoOption from './MemoOption';

Expand All @@ -37,7 +38,9 @@ export default function MemoCardFooter({ memo, lng, isHovered, children, ...prop
router.replace(searchParams.getUrl(), { scroll: false });
};

const handleIsWishClick: MouseEventHandler<SVGSVGElement> = () => {
const handleIsWishClick = (event: MouseEvent<HTMLButtonElement>) => {
event.stopPropagation();

mutateMemoPatch(
{
id: memo.id,
Expand Down Expand Up @@ -72,30 +75,31 @@ export default function MemoCardFooter({ memo, lng, isHovered, children, ...prop
};

return (
<CardFooter className={cn('flex justify-between p-0 px-4 pb-2 pt-0')} {...props}>
<CardFooter className={cn('flex justify-between p-0 px-4 pb-2 pt-0', props.className)} {...props}>
<div>
{memo.category?.name ? (
<Badge variant="outline" className="z-10 cursor-pointer">
<Badge variant="outline" role="button" className="z-10">
{memo.category?.name}
</Badge>
) : (
<span />
)}
</div>
<div
className={cn('flex items-center gap-2 transition', {
className={cn('flex items-center transition', {
'opacity-0': !isHovered,
'opacity-100': isHovered,
})}>
<HeartIcon
size={12}
fill={memo.isWish ? 'pink' : ''}
fillOpacity={memo.isWish ? 100 : 0}
>
className={cn('cursor-pointer transition-transform hover:scale-110', 'active:scale-95', {
'animate-heart-pop': memo.isWish,
})}
/>
<Button variant="ghost" size="icon" >
<HeartIcon
size={12}
fill={memo.isWish ? 'pink' : ''}
fillOpacity={memo.isWish ? 100 : 0}
className={cn('transition-transform hover:scale-110 active:scale-95', {
'animate-heart-pop': memo.isWish,
})}
/>
</Button>
<MemoOption memoId={memo.id} lng={lng} />
{children}
</div>
Expand Down
33 changes: 21 additions & 12 deletions packages/web/src/app/[lng]/memos/components/MemoDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,25 @@ import { useToast } from '@src/hooks/use-toast';
import { LanguageType } from '@src/modules/i18n';
import useTranslation from '@src/modules/i18n/client';
import { useRouter } from 'next/navigation';
import { FocusEvent, useEffect } from 'react';
import { FocusEvent, useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';

import { MemoInput } from '../../types';
import MemoCardFooter from '../MemoCardFooter';
import MemoCardHeader from '../MemoCardHeader';

interface MemoDialog extends LanguageType {}
interface MemoDialog extends LanguageType {
id: string;
}

export default function MemoDialog({ lng }: MemoDialog) {
export default function MemoDialog({ lng, id }: MemoDialog) {
const { t } = useTranslation(lng);
const searchParams = useSearchParams();
const id = searchParams.get('id');
const router = useRouter();
const supabaseClient = useSupabaseClient();
const { memo: memoData } = useMemoQuery({ supabaseClient, id: Number(id) });
const { toast } = useToast();
const [open, setOpen] = useState(false);
const { mutate: mutateMemoPatch } = useMemoPatchMutation({
supabaseClient,
});
Expand Down Expand Up @@ -68,10 +70,14 @@ export default function MemoDialog({ lng }: MemoDialog) {
setValue('memo', memoData?.memo ?? '');
}, [memoData, setValue]);

useEffect(() => {
setOpen(!!id);
}, [id]);

if (!id || !memoData) return;
return (
<Dialog open={!!id}>
<DialogContent className="max-w-[600px] p-0">
<Dialog open={open} >}>
<DialogContent className="max-w-[600px] p-0" >>
<Card>
<MemoCardHeader memo={memoData as GetMemoResponse} />
<CardContent>
Expand All @@ -81,6 +87,7 @@ export default function MemoDialog({ lng }: MemoDialog) {
})}
>
>
className="outline-none focus:border-gray-300 focus:outline-none"
/>

<div className="h-4" />
Expand All @@ -89,12 +96,14 @@ export default function MemoDialog({ lng }: MemoDialog) {
</span>
</CardContent>
<MemoCardFooter memo={memoData as GetMemoResponse} lng={lng} isHovered>
<Button variant="outline" type="button">
닫기
</Button>
<Button variant="outline" >
저장
</Button>
<div className="flex gap-2">
<Button variant="outline" type="button" >
{t('common.close')}
</Button>
<Button variant="outline" >
{t('common.save')}
</Button>
</div>
</MemoCardFooter>
</Card>
</DialogContent>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { useCategoryPostMutation } from '@extension/shared/hooks';
import { Button } from '@src/components/ui/button';
import { Input } from '@src/components/ui/input';
import { useSupabaseClient } from '@src/hooks';
import { PlusIcon } from 'lucide-react';
Expand Down Expand Up @@ -28,15 +29,17 @@ export default memo(function SidebarMenuItemAddCategory() {
setIsEditMode(true);
};

if (isEditMode)
return (
<form >
<Input {...register('category')} />
</form>
);
return (
<p className="flex cursor-pointer justify-center">
<PlusIcon size={16} />
</p>
<div className="flex justify-center">
{isEditMode ? (
<form >
<Input {...register('category')} />
</form>
) : (
<Button className="flex justify-center" role="button" variant="ghost" size="icon">
<PlusIcon size={16} />
</Button>
)}
</div>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default async function MemoSidebar({ lng }: LanguageType) {
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<Link href={PATHS.memosSetting} className="mb-2 ml-2 cursor-pointer">
<Link href={PATHS.memosSetting} className="mb-2 ml-2">
<SettingsIcon size={16} />
</Link>
</TooltipTrigger>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,16 @@ export default async function MemoSidebarTrigger({ lng }: MemoSidebarTriggerProp
const { t } = await useTranslation(lng);

return (
<div>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<SidebarTrigger />
</TooltipTrigger>
<TooltipContent>
<p>{t('tooltip.sideBar')}</p>
<p>Control/Command + B</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<SidebarTrigger />
</TooltipTrigger>
<TooltipContent>
<p>{t('tooltip.sideBar')}</p>
<p>Control/Command + B</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default memo(function MemoItem({ lng, memo, ...props }: MemoItemProps) {

if (!memo) return null;

const handleContentClick = (event: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>) => {
const handleItemClick = (event: MouseEvent<HTMLElement> | KeyboardEvent<HTMLElement>) => {
const id = event.currentTarget.id;
if (!id) return;

Expand All @@ -39,24 +39,18 @@ export default memo(function MemoItem({ lng, memo, ...props }: MemoItemProps) {

return (
<motion.article
id={String(memo.id)}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3 }}
>
=> e.key === 'Enter' && handleItemClick(e)}
className="transition-all"
tabIndex={0}
{...props}>
<Card className="relative box-border w-[300px]" >
<MemoCardHeader memo={memo} />
{memo.memo && (
<CardContent
className="whitespace-break-spaces break-all"
>
id={String(memo.id)}
role="button"
tabIndex={0}
=> e.key === 'Enter' && handleContentClick(e)}>
{memo.memo}
</CardContent>
)}
{memo.memo && <CardContent className="whitespace-break-spaces break-all">{memo.memo}</CardContent>}
<MemoCardFooter memo={memo} lng={lng} isHovered={isHovered} />
</Card>
</motion.article>
Expand Down
25 changes: 15 additions & 10 deletions packages/web/src/app/[lng]/memos/components/MemoView/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
'use client';

import { useMemosQuery } from '@extension/shared/hooks';
import { useSearchParams } from '@extension/shared/modules/search-params';
import { useSupabaseClient } from '@src/hooks';
import { useGuide } from '@src/modules/guide';
import { LanguageType } from '@src/modules/i18n';
import { useTranslation } from 'react-i18next';

import MemoGrid from './MemoGrid';

interface MemoViewProps extends LanguageType {}
interface MemoViewProps extends LanguageType {
isWish?: string;
category?: string;
}

export default function MemoView({ lng }: MemoViewProps) {
export default function MemoView({ lng, isWish = '', category = '' }: MemoViewProps) {
const { t } = useTranslation(lng);
const searchParams = useSearchParams();
const supabaseClient = useSupabaseClient();
const isWish = searchParams.get('isWish') === 'true';
const category = searchParams.get('category');

const { memos } = useMemosQuery({
supabaseClient,
Expand All @@ -25,10 +24,16 @@ export default function MemoView({ lng }: MemoViewProps) {
useGuide({ lng });

const filteredMemos = memos
?.filter(memo => isWish === !!memo.isWish)
?.filter(memo => !!isWish === !!memo.isWish)
.filter(memo => (category ? memo.category?.name === category : true));

if (!filteredMemos || filteredMemos.length === 0)
return <p className="mt-8 w-full text-center">{t('memos.emptyState.message')}</p>;
return <MemoGrid memos={filteredMemos} gridKey={category + isWish} lng={lng} />;
return (
<div className="flex w-full flex-col gap-4">
<p className="text-muted-foreground text-sm">
{category && `${category} | `}
{t('memos.totalMemos', { total: filteredMemos.length })}
</p>
<MemoGrid memos={filteredMemos} gridKey={category + isWish} lng={lng} />
</div>
);
}
Loading
0