mirror of
https://github.com/perfect-panel/ppanel-web.git
synced 2026-02-15 04:41:10 -05:00
💄 style(document): Update
This commit is contained in:
parent
872252c98c
commit
0a8109bbc4
@ -2,27 +2,26 @@
|
|||||||
|
|
||||||
import { queryDocumentDetail } from '@/services/user/document';
|
import { queryDocumentDetail } from '@/services/user/document';
|
||||||
import { Markdown } from '@repo/ui/markdown';
|
import { Markdown } from '@repo/ui/markdown';
|
||||||
import { Button } from '@shadcn/ui/button';
|
import { formatDate } from '@repo/ui/utils';
|
||||||
|
import { Avatar, AvatarFallback } from '@shadcn/ui/avatar';
|
||||||
|
import { buttonVariants } from '@shadcn/ui/button';
|
||||||
import { useOutsideClick } from '@shadcn/ui/hooks/use-outside-click';
|
import { useOutsideClick } from '@shadcn/ui/hooks/use-outside-click';
|
||||||
|
import { cn } from '@shadcn/ui/lib/utils';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import { useEffect, useId, useRef, useState } from 'react';
|
import { useEffect, useId, useRef, useState } from 'react';
|
||||||
|
|
||||||
interface Item {
|
export function DocumentButton({ items }: { items: API.DocumentItem[] }) {
|
||||||
id: number;
|
const [active, setActive] = useState<API.DocumentItem | boolean | null>(null);
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
export function DocumentButton({ items }: { items: Item[] }) {
|
|
||||||
const [active, setActive] = useState<Item | boolean | null>(null);
|
|
||||||
const id = useId();
|
const id = useId();
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const { data } = useQuery({
|
const { data } = useQuery({
|
||||||
enabled: !!(active as Item)?.id,
|
enabled: !!(active as API.DocumentItem)?.id,
|
||||||
queryKey: ['queryDocumentDetail', (active as Item)?.id],
|
queryKey: ['queryDocumentDetail', (active as API.DocumentItem)?.id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data } = await queryDocumentDetail({
|
const { data } = await queryDocumentDetail({
|
||||||
id: (active as Item)?.id,
|
id: (active as API.DocumentItem)?.id,
|
||||||
});
|
});
|
||||||
return data.data?.content;
|
return data.data?.content;
|
||||||
},
|
},
|
||||||
@ -87,31 +86,48 @@ export function DocumentButton({ items }: { items: Item[] }) {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
className='bg-muted flex size-full flex-col overflow-auto p-6 sm:rounded'
|
className='bg-muted flex size-full flex-col overflow-auto p-6 sm:rounded'
|
||||||
>
|
>
|
||||||
<Markdown
|
<Markdown>{data || ''}</Markdown>
|
||||||
components={{
|
|
||||||
img: ({ node, className, ...props }) => {
|
|
||||||
return (
|
|
||||||
// eslint-disable-next-line @next/next/no-img-element
|
|
||||||
<img {...props} width={800} height={600} className='my-4 h-auto' />
|
|
||||||
);
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{data || ''}
|
|
||||||
</Markdown>
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
<ul className='flex w-full flex-wrap items-start gap-4'>
|
<ul className='flex w-full flex-col gap-4'>
|
||||||
{items.map((item, index) => (
|
{items.map((item, index) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
layoutId={`card-${item.id}-${id}`}
|
layoutId={`card-${item.id}-${id}`}
|
||||||
key={item.id}
|
key={`card-${item.id}-${id}`}
|
||||||
onClick={() => setActive(item)}
|
onClick={() => setActive(item)}
|
||||||
className='flex cursor-pointer flex-col rounded-xl'
|
className='bg-background hover:bg-accent flex cursor-pointer items-center justify-between rounded border p-4'
|
||||||
>
|
>
|
||||||
<Button variant='secondary'>{item.title}</Button>
|
<div className='flex flex-row items-center gap-4'>
|
||||||
|
<motion.div layoutId={`image-${item.id}-${id}`}>
|
||||||
|
<Avatar className='size-12'>
|
||||||
|
<AvatarFallback className='bg-primary'>{item.title.split('')[0]}</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
</motion.div>
|
||||||
|
<div className=''>
|
||||||
|
<motion.h3 layoutId={`title-${item.id}-${id}`} className='font-medium'>
|
||||||
|
{item.title}
|
||||||
|
</motion.h3>
|
||||||
|
<motion.p
|
||||||
|
layoutId={`description-${item.id}-${id}`}
|
||||||
|
className='text-sm text-neutral-600 dark:text-neutral-400'
|
||||||
|
>
|
||||||
|
{formatDate(item.updated_at)}
|
||||||
|
</motion.p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<motion.button
|
||||||
|
layoutId={`button-${item.id}-${id}`}
|
||||||
|
className={cn(
|
||||||
|
buttonVariants({
|
||||||
|
variant: 'secondary',
|
||||||
|
}),
|
||||||
|
'rounded-full',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
阅读
|
||||||
|
</motion.button>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
import { getTutorial } from '@/utils/tutorial';
|
import { getTutorial } from '@/utils/tutorial';
|
||||||
import { Markdown } from '@repo/ui/markdown';
|
import { Markdown } from '@repo/ui/markdown';
|
||||||
import { Button } from '@shadcn/ui/button';
|
import { Avatar, AvatarFallback } from '@shadcn/ui/avatar';
|
||||||
|
import { buttonVariants } from '@shadcn/ui/button';
|
||||||
import { useOutsideClick } from '@shadcn/ui/hooks/use-outside-click';
|
import { useOutsideClick } from '@shadcn/ui/hooks/use-outside-click';
|
||||||
|
import { cn } from '@shadcn/ui/lib/utils';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import { useEffect, useId, useRef, useState } from 'react';
|
import { useEffect, useId, useRef, useState } from 'react';
|
||||||
@ -90,7 +92,12 @@ export function TutorialButton({ items }: { items: Item[] }) {
|
|||||||
img: ({ node, className, ...props }) => {
|
img: ({ node, className, ...props }) => {
|
||||||
return (
|
return (
|
||||||
// eslint-disable-next-line @next/next/no-img-element
|
// eslint-disable-next-line @next/next/no-img-element
|
||||||
<img {...props} width={800} height={600} className='my-4 h-auto' />
|
<img
|
||||||
|
{...props}
|
||||||
|
width={800}
|
||||||
|
height={384}
|
||||||
|
className='my-4 inline-block size-auto max-h-96'
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
@ -101,15 +108,43 @@ export function TutorialButton({ items }: { items: Item[] }) {
|
|||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
<ul className='flex w-full flex-wrap items-start gap-4'>
|
<ul className='flex w-full flex-col gap-4'>
|
||||||
{items.map((item) => (
|
{items.map((item, index) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
layoutId={`card-${item.title}-${id}`}
|
layoutId={`card-${item.title}-${id}`}
|
||||||
key={item.title}
|
key={`card-${item.title}-${id}`}
|
||||||
onClick={() => setActive(item)}
|
onClick={() => setActive(item)}
|
||||||
className='flex cursor-pointer flex-col rounded-xl'
|
className='bg-background hover:bg-accent flex cursor-pointer items-center justify-between rounded border p-4'
|
||||||
>
|
>
|
||||||
<Button variant='secondary'>{item.title}</Button>
|
<div className='flex flex-row items-center gap-4'>
|
||||||
|
<motion.div layoutId={`image-${item.title}-${id}`}>
|
||||||
|
<Avatar className='size-12'>
|
||||||
|
<AvatarFallback className='bg-primary'>{item.title.split('')[0]}</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
</motion.div>
|
||||||
|
<div className=''>
|
||||||
|
<motion.h3 layoutId={`title-${item.title}-${id}`} className='font-medium'>
|
||||||
|
{item.title}
|
||||||
|
</motion.h3>
|
||||||
|
{/* <motion.p
|
||||||
|
layoutId={`description-${item.title}-${id}`}
|
||||||
|
className='text-center text-neutral-600 md:text-left dark:text-neutral-400'
|
||||||
|
>
|
||||||
|
{formatDate(item.updated_at)}
|
||||||
|
</motion.p> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<motion.button
|
||||||
|
layoutId={`button-${item.title}-${id}`}
|
||||||
|
className={cn(
|
||||||
|
buttonVariants({
|
||||||
|
variant: 'secondary',
|
||||||
|
}),
|
||||||
|
'rounded-full',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
阅读
|
||||||
|
</motion.button>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user