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
5 changes: 5 additions & 0 deletions app/admin/tasks/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import TasksPage from '~/components/admin/tasks/tasks-page'

export default function AdminTasksPage() {
return <TasksPage />
}
61 changes: 37 additions & 24 deletions components/admin/album/album-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { SquarePenIcon } from '~/components/icons/square-pen'
import { DeleteIcon } from '~/components/icons/delete'
import { useTranslations } from 'next-intl'
import { Badge } from '~/components/ui/badge'
import { AnimatedIconTrigger, mergeAnimatedTriggerProps } from '~/components/icons/animated-trigger'

export default function AlbumList(props : Readonly<HandleProps>) {
const { data, mutate } = useSwrHydrated(props)
Expand Down Expand Up @@ -108,34 +109,46 @@ export default function AlbumList(props : Readonly<HandleProps>) {
<Badge variant="secondary" aria-label={t('Words.sort')}><ArrowDown10 size={18}/>{album.sort}</Badge>
</div>
<div className="space-x-1">
<Button
variant="outline"
size="icon"
onClick={() => {
setAlbumEditData(album)
setAlbumEdit(true)
}}
aria-label={t('Album.editAlbum')}
>
<SquarePenIcon />
</Button>
<Dialog onOpenChange={(value) => {
if (!value) {
setAlbum({} as AlbumType)
}
}}>
<DialogTrigger asChild>
<AnimatedIconTrigger>
{({ iconRef, triggerProps }) => (
<Button
variant="outline"
size="icon"
onClick={() => {
setAlbum(album)
}}
aria-label={t('Album.deleteAlbum')}
aria-label={t('Album.editAlbum')}
{...mergeAnimatedTriggerProps({
onClick: () => {
setAlbumEditData(album)
setAlbumEdit(true)
},
}, triggerProps)}
>
<DeleteIcon />
<SquarePenIcon ref={iconRef} />
</Button>
</DialogTrigger>
)}
</AnimatedIconTrigger>
<Dialog onOpenChange={(value) => {
if (!value) {
setAlbum({} as AlbumType)
}
}}>
<AnimatedIconTrigger>
{({ iconRef, triggerProps }) => (
<DialogTrigger asChild>
<Button
variant="outline"
size="icon"
aria-label={t('Album.deleteAlbum')}
{...mergeAnimatedTriggerProps({
onClick: () => {
setAlbum(album)
},
}, triggerProps)}
>
<DeleteIcon ref={iconRef} />
</Button>
</DialogTrigger>
)}
</AnimatedIconTrigger>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>{t('Tips.reallyDelete')}</DialogTitle>
Expand Down Expand Up @@ -164,4 +177,4 @@ export default function AlbumList(props : Readonly<HandleProps>) {
))}
</div>
)
}
}
156 changes: 100 additions & 56 deletions components/admin/list/list-props.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
} from '~/components/ui/popover'
import { RefreshCWIcon } from '~/components/icons/refresh-cw.tsx'
import { CircleChevronDownIcon } from '~/components/icons/circle-chevron-down.tsx'
import { AnimatedIconTrigger, mergeAnimatedTriggerProps } from '~/components/icons/animated-trigger'

export default function ListProps(props : Readonly<ImageServerHandleProps>) {
const [pageNum, setPageNum] = useState(1)
Expand Down Expand Up @@ -263,37 +264,54 @@ export default function ListProps(props : Readonly<ImageServerHandleProps>) {
</div>
</div>
<div className="flex items-center space-x-1">
<Button
variant="outline"
size="icon"
aria-label={t('Button.batchDelete')}
onClick={() => setImageBatchDelete(true)}
>
<DeleteIcon />
</Button>
<Button
className="cursor-pointer"
variant="outline"
size="icon"
disabled={isLoading}
onClick={async () => {
await totalMutate()
await mutate()
}}
aria-label={t('Button.refresh')}
>
<RefreshCWIcon />
</Button>
<Popover>
<PopoverTrigger asChild>
<AnimatedIconTrigger>
{({ iconRef, triggerProps }) => (
<Button
variant="outline"
size="icon"
aria-label={t('Button.batchDelete')}
{...mergeAnimatedTriggerProps({
onClick: () => setImageBatchDelete(true)
}, triggerProps)}
>
<DeleteIcon ref={iconRef} />
</Button>
)}
</AnimatedIconTrigger>
<AnimatedIconTrigger>
{({ iconRef, triggerProps }) => (
<Button
className="flex sm:hidden cursor-pointer"
className="cursor-pointer"
variant="outline"
size="icon"
disabled={isLoading}
aria-label={t('Button.refresh')}
{...mergeAnimatedTriggerProps({
onClick: async () => {
await totalMutate()
await mutate()
},
}, triggerProps)}
>
<CircleChevronDownIcon />
<RefreshCWIcon ref={iconRef} />
</Button>
</PopoverTrigger>
)}
</AnimatedIconTrigger>
<Popover>
<AnimatedIconTrigger>
{({ iconRef, triggerProps }) => (
<PopoverTrigger asChild>
<Button
className="flex sm:hidden cursor-pointer"
variant="outline"
size="icon"
{...mergeAnimatedTriggerProps({}, triggerProps)}
>
<CircleChevronDownIcon ref={iconRef} />
</Button>
</PopoverTrigger>
)}
</AnimatedIconTrigger>
<PopoverContent className="w-80">
<div className="flex flex-col items-center space-y-1">
<Select
Expand Down Expand Up @@ -464,17 +482,23 @@ export default function ListProps(props : Readonly<ImageServerHandleProps>) {
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<Button
variant="outline"
size="icon"
onClick={() => {
setImageEditData(image)
setImageEdit(true)
}}
aria-label={t('List.editImage')}
>
<SquarePenIcon />
</Button>
<AnimatedIconTrigger>
{({ iconRef, triggerProps }) => (
<Button
variant="outline"
size="icon"
aria-label={t('List.editImage')}
{...mergeAnimatedTriggerProps({
onClick: () => {
setImageEditData(image)
setImageEdit(true)
},
}, triggerProps)}
>
<SquarePenIcon ref={iconRef} />
</Button>
)}
</AnimatedIconTrigger>
</div>
</CardFooter>
</Card>
Expand All @@ -500,29 +524,49 @@ export default function ListProps(props : Readonly<ImageServerHandleProps>) {
))}
</SelectContent>
</Select>
<ChevronLeftIcon
onClick={async () => {
if (pageNum > 1) {
setPageNum(pageNum - 1)
await mutate()
}
}}
size={18}
/>
<ChevronRightIcon
onClick={async () => {
if (pageNum < Math.ceil((total ?? 0) / pageSize)) {
setPageNum(pageNum + 1)
await mutate()
}
}}
size={18}
/>
<AnimatedIconTrigger>
{({ iconRef, triggerProps }) => (
<button
type="button"
aria-label="Previous page"
className="inline-flex items-center justify-center rounded-md"
{...mergeAnimatedTriggerProps({
onClick: async () => {
if (pageNum > 1) {
setPageNum(pageNum - 1)
await mutate()
}
},
}, triggerProps)}
>
<ChevronLeftIcon ref={iconRef} size={18} />
</button>
)}
</AnimatedIconTrigger>
<AnimatedIconTrigger>
{({ iconRef, triggerProps }) => (
<button
type="button"
aria-label="Next page"
className="inline-flex items-center justify-center rounded-md"
{...mergeAnimatedTriggerProps({
onClick: async () => {
if (pageNum < Math.ceil((total ?? 0) / pageSize)) {
setPageNum(pageNum + 1)
await mutate()
}
},
}, triggerProps)}
>
<ChevronRightIcon ref={iconRef} size={18} />
</button>
)}
</AnimatedIconTrigger>
</div>
}
<ImageEditSheet {...{...props, pageNum, album}} />
<ImageView />
<ImageBatchDeleteSheet {...{...props, dataProps, pageNum, album}} />
</div>
)
}
}
Loading
Loading