Skip to content

Commit

Permalink
Merge pull request #119 from besscroft/dev
Browse files Browse the repository at this point in the history
v1.0.0
  • Loading branch information
besscroft authored Sep 28, 2024
2 parents 9d0e465 + 73c9128 commit c6a9233
Show file tree
Hide file tree
Showing 39 changed files with 3,603 additions and 2,142 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ PicImpact
</p>

<p align="center">
<img src=picimpact.png width=384 />
<img src=picimpact.jpg width=384 />
</p>

PicImpact 是一个摄影师专用的摄影作品展示网站,基于 Next.js 开发。
Expand All @@ -24,6 +24,7 @@ PicImpact 是一个摄影师专用的摄影作品展示网站,基于 Next.js
- 支持批量自动化上传,上传图片时会生成 0.3 倍率的压缩图片,以提供加载优化。
- 图片版权信息展示和维护功能,支持外链跳转。
- 后台有图片数据统计、图片上传、图片维护、相册管理、系统设置和存储配置功能。
- 双因素认证功能,基于 TOTP 算法 [RFC 6238](https://www.rfc-editor.org/rfc/rfc6238),支持 Google Authenticator、Microsoft Authenticator 和 1Password 等。
- 基于 SSR 的混合渲染,采用状态机制,提供良好的使用体验。
- 基于 prisma 的自动初始化数据库和数据迁移,简化部署流程。
- 支持 Vercel 部署、Node.js 部署、Docker 等容器化部署,当然 k8s 也支持。
Expand Down
57 changes: 36 additions & 21 deletions app/admin/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ import { ExternalLink, Github } from 'lucide-react'
import Link from 'next/link'

export default function About() {
const contributors = [
{
name: 'Bess Croft',
url: 'https://github.com/besscroft',
avatar: 'https://avatars.githubusercontent.com/u/33775809?v=4'
},
{
name: 'Nadeshiko Manju',
url: 'https://github.com/Zheaoli',
avatar: 'https://avatars.githubusercontent.com/u/7054676?v=4'
},
{
name: '仙姑本咕',
url: 'https://github.com/hexgu',
avatar: 'https://avatars.githubusercontent.com/u/85490069?v=4'
},
]
return (
<div className="flex flex-col space-y-2 h-full flex-1 w-full mx-auto items-center p-2">
<Image
Expand All @@ -16,12 +33,12 @@ export default function About() {
width={64}
height={64}
/>
<Chip color="success" variant="bordered">v0.11.1</Chip>
<Chip color="success" variant="bordered">v1.0.0</Chip>
<span>PicImpact 是一个摄影师专用的摄影作品展示网站,基于 Next.js 开发。</span>
<Divider className="my-4" />
<div className="flex flex-col w-full">
<Link
className="flex items-center w-full p-2 hover:bg-slate-100"
className="flex items-center w-full p-2 hover:bg-slate-100 dark:hover:text-black"
href="https://github.com/besscroft/PicImpact"
target="_blank"
>
Expand All @@ -33,30 +50,28 @@ export default function About() {
<Divider className="my-4" />
<div className="flex flex-col w-full">
<span>Contributors</span>
<Link
className="flex items-center w-full p-2 hover:bg-slate-100"
href="https://github.com/besscroft"
target="_blank"
>
<Avatar src="https://avatars.githubusercontent.com/u/33775809?v=4" />
<span className="flex-1 px-2">Bess Croft</span>
<ExternalLink />
</Link>
<Link
className="flex items-center w-full p-2 hover:bg-slate-100"
href="https://github.com/Zheaoli"
target="_blank"
>
<Avatar src="https://avatars.githubusercontent.com/u/7054676?v=4" />
<span className="flex-1 px-2">Nadeshiko Manju</span>
<ExternalLink />
</Link>
{
contributors.map((item: any) => {
return (
<Link
key={item.name}
className="flex items-center w-full p-2 hover:bg-slate-100 dark:hover:text-black"
href={item.url}
target="_blank"
>
<Avatar src={item.avatar} />
<span className="flex-1 px-2">{item.name}</span>
<ExternalLink />
</Link>
)
})
}
</div>
<Divider className="my-4" />
<div className="flex flex-col w-full">
<span>支持项目</span>
<Link
className="flex items-center w-full p-2 hover:bg-slate-100"
className="flex items-center w-full p-2 hover:bg-slate-100 dark:hover:text-black"
href="https://afdian.com/a/besscroft"
target="_blank"
>
Expand Down
2 changes: 2 additions & 0 deletions app/admin/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import DashHeader from '~/components/layout/DashHeader'
import { BaseSide } from '~/components/layout/BaseSide'

import { AntdRegistry } from '@ant-design/nextjs-registry'
import Command from '~/components/admin/Command'

export default function AdminLayout({
children,
Expand All @@ -17,6 +18,7 @@ export default function AdminLayout({
<BaseSide/>
</aside>
<main className="flex w-full h-full flex-1 flex-col p-2">
<Command />
<AntdRegistry>{children}</AntdRegistry>
</main>
</div>
Expand Down
29 changes: 5 additions & 24 deletions app/admin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Button, Card, CardBody } from '@nextui-org/react'
import Link from 'next/link'
import { Star, MessageSquareHeart } from 'lucide-react'
import { fetchImagesAnalysis } from '~/server/lib/query'
import TagTable from '~/components/admin/dashboard/TagTable'
import CardList from '~/components/admin/dashboard/CardList'
import { DataProps } from '~/types'

export default async function Admin() {
const getData = async (): Promise<{
total: number
showTotal: number
crTotal: number
tagsTotal: number
result: any[]
}> => {
'use server'
Expand All @@ -23,26 +22,8 @@ export default async function Admin() {
}

return (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4 sm:gap-6 md:gap-8 mt-4">
<TagTable {...props} />
<Card isBlurred shadow="sm" className="h-48">
<CardBody className="flex flex-col space-y-2">
<span className="flex items-center">
<span className="pr-6">如果您觉得项目不错</span>
<span className="h-px flex-1 bg-black"></span>
</span>
<Link href="https://github.com/besscroft/PicImpact" target="_blank">
<Button startContent={<Star size={20} />} variant="bordered" size="sm">Star</Button>
</Link>
<span className="flex items-center">
<span className="pr-6">如果您有 Bug 反馈和建议</span>
<span className="h-px flex-1 bg-black"></span>
</span>
<Link href="https://github.com/besscroft/PicImpact/issues/new" target="_blank">
<Button startContent={<MessageSquareHeart size={20} />} variant="bordered" size="sm">反馈 | 建议</Button>
</Link>
</CardBody>
</Card>
<div className="flex flex-col mt-4 space-y-2">
<CardList {...props} />
</div>
)
}
5 changes: 1 addition & 4 deletions app/providers/toaster-providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ export function ToasterProviders() {
<Toaster
richColors
closeButton
position="top-right"
position="bottom-right"
theme={ theme === 'light' ? 'light' : 'dark' }
toastOptions={{
className: 'z-[9999]',
}}
/>
)
}
8 changes: 4 additions & 4 deletions components/MasonryItem.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use client'

import {
Dialog,
CustomDialog,
DialogContent,
} from '~/components/ui/Dialog'
} from '~/components/ui/CustomDialog'
import { useButtonStore } from '~/app/providers/button-store-Providers'
import { CopyrightType, DataProps, ImageType } from '~/types'
import { Image, Tabs, Tab, Card, CardHeader, CardBody, CardFooter, Button, Chip, Link, Avatar, Tooltip } from '@nextui-org/react'
Expand Down Expand Up @@ -72,7 +72,7 @@ export default function MasonryItem() {
}

return (
<Dialog
<CustomDialog
defaultOpen={false}
open={MasonryView}
onOpenChange={(open: boolean) => {
Expand Down Expand Up @@ -365,6 +365,6 @@ export default function MasonryItem() {
</div>
</div>
</DialogContent>
</Dialog>
</CustomDialog>
)
}
106 changes: 106 additions & 0 deletions components/admin/Command.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
'use client'

import * as React from 'react'
import {
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
} from '~/components/ui/command'
import { useButtonStore } from '~/app/providers/button-store-Providers'
import { Archive, Milestone, Image, Server, ImageUp, MonitorDot, Copyright, Info, SquareAsterisk, ShieldCheck } from 'lucide-react'
import { useRouter } from 'next-nprogress-bar'

export default function Command() {
const router = useRouter()
const { searchOpen, setSearchOpen } = useButtonStore(
(state) => state,
)

return (
<CommandDialog open={searchOpen} onOpenChange={setSearchOpen}>
<CommandInput placeholder="Type a command or search..." />
<CommandList>
<CommandEmpty>没有任何结果.</CommandEmpty>
<CommandGroup heading="主菜单">
<CommandItem className="cursor-pointer" onSelect={() => {
router.push('/admin')
setSearchOpen(false)
}}>
<MonitorDot className="mr-2 h-4 w-4" />
<span>控制台</span>
</CommandItem>
<CommandItem className="cursor-pointer" onSelect={() => {
router.push('/admin/upload')
setSearchOpen(false)
}}>
<ImageUp className="mr-2 h-4 w-4" />
<span>上传</span>
</CommandItem>
<CommandItem className="cursor-pointer" onSelect={() => {
router.push('/admin/list')
setSearchOpen(false)
}}>
<Image className="mr-2 h-4 w-4" />
<span>图片维护</span>
</CommandItem>
<CommandItem className="cursor-pointer" onSelect={() => {
router.push('/admin/tag')
setSearchOpen(false)
}}>
<Milestone className="mr-2 h-4 w-4" />
<span>相册管理</span>
</CommandItem>
<CommandItem className="cursor-pointer" onSelect={() => {
router.push('/admin/copyright')
setSearchOpen(false)
}}>
<Copyright className="mr-2 h-4 w-4" />
<span>版权管理</span>
</CommandItem>
<CommandItem className="cursor-pointer" onSelect={() => {
router.push('/admin/about')
setSearchOpen(false)
}}>
<Info className="mr-2 h-4 w-4" />
<span>关于</span>
</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="二级菜单">
<CommandItem className="cursor-pointer" onSelect={() => {
router.push('/admin/settings/preferences')
setSearchOpen(false)
}}>
<Archive className="mr-2 h-4 w-4" />
<span>首选项</span>
</CommandItem>
<CommandItem className="cursor-pointer" onSelect={() => {
router.push('/admin/settings/password')
setSearchOpen(false)
}}>
<SquareAsterisk className="mr-2 h-4 w-4" />
<span>密码修改</span>
</CommandItem>
<CommandItem className="cursor-pointer" onSelect={() => {
router.push('/admin/settings/storages')
setSearchOpen(false)
}}>
<Server className="mr-2 h-4 w-4" />
<span>存储</span>
</CommandItem>
<CommandItem className="cursor-pointer" onSelect={() => {
router.push('/admin/settings/authenticator')
setSearchOpen(false)
}}>
<ShieldCheck className="mr-2 h-4 w-4" />
<span>双因素验证</span>
</CommandItem>
</CommandGroup>
</CommandList>
</CommandDialog>
)
}
26 changes: 26 additions & 0 deletions components/admin/SearchBorder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use client'

import { Button } from '~/components/ui/button'
import { cn } from '~/utils'
import { MagnifyingGlassIcon } from '@radix-ui/react-icons'
import { useButtonStore } from '~/app/providers/button-store-Providers'

export default function SearchBorder() {
const { setSearchOpen } = useButtonStore(
(state) => state,
)

return (
<Button
variant={"outline"}
className={cn(
"w-[240px] justify-start text-left font-normal",
"text-muted-foreground"
)}
onClick={() => setSearchOpen(true)}
>
<MagnifyingGlassIcon className="mr-2 h-4 w-4" />
<span>搜索</span>
</Button>
)
}
20 changes: 20 additions & 0 deletions components/admin/SearchButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use client'

import { Search } from 'lucide-react'
import { useButtonStore } from '~/app/providers/button-store-Providers'
import { usePathname } from 'next/navigation'

export default function SearchButton() {
const pathname = usePathname()
const { setSearchOpen } = useButtonStore(
(state) => state,
)

return (
<>
{
pathname.startsWith('/admin') && <Search onClick={() => setSearchOpen(true)} size={20} />
}
</>
)
}
Loading

0 comments on commit c6a9233

Please sign in to comment.