From e2be9aeb3fefba7e87c8dfc28cf91c19c92c3a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E9=98=B3?= <3311118881@qq.com> Date: Fri, 23 Aug 2024 14:09:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=A7=E6=94=B9=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 7 + package.json | 1 + src/app/page.tsx | 10 ++ .../ArticleLayout/Classics/index.scss | 145 ++++++++++++++++++ .../ArticleLayout/Classics/index.tsx | 95 ++++++++++++ src/components/ArticleLayout/index.tsx | 12 ++ src/components/Container/index.scss | 26 ++++ src/components/Container/index.tsx | 11 ++ src/components/Header/index.tsx | 11 +- src/components/Sidebar/index.tsx | 9 ++ src/styles/index.scss | 12 ++ src/styles/var.scss | 45 +++++- src/utils/index.ts | 27 ++++ src/utils/request.ts | 6 + 14 files changed, 410 insertions(+), 7 deletions(-) create mode 100644 src/components/ArticleLayout/Classics/index.scss create mode 100644 src/components/ArticleLayout/Classics/index.tsx create mode 100644 src/components/ArticleLayout/index.tsx create mode 100644 src/components/Container/index.scss create mode 100644 src/components/Container/index.tsx create mode 100644 src/components/Sidebar/index.tsx create mode 100644 src/utils/index.ts create mode 100644 src/utils/request.ts diff --git a/package-lock.json b/package-lock.json index 7923256..ac49d7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "thrive", "version": "0.1.0", "dependencies": { + "dayjs": "^1.11.13", "next": "14.2.5", "react": "^18", "react-dom": "^18", @@ -556,6 +557,12 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "dev": true }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz", diff --git a/package.json b/package.json index a2cba12..a98ffc7 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "next lint" }, "dependencies": { + "dayjs": "^1.11.13", "next": "14.2.5", "react": "^18", "react-dom": "^18", diff --git a/src/app/page.tsx b/src/app/page.tsx index 348b408..c4ca595 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,6 +1,9 @@ import Swiper from "@/components/Swiper"; import Typed from "@/components/Typed"; import Starry from "@/components/Starry" +import Container from "@/components/Container"; +import ArticleLayout from "@/components/ArticleLayout"; +import Sidebar from "@/components/Sidebar"; export default function Home() { return ( @@ -11,6 +14,13 @@ export default function Home() { {/* 打字机组件 */} + + + {/* 文章列表 */} + + {/* 侧边栏 */} + + ); } \ No newline at end of file diff --git a/src/components/ArticleLayout/Classics/index.scss b/src/components/ArticleLayout/Classics/index.scss new file mode 100644 index 0000000..ae7f69a --- /dev/null +++ b/src/components/ArticleLayout/Classics/index.scss @@ -0,0 +1,145 @@ +@import "@/styles/var.scss"; + +.ClassicsComponent { + .classics { + + // 文章列表 + .item { + position: relative; + overflow: hidden; + display: flex; + height: 230px; + margin-bottom: 15px; + background-color: #333; + @include container; + + // 文章封面 + .cover { + position: relative; + width: 45%; + background: url("") no-repeat center; + background-size: cover; + transition: all $move; + transform: scale(1); + clip-path: polygon(0 0, 100% 0, 90% 100%, 0 100%); + z-index: 1; + + &:hover { + transform: scale(1.2); + transition: all $move; + } + } + + // 文章信息 + .info { + position: relative; + width: 65%; + padding: 20px 40px; + z-index: 2; + + .link { + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100%; + + // 文章标题 + h3 { + position: relative; + width: 100%; + padding-top: 10px; + padding-bottom: 20px; + color: #fff; + font-size: 25px; + + // 防止超长文本 溢出 + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + // 文章简述 + p { + color: #dfdfdf; + font-size: 15px; + line-height: 30px; + text-indent: 2em; + + // 多行文本溢出 + display: -webkit-box !important; + overflow: hidden; + word-break: break-all; + text-overflow: ellipsis; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + } + + .fun { + display: flex; + padding-top: 20px; + text-align: end; + + .fun_item { + display: flex; + align-items: center; + padding-left: 30px; + font-size: 12px; + color: #ffffff; + + span:nth-of-type(1) { + padding-right: 5px; + } + + svg { + padding: 4px; + margin-top: -2px; + margin-right: 3px; + font-size: 23px; + color: #fff; + border-radius: 50%; + vertical-align: middle; + } + + &:nth-child(1) svg { + background-color: #539dfd; + } + + &:nth-child(2) svg { + margin-right: 0; + background-color: #eb373a; + } + + &:nth-child(3) svg { + background-color: #f5a630; + } + } + } + + .start { + justify-content: start; + } + + .end { + justify-content: end; + } + } + } + + // 背景虚化 + .bg { + position: absolute; + width: 100%; + height: 250px; + background-position-x: center; + background-position-y: center; + background-size: cover; + filter: blur(2.5rem) brightness(0.6); + } + } + + // 最后一个文章取消下边距 + & .item:last-of-type { + margin-bottom: 0; + } + } +} \ No newline at end of file diff --git a/src/components/ArticleLayout/Classics/index.tsx b/src/components/ArticleLayout/Classics/index.tsx new file mode 100644 index 0000000..1a07dc8 --- /dev/null +++ b/src/components/ArticleLayout/Classics/index.tsx @@ -0,0 +1,95 @@ +import React, { useEffect, useState } from 'react'; +import dayjs from 'dayjs'; +import Link from 'next/link'; +import { randomImage } from '@/utils'; +// import Empty from '@/components/Empty'; +// import Pagination from '@/components/Pagination'; +import { Article } from '@/types/app/article'; +import "./index.scss" + +import { RiFireLine } from "react-icons/ri"; +import { IoTimeOutline } from "react-icons/io5"; +import { GoTag } from "react-icons/go"; + +interface ClassicsProps { + data: Paginate; +} + +const Classics: React.FC = ({ data }) => { + // const [paginate, setPaginate] = useState({ page: data.page, size: data.size }); + + // useEffect(() => { + // if (data) onGet({ page: paginate.page, size: paginate.size }); + // }, [paginate, data, onGet]); + + if (!data) { + return null; + } + + return ( +
+
+ {data?.result.map((item, index) => ( +
+ {index % 2 === 0 && ( +
+ )} + +
+ +

{item.title}

+

{item.description}

+ +
+
+ + {dayjs(+item.createTime!).format('YYYY-MM-DD')} +
+ +
+ + {item.view} +
+ +
+ + {item.cateList[0]?.name} +
+
+ +
+ +
+ + {index % 2 !== 0 && ( +
+ )} +
+ ))} + + {/* {!data.total && } */} + + {/* {data.total >= 5 && ( + setPaginate(newPaginate)} + /> + )} */} +
+
+ ); +}; + +export default Classics; \ No newline at end of file diff --git a/src/components/ArticleLayout/index.tsx b/src/components/ArticleLayout/index.tsx new file mode 100644 index 0000000..5a3ad1a --- /dev/null +++ b/src/components/ArticleLayout/index.tsx @@ -0,0 +1,12 @@ +import Classics from "./Classics" +import Request from '@/utils/request' + +export default async () => { + const { data } = await Request("/article") + + return ( + <> + + + ) +} \ No newline at end of file diff --git a/src/components/Container/index.scss b/src/components/Container/index.scss new file mode 100644 index 0000000..a480441 --- /dev/null +++ b/src/components/Container/index.scss @@ -0,0 +1,26 @@ +.ContainerComponent { + .main { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + padding: 20px; + margin: 0 auto; + + .left { + margin: 0 auto; + transition: width $move; + } + + .right { + width: 24%; + border-radius: $round; + transition: width $move; + + // 粘性定位 + .sticky { + position: sticky; + top: 70px; + } + } + } +} \ No newline at end of file diff --git a/src/components/Container/index.tsx b/src/components/Container/index.tsx new file mode 100644 index 0000000..5556ef7 --- /dev/null +++ b/src/components/Container/index.tsx @@ -0,0 +1,11 @@ +export default ({ children }: { children: React.ReactNode }) => { + return ( + <> +
+
+ {children} +
+
+ + ) +} \ No newline at end of file diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index 11c6fdf..85ecd02 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -1,24 +1,23 @@ "use client" -import React, { useState, useEffect } from 'react'; import Link from 'next/link'; +import React, { useState, useEffect } from 'react'; +import Request from '@/utils/request'; +import Show from '@/components/Show' import lightLogo from '@/assets/image/light_logo.png'; import darkLogo from '@/assets/image/dark_logo.png'; -import "./index.scss" import { IoIosArrowDown } from 'react-icons/io'; import { Cate } from '@/types/app/cate'; - -import Show from '@/components/Show' +import "./index.scss" const Header = () => { const [isScrolled, setIsScrolled] = useState(false); const [cateList, setCateList] = useState([]) const getCateList = async () => { - const res = await fetch("http://localhost:9999/api/cate/all") - const { data } = await res.json() + const { data } = await Request("/cate/all") console.log(data); setCateList(data) } diff --git a/src/components/Sidebar/index.tsx b/src/components/Sidebar/index.tsx new file mode 100644 index 0000000..86936ac --- /dev/null +++ b/src/components/Sidebar/index.tsx @@ -0,0 +1,9 @@ +export default () => { + return ( + <> +
+

Hello World!

+
+ + ) +} \ No newline at end of file diff --git a/src/styles/index.scss b/src/styles/index.scss index 6a11da3..a91d93d 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -3,6 +3,18 @@ body { background-color: #f9f9f9; } +// 滚动条轨道 +::-webkit-scrollbar-track { + border-radius: 5px; + background-color: #f5f5f5; +} + +// 进度条颜色 +::-webkit-scrollbar-thumb { + background-color: #d4d4d4; +} + +// 文字阴影 .custom_text_shadow { text-shadow: 0 0.1875rem 0.3125rem #1c1f21; } \ No newline at end of file diff --git a/src/styles/var.scss b/src/styles/var.scss index a47f7df..ef4e9bc 100644 --- a/src/styles/var.scss +++ b/src/styles/var.scss @@ -12,4 +12,47 @@ $move: 0.3s; $round: 5px; // 阴影效果 -$boxShadow: 0 2px 8px rgba(186, 186, 186, 0.15); \ No newline at end of file +$boxShadow: 0 2px 8px rgba(186, 186, 186, 0.15); + +// 文字效果 +$fontSty: PingFang SC, "Hiragino Sans GB", "Microsoft JhengHei", "Microsoft YaHei", sans-serif; //文章列表字体 + +// 文本标题 +$textColor: var(--textColor, #333); +// 边框 +$borderColor: var(--borderColor, #eee); +// 下边框 +$underBorderColor: var(--underBorderColor, #eee); +// 阴影 +$shadeColor: var(--shadeColor, 0 2px 8px rgba(186, 186, 186, 0.15)); + +// 封装CSS容器样式 +@mixin container { + border-radius: $round; + border: 1px solid $borderColor; + transition: all $move; + + &:hover { + box-shadow: $shadeColor; + } +} + +// 封装右侧模块标题样式 +@mixin titleRight { + .title { + display: flex; + justify-content: center; + align-items: center; + padding-bottom: 15px; + border-bottom: 1px solid $underBorderColor; + font-size: 17px; + font-weight: 400; + color: $textColor; + transition: all $move; + + img { + width: 30px; + height: 20px; + } + } +} \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..d0efaff --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,27 @@ +// 生成随机数 +export function getRandom(min: number, max: number): number { + return Math.floor(Math.random() * (max - min + 1) + min); +} + +// 随机预览图 +export function randomImage() { + const covers = [ + "https://bu.dusays.com/2023/11/10/654e2da1d80f8.jpg", + "https://bu.dusays.com/2023/11/10/654e2d719d31c.jpg", + "https://bu.dusays.com/2023/11/10/654e2cf92cd45.jpg", + "https://bu.dusays.com/2023/11/10/654e2cf6055b0.jpg", + "https://bu.dusays.com/2023/11/10/654e2db0889fe.jpg", + "https://bu.dusays.com/2023/11/10/654e2d50015a9.jpg", + "https://bu.dusays.com/2023/11/05/65473848ed863.jpg", + "https://bu.dusays.com/2023/11/10/654e2c870e280.jpg", + "https://bu.dusays.com/2023/11/10/654e2c717eb73.jpg", + "https://bu.dusays.com/2023/11/10/654e2c5d75d5b.jpg", + "https://bu.dusays.com/2023/11/10/654e2da27801e.jpg", + "https://bu.dusays.com/2023/11/10/654e2d2a67517.jpg", + "https://bu.dusays.com/2023/11/10/654e2cf47f17a.jpg", + "https://bu.dusays.com/2023/11/05/65473848ed863.jpg" + ]; + + + return covers[getRandom(0, covers.length - 1)]; +} diff --git a/src/utils/request.ts b/src/utils/request.ts new file mode 100644 index 0000000..207897f --- /dev/null +++ b/src/utils/request.ts @@ -0,0 +1,6 @@ +const url = "http://localhost:9999/api" + +export default async (api: string) => { + const res = await fetch(`${url}${api}`) + return res.json() +} \ No newline at end of file