主页开发

This commit is contained in:
expdsn 2025-01-16 18:30:24 +08:00
parent 11ccf67486
commit bb3427010c
16 changed files with 220 additions and 58 deletions

0
app/_lib/data/search.ts Normal file
View File

0
app/_lib/data/sider.tsx Normal file
View File

View File

@ -1,7 +1,10 @@
import LogoImg from "@/assets/logo.png"
import Image from "next/image"
import Link from "next/link"
export default function Logo() {
return (
<div className="p-5 bg-white rounded-lg">
<h1 className="text-4xl font-bold text-center text-gray-800">AI工具集</h1>
</div>
<Link href={"/"} className="p-5 rounded-lg block" >
<Image src={LogoImg} alt="logo img"></Image>
</Link>
)
}

33
app/_ui/PosterBox.tsx Normal file
View File

@ -0,0 +1,33 @@
export default function PosterBox({ posterList }: { posterList: string[] }) {
return (
<div className="w-full min-h-[140px] bg-white shadow-md rounded-lg p-2">
<div className="w-full grid grid-cols-5 gap-x-2">
<div className="rounded-lg h-[120px]" style={{
backgroundImage: `url('https://ai-bot.cn/wp-content/uploads/2023/08/daily-ai-news.png')`,
backgroundSize: 'cover'
}}>
</div>
<div className="rounded-lg" style={{
backgroundImage: `url('https://ai-bot.cn/wp-content/uploads/2023/08/daily-ai-news.png')`,
backgroundSize: 'cover'
}}>
</div>
<div className="rounded-lg" style={{
backgroundImage: `url('https://ai-bot.cn/wp-content/uploads/2023/08/daily-ai-news.png')`,
backgroundSize: 'cover'
}}>
</div>
<div className="rounded-lg" style={{
backgroundImage: `url('https://ai-bot.cn/wp-content/uploads/2023/08/daily-ai-news.png')`,
backgroundSize: 'cover'
}}>
</div>
<div className="rounded-lg" style={{
backgroundImage: `url('https://ai-bot.cn/wp-content/uploads/2023/08/daily-ai-news.png')`,
backgroundSize: 'cover'
}}>
</div>
</div>
</div>
)
}

124
app/_ui/Search.tsx Normal file
View File

@ -0,0 +1,124 @@
"use client";
import { faSearch } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import clsx from "clsx";
import { useMemo, useState } from "react";
import Logo from "./Logo";
export type SearchTypeItem = {
name: string;
key: string;
includes: string[];
priority: number;
}
export type SearchWayItemType = {
label: string;
value: string;
fullName: string;
key: string;
}
export const SearchTypeList: SearchTypeItem[] = [
{
name: '常用',
key: 'custom',
includes: ['inside', 'bing'],
priority: 0
},
{
name: '搜索',
key: 'search',
includes: ['101'],
priority: 0
},
{
name: '社区',
key: 'community',
includes: ['101'],
priority: 0
},
{
name: '图片',
key: 'picture',
includes: ['101'],
priority: 0
},
{
name: '生活',
key: 'life',
includes: ['101'],
priority: 0
}
]
export const SearchWayItem: SearchWayItemType[] = [
{
label: '站内',
value: '',
fullName: '站内资源',
key: 'inside',
},
{
label: 'Bing',
fullName: '站内资源',
value: 'https://bing.com',
key: 'bing'
}
]
export default function Search() {
const [selectKey, setSelectKey] = useState(SearchTypeList[0].key)
const nowSelectConfig = useMemo(() => {
const idx = SearchTypeList.findIndex(val => val.key === selectKey)
if (idx !== -1) return SearchTypeList[idx]
else return null
}, [selectKey])
const [activeSearchKey, setActiveSearchKey] = useState(nowSelectConfig?.includes[0])
const activeSearch = useMemo(() => {
const idx = SearchWayItem.findIndex(val => val.key === activeSearchKey)
if (idx !== -1) {
return SearchWayItem[idx]
} else {
return null
}
}, [activeSearchKey])
return (
<div className="w-full flex justify-center flex-col items-center py-10">
<div className="w-[200px]">
<Logo></Logo>
</div>
<div className="w-[800px] flex flex-col gap-y-2">
<div className="flex w-full justify-center gap-x-5 text-[#666666]">
{
SearchTypeList.map(item => (
<div key={item.key}
onClick={() => {
setSelectKey(item.key)
}}
className={clsx(item.key === selectKey ?
"text-[#333]" : "text-[#999] cursor-pointer")}>
{item.name}
</div>
))
}
</div>
<div className="w-full relative">
<input type="text" placeholder={`${activeSearch?.label}搜索`} className="w-full bg-[#C4C2C6] px-4 h-[50px] rounded-3xl outline-none" />
<FontAwesomeIcon className="text-white absolute top-1/2 -translate-y-1/2 right-6 text-xl" icon={faSearch}></FontAwesomeIcon>
</div>
<div className="w-full flex justify-center gap-x-4 ">
{
SearchWayItem.filter(val => nowSelectConfig?.includes.includes(val.key)).map(item => (
<div key={item.key} onClick={() => {
setActiveSearchKey(item.key)
}} className={clsx(activeSearchKey === item.key ?
"text-[#333]" : "text-[#999] cursor-pointer")}>{item.label}</div>
))
}
</div>
</div>
</div>
);
}

View File

@ -4,7 +4,7 @@ import Logo from "./Logo";
export default function SiderNav({ linkList }: { linkList: LinkTypeItem[] }) {
return (
<div className="w-[220px] flex flex-col gap-y-2 fixed left-0 top-0 h-[100vh] shadow-md bg-[#F9F9F9]">
<div className="w-[220px] flex flex-col gap-y-2 fixed left-0 top-0 h-[100vh] bg-[#F9F9F9]">
<div>
<Logo />
</div>

View File

@ -1,18 +0,0 @@
export type SearchConfigItem = {
name: string;
label: string;
type: string;
value: string;
options?: string[];
}
export type SearchConfig = [
{
name: 'searchType';
label: 'Search Type';
type: 'select';
value: 'global';
options: ['global', 'local'];
},
];

View File

@ -1,28 +0,0 @@
"use client";
import { faSearch } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
export default function Search() {
return (
<div className="w-full flex min-h-[100vh] justify-center flex-col items-center py-10">
<div className="text-[30px] font-bold">AI工具集</div>
<div className="w-[800px] flex flex-col gap-y-2">
<div className="flex w-full justify-center gap-x-5 text-[#666666]">
<div className="text-[#333]"></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div className="w-full relative ">
<input type="text" placeholder="站内资源搜索" className="w-full bg-[#C4C2C6] px-4 h-[50px] rounded-3xl outline-none" />
<FontAwesomeIcon className="text-white absolute top-1/2 -translate-y-1/2 right-6 text-xl" icon={faSearch}></FontAwesomeIcon>
</div>
</div>
</div>
);
}

View File

@ -8,7 +8,7 @@ export default function Layout({
children: React.ReactNode;
}>) {
return (
<div >
<div >
<SiderNav linkList={AIAppLinkList}></SiderNav>
{children}
</div>

View File

@ -16,7 +16,7 @@ export default function RootLayout({
return (
<html lang="en">
<body
className={`pl-[220px] antialiased`}
className={`pl-[220px] antialiased bg-[#F9F9F9]`}
>
{children}
</body>

View File

@ -1,16 +1,19 @@
import HeaderNav from "./_ui/HeaderNav";
import SiderNav from "./_ui/SiderNav";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faArrowRotateBack, faDeafness, faImage, faMagnet, faMessage, faPenClip, faSearch, faThumbsUp, faVideo } from '@fortawesome/free-solid-svg-icons'
import '@fortawesome/fontawesome-svg-core/styles.css'
import Search from "./_ui/Search";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faArrowRotateBack, faDeafness, faImage, faMagnet, faMessage, faPenClip, faSearch, faThumbsUp, faVideo } from '@fortawesome/free-solid-svg-icons'
import { LinkTypeItem } from "./_lib/types";
import Search from "./_ui/search";
import PosterBox from "./_ui/PosterBox";
const defaultLinkList = [
{
label: 'AI应用集',
icon: <FontAwesomeIcon icon={faThumbsUp} className="fa-fw text-[20px]" />,
href: '/ai-apps',
id: 1,
},
{
label: 'AI写作工具',
@ -61,14 +64,37 @@ const defaultLinkList = [
id: 9,
}
] as LinkTypeItem[];
export default function Home() {
export default async function Home() {
return (
<div className="flex min-h-full w-full font-[family-name:var(--font-geist-sans)]">
<div className="flex min-h-full w-full font-[family-name:var(--font-geist-sans)] relative">
<SiderNav linkList={defaultLinkList} />
<main className="flex-1 flex flex-col bg-gradient-to-br from-[#E6EEF4] via-[#F1ECF4] to-[#F5ECEA]">
<div className="absolute -z-10 from-[#E6EEF4] h-[50vh] w-full bg-gradient-to-br via-[#F1ECF4] to-[#F5ECEA]">
<div className="absolute z-10 from-[#F9F9F9] left-0 to-transparent bg-gradient-to-t w-full h-[100px] bottom-[0px]">
</div>
</div>
<main className="flex-1 relative flex flex-col p-5 gap-y-4">
<HeaderNav></HeaderNav>
<Search></Search>
<PosterBox posterList={[]} />
<div className="flex w-full flex-col">
{
defaultLinkList.map(item => (
<div className="flex flex-col" key={item.id}>
<div className="flex items-center text-[#555555] ">
{item.icon}
<span>{item.label}</span>
</div>
</div>
))
}
</div>
</main>
</div>
);

BIN
assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

12
dcoker.compose.yml Normal file
View File

@ -0,0 +1,12 @@
version: "3.8"
services:
db:
image: postgres:latest
environment:
POSTGRES_USER: expdsn
POSTGRES_PASSWORD: YlBau_58662
POSTGRES_DB: mydatabase
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"

View File

@ -12,6 +12,7 @@
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.2",
"clsx": "^2.1.1",
"icons": "link:@awesome.me/kit-KIT_CODE/icons",
"next": "15.1.4",
"react": "^19.0.0",

View File

@ -17,6 +17,9 @@ importers:
'@fortawesome/react-fontawesome':
specifier: ^0.2.2
version: 0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.0.0)
clsx:
specifier: ^2.1.1
version: 2.1.1
icons:
specifier: link:@awesome.me/kit-KIT_CODE/icons
version: link:@awesome.me/kit-KIT_CODE/icons
@ -567,6 +570,10 @@ packages:
client-only@0.0.1:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
clsx@2.1.1:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
@ -2203,6 +2210,8 @@ snapshots:
client-only@0.0.1: {}
clsx@2.1.1: {}
color-convert@2.0.1:
dependencies:
color-name: 1.1.4