From 7716201821feb3481f5f6109dd3d629b122cf7dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EA=B6=8C=EC=A7=84?= Date: Wed, 21 May 2025 09:23:20 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EC=8A=A4=ED=94=84=EB=A6=B0=ED=8A=B8=20?= =?UTF-8?q?=EB=AF=B8=EC=85=989=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ArticleCard.tsx | 60 ++ components/ArticleCardList.tsx | 90 ++ components/ArticleDropdown.tsx | 98 +++ components/ArticleSearch.tsx | 37 + components/BestArticleCard.tsx | 71 ++ components/BestArticleCardList.tsx | 25 + components/common/Header.tsx | 43 + package-lock.json | 1212 ++++++++++++++++++++++++++- package.json | 11 +- pages/_app.tsx | 16 +- pages/api/fetchArticles.ts | 44 + pages/api/hello.ts | 13 - pages/hooks/useFetchArticles.tsx | 45 + pages/hooks/useFetchBestArticle.tsx | 43 + pages/hooks/useInfiniteArticles.tsx | 71 ++ pages/index.tsx | 119 +-- postcss.config.js | 6 + public/favicon.ico | Bin 25931 -> 0 bytes public/icons/ic_arrow_down.png | Bin 0 -> 610 bytes public/icons/ic_heart.png | Bin 0 -> 1235 bytes public/icons/ic_search.png | Bin 0 -> 1319 bytes public/icons/ic_sort.png | Bin 0 -> 881 bytes public/images/best-bedge.png | Bin 0 -> 3669 bytes public/images/panda-face-logo.png | Bin 0 -> 4116 bytes public/images/panda-face.png | Bin 0 -> 3412 bytes public/images/panda-logo.png | Bin 0 -> 7194 bytes public/next.svg | 1 - public/vercel.svg | 1 - styles/Home.module.css | 229 ----- styles/globals.css | 110 +-- tailwind.config.js | 11 + 31 files changed, 1854 insertions(+), 502 deletions(-) create mode 100644 components/ArticleCard.tsx create mode 100644 components/ArticleCardList.tsx create mode 100644 components/ArticleDropdown.tsx create mode 100644 components/ArticleSearch.tsx create mode 100644 components/BestArticleCard.tsx create mode 100644 components/BestArticleCardList.tsx create mode 100644 components/common/Header.tsx create mode 100644 pages/api/fetchArticles.ts delete mode 100644 pages/api/hello.ts create mode 100644 pages/hooks/useFetchArticles.tsx create mode 100644 pages/hooks/useFetchBestArticle.tsx create mode 100644 pages/hooks/useInfiniteArticles.tsx create mode 100644 postcss.config.js delete mode 100644 public/favicon.ico create mode 100644 public/icons/ic_arrow_down.png create mode 100644 public/icons/ic_heart.png create mode 100644 public/icons/ic_search.png create mode 100644 public/icons/ic_sort.png create mode 100644 public/images/best-bedge.png create mode 100644 public/images/panda-face-logo.png create mode 100644 public/images/panda-face.png create mode 100644 public/images/panda-logo.png delete mode 100644 public/next.svg delete mode 100644 public/vercel.svg delete mode 100644 styles/Home.module.css create mode 100644 tailwind.config.js diff --git a/components/ArticleCard.tsx b/components/ArticleCard.tsx new file mode 100644 index 00000000..b7a0a8fd --- /dev/null +++ b/components/ArticleCard.tsx @@ -0,0 +1,60 @@ +import Image from "next/image"; + +import heartIcon from "@/public/icons/ic_heart.png"; + +const ArticleCard = ({ article }: { article: Article }) => { + return ( +
+
+
{article.title}
+
+ {/* eslint-disable-next-line @next/next/no-img-element */} + {article.title} +
+
+
+
+
+ {article.writer.nickname} +
+
+ {new Date(article.createdAt).toLocaleDateString("ko-KR")} +
+
+
+
+ heartIcon +
+
+ {article.likeCount} +
+
+
+
+ ); +}; + +export default ArticleCard; + +type Article = { + id: number; + title: string; + content: string; + image: string; + likeCount: number; + createdAt: string; + updatedAt: string; + writer: { + id: number; + nickname: string; + }; +}; + +type ArticleCardProps = { + article: Article; + onClick: () => void; +}; diff --git a/components/ArticleCardList.tsx b/components/ArticleCardList.tsx new file mode 100644 index 00000000..bb7b0dcd --- /dev/null +++ b/components/ArticleCardList.tsx @@ -0,0 +1,90 @@ +import { useState, useRef, useCallback } from "react"; + +import ArticleSearch from "./ArticleSearch"; +import ArticleDropdown from "./ArticleDropdown"; +import ArticleCard from "./ArticleCard"; + +import useInfiniteArticles from "@/pages/hooks/useInfiniteArticles"; + +const ArticleCardList = () => { + const [sortOption, setSortOption] = useState<"recent" | "like">("recent"); + const [searchKeyword, setSearchKeyword] = useState(""); + + const observer = useRef(null); + + const { articles, setPage, hasMore } = useInfiniteArticles({ + sortOption: sortOption, + keyword: searchKeyword, + pageSize: 10, + }); + + const lastArticleRef = useCallback( + (node: HTMLDivElement | null) => { + if (!hasMore) return; + if (observer.current) observer.current.disconnect(); + + observer.current = new IntersectionObserver((entries) => { + if (entries[0].isIntersecting) { + setPage((prev) => prev + 1); + } + }); + + if (node) observer.current.observe(node); + }, + [hasMore] + ); + + const handleSortChange = (option: "recent" | "like") => { + setSortOption(option); + }; + + return ( +
+
+
+ 게시글 +
+
+ 글쓰기 +
+
+
+ setSearchKeyword(keyword)} /> + +
+
+ {articles.map((article, index) => { + const isLast = index === articles.length - 1; + return ( +
+ +
+ ); + })} +
+
+ ); +}; + +export default ArticleCardList; + +type Article = { + id: number; + title: string; + content: string; + image: string; + likeCount: number; + createdAt: string; + updatedAt: string; + writer: { + id: number; + nickname: string; + }; +}; + +type Articles = { + list: Article[]; +}; diff --git a/components/ArticleDropdown.tsx b/components/ArticleDropdown.tsx new file mode 100644 index 00000000..b02db734 --- /dev/null +++ b/components/ArticleDropdown.tsx @@ -0,0 +1,98 @@ +import Image from "next/image"; +import { useState } from "react"; + +import sortIcon from "@/public/icons/ic_sort.png"; +import arrowDownIcon from "@/public/icons/ic_arrow_down.png"; + +const ArticleDropdown = ({ + sortOption, + handleSortChange, +}: ArticleDropdownProps) => { + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + + return ( +
+ {/* 모바일 버전 드롭다운 */} + <> + + {isDropdownOpen && ( +
+
{ + handleSortChange("recent"); + setIsDropdownOpen(false); + }} + > + 최신순 +
+
{ + handleSortChange("like"); + setIsDropdownOpen(false); + }} + > + 좋아요순 +
+
+ )} + + + {/* 태블릿 이상 버전 드롭다운 */} + <> + + {isDropdownOpen && ( +
+
{ + handleSortChange("recent"); + setIsDropdownOpen(false); + }} + > + 최신순 +
+
{ + handleSortChange("like"); + setIsDropdownOpen(false); + }} + > + 좋아요순 +
+
+ )} + +
+ ); +}; + +export default ArticleDropdown; + +type ArticleDropdownProps = { + sortOption: "recent" | "like"; + handleSortChange: (option: "recent" | "like") => void; +}; diff --git a/components/ArticleSearch.tsx b/components/ArticleSearch.tsx new file mode 100644 index 00000000..d15b0a1d --- /dev/null +++ b/components/ArticleSearch.tsx @@ -0,0 +1,37 @@ +import Image from "next/image"; +import React, { useState } from "react"; + +import searchIcon from "@/public/icons/ic_search.png"; + +const ArticleSearch = ({ + onSearch, +}: { + onSearch: (keyword: string) => void; +}) => { + const [inputValue, setInputValue] = useState(""); + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + onSearch(inputValue); + } + }; + return ( +
+
+ setInputValue(e.target.value)} + onKeyDown={handleKeyDown} + className="w-[288px] md:w-[560px] lg:w-[1054px] h-[42px] rounded-[12px] pt-[9px] pl-[55px] pr-[20px] pb-[9px] bg-[#F3F4F6]" + /> +
+
+ searchIcon +
+
+ ); +}; + +export default ArticleSearch; diff --git a/components/BestArticleCard.tsx b/components/BestArticleCard.tsx new file mode 100644 index 00000000..cf5d3e0a --- /dev/null +++ b/components/BestArticleCard.tsx @@ -0,0 +1,71 @@ +import Image from "next/image"; + +import bestBedge from "@/public/images/best-bedge.png"; +import heartIcon from "@/public/icons/ic_heart.png"; + +const BestArticleCard = ({ article, onClick }: ArticleCardProps) => { + return ( +
+
+ bestBedge +
+
+
+
+ {article.title} +
+
+ {/* eslint-disable-next-line @next/next/no-img-element */} + {article.title} +
+
+
+
+
+ {article.writer.nickname} +
+
+
+ heartIcon +
+
+ {article.likeCount} +
+
+
+
+ {new Date(article.createdAt).toLocaleDateString("ko-KR")} +
+
+
+
+ ); +}; + +export default BestArticleCard; + +type Article = { + id: number; + title: string; + content: string; + image: string; + likeCount: number; + createdAt: string; + updatedAt: string; + writer: { + id: number; + nickname: string; + }; +}; + +type ArticleCardProps = { + article: Article; + onClick: () => void; +}; diff --git a/components/BestArticleCardList.tsx b/components/BestArticleCardList.tsx new file mode 100644 index 00000000..be900339 --- /dev/null +++ b/components/BestArticleCardList.tsx @@ -0,0 +1,25 @@ +import useFetchBestArticle from "@/pages/hooks/useFetchBestArticle"; +import BestArticleCard from "@/components/BestArticleCard"; + +const BestArticleCardList = () => { + const { bestArticle } = useFetchBestArticle(); + + return ( +
+
+ 베스트 게시글 +
+
+ {bestArticle?.list.map((article) => ( + console.log("상세페이지 들어감")} + /> + ))} +
+
+ ); +}; + +export default BestArticleCardList; diff --git a/components/common/Header.tsx b/components/common/Header.tsx new file mode 100644 index 00000000..a9c0e2ae --- /dev/null +++ b/components/common/Header.tsx @@ -0,0 +1,43 @@ +import pandaFace from "@/public/images/panda-face.png"; +import pandaFaceLogo from "@/public/images/panda-face-logo.png"; +import Link from "next/link"; +import Image from "next/image"; + +const Nav = () => { + return ( + + ); +}; + +export default Nav; diff --git a/package-lock.json b/package-lock.json index baa2b665..d686369c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,8 +16,11 @@ "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", + "autoprefixer": "^10.4.21", "eslint": "^8", "eslint-config-next": "13.5.6", + "postcss": "^8.5.3", + "tailwindcss": "^3.4.17", "typescript": "^5" } }, @@ -30,6 +33,19 @@ "node": ">=0.10.0" } }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@babel/runtime": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.4.tgz", @@ -131,6 +147,106 @@ "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@next/env": { "version": "13.5.6", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.6.tgz", @@ -315,6 +431,17 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.0.tgz", @@ -545,6 +672,34 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -705,6 +860,44 @@ "has-symbols": "^1.0.3" } }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -741,6 +934,19 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -752,17 +958,51 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, + "node_modules/browserslist": { + "version": "4.24.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz", + "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001716", + "electron-to-chromium": "^1.5.149", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -797,10 +1037,20 @@ "node": ">=6" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/caniuse-lite": { - "version": "1.0.30001564", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001564.tgz", - "integrity": "sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg==", + "version": "1.0.30001718", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", + "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", "funding": [ { "type": "opencollective", @@ -814,7 +1064,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", @@ -832,6 +1083,44 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -855,6 +1144,16 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -862,10 +1161,11 @@ "dev": true }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -875,6 +1175,19 @@ "node": ">= 8" } }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", @@ -950,6 +1263,13 @@ "node": ">=6" } }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -962,6 +1282,13 @@ "node": ">=8" } }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -974,6 +1301,20 @@ "node": ">=6.0.0" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.152", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.152.tgz", + "integrity": "sha512-xBOfg/EBaIlVsHipHl2VdTPJRSvErNUaqW8ejTq5OlOlIYx1wOllCHsAvAIrr55jD1IYEfdR86miUEt8H5IeJg==", + "dev": true, + "license": "ISC" + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -1108,6 +1449,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1598,10 +1949,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1654,12 +2006,58 @@ "is-callable": "^1.1.3" } }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -2035,6 +2433,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -2111,6 +2522,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -2164,6 +2585,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -2333,6 +2755,32 @@ "set-function-name": "^2.0.1" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2435,6 +2883,26 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -2489,12 +2957,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -2522,22 +2991,45 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -2596,7 +3088,62 @@ } } }, - "node_modules/object-assign": { + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", @@ -2605,6 +3152,16 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -2770,6 +3327,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2815,6 +3379,30 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -2825,9 +3413,10 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -2841,10 +3430,31 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, "funding": [ { "type": "opencollective", @@ -2859,15 +3469,101 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -2946,6 +3642,29 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", @@ -3191,6 +3910,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -3201,9 +3933,10 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -3216,6 +3949,76 @@ "node": ">=10.0.0" } }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", @@ -3293,6 +4096,20 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -3336,6 +4153,76 @@ } } }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3360,6 +4247,80 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -3375,11 +4336,35 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -3399,6 +4384,13 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -3539,6 +4531,37 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3548,6 +4571,13 @@ "punycode": "^2.1.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -3651,6 +4681,107 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -3663,6 +4794,19 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/yaml": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", + "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 1ce24924..a29a543d 100644 --- a/package.json +++ b/package.json @@ -9,16 +9,19 @@ "lint": "next lint" }, "dependencies": { + "next": "13.5.6", "react": "^18", - "react-dom": "^18", - "next": "13.5.6" + "react-dom": "^18" }, "devDependencies": { - "typescript": "^5", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", + "autoprefixer": "^10.4.21", "eslint": "^8", - "eslint-config-next": "13.5.6" + "eslint-config-next": "13.5.6", + "postcss": "^8.5.3", + "tailwindcss": "^3.4.17", + "typescript": "^5" } } diff --git a/pages/_app.tsx b/pages/_app.tsx index 021681f4..f5083d48 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,6 +1,14 @@ -import '@/styles/globals.css' -import type { AppProps } from 'next/app' +import "../styles/globals.css"; +import type { AppProps } from "next/app"; +import Header from "@/components/common/Header"; -export default function App({ Component, pageProps }: AppProps) { - return +function MyApp({ Component, pageProps }: AppProps) { + return ( +
+
+ +
+ ); } + +export default MyApp; diff --git a/pages/api/fetchArticles.ts b/pages/api/fetchArticles.ts new file mode 100644 index 00000000..bbaeae11 --- /dev/null +++ b/pages/api/fetchArticles.ts @@ -0,0 +1,44 @@ +const fetchArticles = async ({ + page = 1, + pageSize = 10, + orderBy, + keyword = "", +}: { + page?: number; + pageSize: number; + orderBy: "recent" | "like"; + keyword?: string; +}) => { + const query = new URLSearchParams({ + page: String(page), + pageSize: String(pageSize), + orderBy, + }); + if (keyword) query.append("keyword", keyword); + + const url = `https://panda-market-api.vercel.app/articles?${query.toString()}`; + const res = await fetch(url); + const data: Articles = await res.json(); + console.log("🛰 요청 URL:", url); + return data; +}; + +export default fetchArticles; + +type Article = { + id: number; + title: string; + content: string; + image: string; + likeCount: number; + createdAt: string; + updatedAt: string; + writer: { + id: number; + nickname: string; + }; +}; + +type Articles = { + list: Article[]; +}; diff --git a/pages/api/hello.ts b/pages/api/hello.ts deleted file mode 100644 index f8bcc7e5..00000000 --- a/pages/api/hello.ts +++ /dev/null @@ -1,13 +0,0 @@ -// Next.js API route support: https://nextjs.org/docs/api-routes/introduction -import type { NextApiRequest, NextApiResponse } from 'next' - -type Data = { - name: string -} - -export default function handler( - req: NextApiRequest, - res: NextApiResponse -) { - res.status(200).json({ name: 'John Doe' }) -} diff --git a/pages/hooks/useFetchArticles.tsx b/pages/hooks/useFetchArticles.tsx new file mode 100644 index 00000000..f998f0ff --- /dev/null +++ b/pages/hooks/useFetchArticles.tsx @@ -0,0 +1,45 @@ +import { useState, useEffect } from "react"; + +import fetchArticles from "../api/fetchArticles"; + +const useFetchArticles = ({ + sortOption = "recent", + pageSize = 10, + keyword, + page = 1, +}: { + sortOption?: "recent" | "like"; + pageSize?: number; + keyword?: string; + page?: number; +}) => { + const [articles, setArticles] = useState(null); + + useEffect(() => { + fetchArticles({ page, pageSize, orderBy: sortOption, keyword }).then( + setArticles + ); + }, [sortOption, pageSize, keyword, page]); + + return { articles }; +}; + +export default useFetchArticles; + +type Article = { + id: number; + title: string; + content: string; + image: string; + likeCount: number; + createdAt: string; + updatedAt: string; + writer: { + id: number; + nickname: string; + }; +}; + +type Articles = { + list: Article[]; +}; diff --git a/pages/hooks/useFetchBestArticle.tsx b/pages/hooks/useFetchBestArticle.tsx new file mode 100644 index 00000000..e233494b --- /dev/null +++ b/pages/hooks/useFetchBestArticle.tsx @@ -0,0 +1,43 @@ +import { useState, useEffect } from "react"; + +import fetchArticles from "../api/fetchArticles"; + +const useFetchBestArticle = () => { + const [bestArticle, setBestArticle] = useState(null); + + useEffect(() => { + const width = window.innerWidth; + const pageSize = width < 768 ? 1 : width < 1024 ? 2 : 3; + fetchArticles({ pageSize, orderBy: "like" }).then(setBestArticle); + }, []); + + /** + * 요구사항이 모바일 태블릿 pc 사용자에 따라서 데이터를 fetch하면 되어서 굳이 화면이 변경될 때마다 fetch를 해서 데이터를 새로 받아오지 않게 하려고 했어요. + * (모바일/태블릿/PC 등 디바이스별 대응은 첫 진입 시점에만 하면 충분하다고 판단.) + * + * 물론 크롬 개발자 도구에서 화면 너비를 바꿀 때마다 리렌더링이 일어나지 않아서 새로고침을 통해서 데이터를 다시 받아와야하지만 + * 성능적으로 이점이 있어서 이렇게 구현했어요. (API 호출 최소화) + */ + + return { bestArticle }; +}; + +export default useFetchBestArticle; + +type Article = { + id: number; + title: string; + content: string; + image: string; + likeCount: number; + createdAt: string; + updatedAt: string; + writer: { + id: number; + nickname: string; + }; +}; + +type Articles = { + list: Article[]; +}; diff --git a/pages/hooks/useInfiniteArticles.tsx b/pages/hooks/useInfiniteArticles.tsx new file mode 100644 index 00000000..96738bd3 --- /dev/null +++ b/pages/hooks/useInfiniteArticles.tsx @@ -0,0 +1,71 @@ +import { useState, useEffect } from "react"; + +import useFetchArticles from "./useFetchArticles"; + +const useInfiniteArticles = ({ + sortOption, + keyword, + pageSize = 10, +}: { + sortOption: "recent" | "like"; + keyword: string; + pageSize?: number; +}) => { + const [page, setPage] = useState(1); + const [hasMore, setHasMore] = useState(true); + const [articles, setArticles] = useState([]); + + const { articles: fetched } = useFetchArticles({ + sortOption, + keyword, + pageSize, + page, + }); + + useEffect(() => { + if (!fetched) return; + + if (fetched.list.length < pageSize) setHasMore(false); + setArticles((prev) => { + const existingIds = new Set(prev.map((a) => a.id)); + const newArticles = fetched.list.filter((a) => !existingIds.has(a.id)); + return [...prev, ...newArticles]; + }); + }, [fetched]); + + useEffect(() => { + setPage(1); + setArticles([]); + setHasMore(true); + }, [sortOption, keyword]); + + useEffect(() => { + console.log("✅ page:", page); + }, [page]); + + useEffect(() => { + console.log("📦 fetched list:", fetched?.list); + }, [fetched]); + + return { articles, setPage, hasMore }; +}; + +export default useInfiniteArticles; + +type Article = { + id: number; + title: string; + content: string; + image: string; + likeCount: number; + createdAt: string; + updatedAt: string; + writer: { + id: number; + nickname: string; + }; +}; + +type Articles = { + list: Article[]; +}; diff --git a/pages/index.tsx b/pages/index.tsx index 02c4dee0..e6fa6ac5 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,114 +1,15 @@ -import Head from 'next/head' -import Image from 'next/image' -import { Inter } from 'next/font/google' -import styles from '@/styles/Home.module.css' - -const inter = Inter({ subsets: ['latin'] }) +import BestArticleCardList from "@/components/BestArticleCardList"; +import ArticleCardList from "@/components/ArticleCardList"; export default function Home() { return ( - <> - - Create Next App - - - - -
-
-

- Get started by editing  - pages/index.tsx -

- -
- -
- Next.js Logo -
- -
- - ) + + + ); } diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 00000000..33ad091d --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 718d6fea4835ec2d246af9800eddb7ffb276240c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25931 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 LrJugUA?W`A8`#=m diff --git a/public/icons/ic_arrow_down.png b/public/icons/ic_arrow_down.png new file mode 100644 index 0000000000000000000000000000000000000000..8a995e9760fa2dfe458f3c280a476e6ee0cd1237 GIT binary patch literal 610 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!oCO|{#S9FJ79h;%I?XTvD9BhG zkG$B+ufw>RwlMI0rLf4twowzfq>^y8)y zfmvGvIz_KX{^GlG$CGOY@zwSVr$gVo?Z}BG38ao!&nt3mp1$ z)AL7d*XnP2#rJJy&W&y8Kn8iX%?@2l#Z}LoG$|_N$u8d|Hm`{#OV{qdj{O(8nT5yJ ze%rpp(s6HaCmH6NeZb6&;wz;zX_CvW=h|N6sx_wRni`C^ruzJ+gR=D*jN z6U(2{bNht;B-yp6y?5-saj3}fRyUVPzJ&Vh-8UlCCT4wpUw8Y~IR-`+-X&6fA|`#G z?k~~5u+c2I-Cw1)w?*d8_6vm}A2_A7PZiyg_02tX%G+gG;jg`~c$GTDGS+PUk#qOJ z9yb-fAD7_IgSK8G4*It@G?fEm+pbwst_U8GjJy%xhlJm%1GSj_(sbHAE34?QG zTf0t7VhL*gyVq}p$I3@5QW`@#JT_(4-FO>1e}cy)hg0g4=JegaHFxcL4~b4O@GW75mamvbftZ@2vIXMIC>Xa9rqN#+ZM7fo)u nXsvqlpta=@MI~e)WyP8wbWqFRVn!P+$UMOTi?!pvpX|8GXMz^BuMa(&>$uX1!mNBn8U}X zINNZ?IfvtH7Oe7nW{1sRe#eYV1J+wDM}|A!Mp<@L8GR|R_LiBrz!q>Ydq}KgGEnl8 zC@_|*-{5?Fgx;)_GSr{;04;oX3r8Avb}TCFOcwGk0owIc9ZpdBi8wMe4L0_-*=g8E zdf1<|Fz(uQ2zgq>Qj8n*JNR0_`SgP1j}+u<_^Z$_NCuwx$x5-b1tHMF$fuA5+}mk; z0xhONDcyi-xy*uN4ks-p3?nFOAG3d-~Y(0Fd4cIyGTr08%=Ujzv;grN%BYv8ViVWq$v$IT)U*I(km3EeHnB->;a zn~?TS;sCSaJDN@j`ov+GRbc?oX|5I>#d8if?r@V7@R<-Ei5TwesHQVAa5xj*47!)Z zzkLdDAztJ2Pk3lhC>BwJa0R5f8vKC=25;XRT{O~ih}PjhhX(SFw;HlSDg|s|cAVU0 zB*6Q~5Z|*oIXwFn;BYQHPk5bX+~ArN740%(;U~a7iB;n!Li#%*bS^GK7_z+I_!P*t zfYODomgq$5ZdN&N;3X!d516L-5;~s(bYr69>7{D%9%KZ89`q4tx^Fx1w1}V$nG5mm7vOO)JhO}@T3c95v8Dv zAhe`((rWOfu~NA>EI2juty6ZIAQLR@?=TiLF9jjEy0EHK(q}X&4qWRQ#3i5{^2Fo~uN>{{&x9n6QQYt}}7;ig~ zEez+hCS1QMMlVvlpg51@uR$hHrR#hY@`Myb#MPzs``MIvrfW{A**yt7!dK6y^JH%4 z5Cf~5r3JKix^o^0!!~Zz>x13!vQtE41qeSbt(v2R?)bzLcN~>4U(A@ftMAsAC~_#q zW0>^rFxB1pPi6KCVjy;F(Z%W}tKbeUh+~+BoMs=xk~d$G<|)D?<@{I!=ldx;`&NLk zR%DEO8UPRwW&=BX*nOY^z8~`K=>sB)5<#uSC}FY}23CL&6lSRr*2q9r+2I=k`Hr07 zAfzkT?JBtMcw!saysE$uFf;`S5n79sW90{Jw}=>OO-yaUCS7>mPC^?_dvciM2}3;r x5#-z`eHMMgz{qo)=D_-mGzk(UNRVJ;_y<|v*FWQl3B>>a002ovPDHLkV1n(1E+7B^ literal 0 HcmV?d00001 diff --git a/public/icons/ic_search.png b/public/icons/ic_search.png new file mode 100644 index 0000000000000000000000000000000000000000..f5c1e861d629a69b2b7477546a2b5a8159b57326 GIT binary patch literal 1319 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 \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index d2f84222..00000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/styles/Home.module.css b/styles/Home.module.css deleted file mode 100644 index 6676d2c6..00000000 --- a/styles/Home.module.css +++ /dev/null @@ -1,229 +0,0 @@ -.main { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - padding: 6rem; - min-height: 100vh; -} - -.description { - display: inherit; - justify-content: inherit; - align-items: inherit; - font-size: 0.85rem; - max-width: var(--max-width); - width: 100%; - z-index: 2; - font-family: var(--font-mono); -} - -.description a { - display: flex; - justify-content: center; - align-items: center; - gap: 0.5rem; -} - -.description p { - position: relative; - margin: 0; - padding: 1rem; - background-color: rgba(var(--callout-rgb), 0.5); - border: 1px solid rgba(var(--callout-border-rgb), 0.3); - border-radius: var(--border-radius); -} - -.code { - font-weight: 700; - font-family: var(--font-mono); -} - -.grid { - display: grid; - grid-template-columns: repeat(4, minmax(25%, auto)); - max-width: 100%; - width: var(--max-width); -} - -.card { - padding: 1rem 1.2rem; - border-radius: var(--border-radius); - background: rgba(var(--card-rgb), 0); - border: 1px solid rgba(var(--card-border-rgb), 0); - transition: background 200ms, border 200ms; -} - -.card span { - display: inline-block; - transition: transform 200ms; -} - -.card h2 { - font-weight: 600; - margin-bottom: 0.7rem; -} - -.card p { - margin: 0; - opacity: 0.6; - font-size: 0.9rem; - line-height: 1.5; - max-width: 30ch; -} - -.center { - display: flex; - justify-content: center; - align-items: center; - position: relative; - padding: 4rem 0; -} - -.center::before { - background: var(--secondary-glow); - border-radius: 50%; - width: 480px; - height: 360px; - margin-left: -400px; -} - -.center::after { - background: var(--primary-glow); - width: 240px; - height: 180px; - z-index: -1; -} - -.center::before, -.center::after { - content: ''; - left: 50%; - position: absolute; - filter: blur(45px); - transform: translateZ(0); -} - -.logo { - position: relative; -} -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - .card:hover { - background: rgba(var(--card-rgb), 0.1); - border: 1px solid rgba(var(--card-border-rgb), 0.15); - } - - .card:hover span { - transform: translateX(4px); - } -} - -@media (prefers-reduced-motion) { - .card:hover span { - transform: none; - } -} - -/* Mobile */ -@media (max-width: 700px) { - .content { - padding: 4rem; - } - - .grid { - grid-template-columns: 1fr; - margin-bottom: 120px; - max-width: 320px; - text-align: center; - } - - .card { - padding: 1rem 2.5rem; - } - - .card h2 { - margin-bottom: 0.5rem; - } - - .center { - padding: 8rem 0 6rem; - } - - .center::before { - transform: none; - height: 300px; - } - - .description { - font-size: 0.8rem; - } - - .description a { - padding: 1rem; - } - - .description p, - .description div { - display: flex; - justify-content: center; - position: fixed; - width: 100%; - } - - .description p { - align-items: center; - inset: 0 0 auto; - padding: 2rem 1rem 1.4rem; - border-radius: 0; - border: none; - border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25); - background: linear-gradient( - to bottom, - rgba(var(--background-start-rgb), 1), - rgba(var(--callout-rgb), 0.5) - ); - background-clip: padding-box; - backdrop-filter: blur(24px); - } - - .description div { - align-items: flex-end; - pointer-events: none; - inset: auto 0 0; - padding: 2rem; - height: 200px; - background: linear-gradient( - to bottom, - transparent 0%, - rgb(var(--background-end-rgb)) 40% - ); - z-index: 1; - } -} - -/* Tablet and Smaller Desktop */ -@media (min-width: 701px) and (max-width: 1120px) { - .grid { - grid-template-columns: repeat(2, 50%); - } -} - -@media (prefers-color-scheme: dark) { - .vercelLogo { - filter: invert(1); - } - - .logo { - filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70); - } -} - -@keyframes rotate { - from { - transform: rotate(360deg); - } - to { - transform: rotate(0deg); - } -} diff --git a/styles/globals.css b/styles/globals.css index d4f491e1..b5c61c95 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -1,107 +1,3 @@ -:root { - --max-width: 1100px; - --border-radius: 12px; - --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', - 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', - 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace; - - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; - - --primary-glow: conic-gradient( - from 180deg at 50% 50%, - #16abff33 0deg, - #0885ff33 55deg, - #54d6ff33 120deg, - #0071ff33 160deg, - transparent 360deg - ); - --secondary-glow: radial-gradient( - rgba(255, 255, 255, 1), - rgba(255, 255, 255, 0) - ); - - --tile-start-rgb: 239, 245, 249; - --tile-end-rgb: 228, 232, 233; - --tile-border: conic-gradient( - #00000080, - #00000040, - #00000030, - #00000020, - #00000010, - #00000010, - #00000080 - ); - - --callout-rgb: 238, 240, 241; - --callout-border-rgb: 172, 175, 176; - --card-rgb: 180, 185, 188; - --card-border-rgb: 131, 134, 135; -} - -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - - --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); - --secondary-glow: linear-gradient( - to bottom right, - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0.3) - ); - - --tile-start-rgb: 2, 13, 46; - --tile-end-rgb: 2, 5, 19; - --tile-border: conic-gradient( - #ffffff80, - #ffffff40, - #ffffff30, - #ffffff20, - #ffffff10, - #ffffff10, - #ffffff80 - ); - - --callout-rgb: 20, 20, 20; - --callout-border-rgb: 108, 108, 108; - --card-rgb: 100, 100, 100; - --card-border-rgb: 200, 200, 200; - } -} - -* { - box-sizing: border-box; - padding: 0; - margin: 0; -} - -html, -body { - max-width: 100vw; - overflow-x: hidden; -} - -body { - color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); -} - -a { - color: inherit; - text-decoration: none; -} - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } -} +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 00000000..48429970 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,11 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + "./pages/**/*.{js,ts,jsx,tsx}", + "./components/**/*.{js,ts,jsx,tsx}", + ], + theme: { + extend: {}, + }, + plugins: [], +}; From 546839442ba527da0a0fba47058bca0f30637e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EA=B6=8C=EC=A7=84?= Date: Wed, 21 May 2025 09:52:32 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EB=B0=B0?= =?UTF-8?q?=EC=97=B4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ArticleCardList.tsx | 2 +- components/BestArticleCard.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/components/ArticleCardList.tsx b/components/ArticleCardList.tsx index bb7b0dcd..277b4005 100644 --- a/components/ArticleCardList.tsx +++ b/components/ArticleCardList.tsx @@ -31,7 +31,7 @@ const ArticleCardList = () => { if (node) observer.current.observe(node); }, - [hasMore] + [hasMore, setPage] ); const handleSortChange = (option: "recent" | "like") => { diff --git a/components/BestArticleCard.tsx b/components/BestArticleCard.tsx index cf5d3e0a..8c4c1f8d 100644 --- a/components/BestArticleCard.tsx +++ b/components/BestArticleCard.tsx @@ -1,4 +1,5 @@ import Image from "next/image"; +import Link from "next/link"; import bestBedge from "@/public/images/best-bedge.png"; import heartIcon from "@/public/icons/ic_heart.png"; From 79f9fa67c301c1a489617e98038444da84bb3712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EA=B6=8C=EC=A7=84?= Date: Wed, 21 May 2025 10:11:23 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EB=B0=B0?= =?UTF-8?q?=EC=97=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/hooks/useInfiniteArticles.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/hooks/useInfiniteArticles.tsx b/pages/hooks/useInfiniteArticles.tsx index 96738bd3..ff18b200 100644 --- a/pages/hooks/useInfiniteArticles.tsx +++ b/pages/hooks/useInfiniteArticles.tsx @@ -31,7 +31,7 @@ const useInfiniteArticles = ({ const newArticles = fetched.list.filter((a) => !existingIds.has(a.id)); return [...prev, ...newArticles]; }); - }, [fetched]); + }, [fetched, pageSize]); useEffect(() => { setPage(1);