├── dist └── a.txt ├── .eslintrc.json ├── public ├── ai.webp ├── next.ico ├── wechat-yasuo.png ├── kofi_button_red.png ├── vercel.svg ├── next.svg ├── redbook.svg └── ai.svg ├── src ├── app │ ├── favicon.ico │ ├── table │ │ └── page.tsx │ ├── layout.tsx │ ├── globals.css │ ├── page.tsx │ └── antd │ │ └── page.tsx ├── types │ └── lc.ts ├── lib │ └── utils.ts ├── components │ ├── time-line.tsx │ ├── ui │ │ ├── separator.tsx │ │ ├── input.tsx │ │ ├── badge.tsx │ │ ├── popover.tsx │ │ ├── button.tsx │ │ ├── table.tsx │ │ ├── dialog.tsx │ │ ├── command.tsx │ │ ├── select.tsx │ │ └── dropdown-menu.tsx │ ├── Modal.tsx │ ├── lc │ │ ├── data.tsx │ │ ├── data-table-view-options.tsx │ │ ├── data-table-toolbar.tsx │ │ ├── data-table-column-header.tsx │ │ ├── colums.tsx │ │ ├── data-table-pagination.tsx │ │ ├── data-table.tsx │ │ └── data-table-facet-filter.tsx │ ├── SquigglyLines.tsx │ ├── page │ │ └── ref.tsx │ ├── footer.tsx │ └── icons.tsx └── hooks │ └── useLocalStorage.ts ├── next.config.mjs ├── postcss.config.js ├── components.json ├── .gitignore ├── tsconfig.json ├── README.md ├── package.json └── tailwind.config.ts /dist/a.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /public/ai.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonyljx/running-leetcode/HEAD/public/ai.webp -------------------------------------------------------------------------------- /public/next.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonyljx/running-leetcode/HEAD/public/next.ico -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonyljx/running-leetcode/HEAD/src/app/favicon.ico -------------------------------------------------------------------------------- /public/wechat-yasuo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonyljx/running-leetcode/HEAD/public/wechat-yasuo.png -------------------------------------------------------------------------------- /public/kofi_button_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonyljx/running-leetcode/HEAD/public/kofi_button_red.png -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /src/types/lc.ts: -------------------------------------------------------------------------------- 1 | export type Grade = "easy" | "medium" | "hard"; 2 | export interface DataType { 3 | idx: number; 4 | name: string; // 题目 5 | url: string; //url 6 | grade: Grade; // easy medium hard 7 | tags: string[]; // 属于剑指 offer, hot100,牛客 hot100 8 | algoCategory: string; // 算法题类型 9 | ext: string; //补充思路 10 | [key: string]: any; // 添加索引签名 11 | } 12 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "src/app/globals.css", 9 | "baseColor": "slate", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | import { Grade } from "@/types/lc"; 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | 8 | /** 9 | * 辅助函数-获取难度对应的映射 10 | * @param grade 11 | * @returns 12 | */ 13 | export function getGradeValue(grade: Grade): number { 14 | const gradeMap: { [K in Grade]: number } = { 15 | easy: 1, 16 | medium: 2, 17 | hard: 3, 18 | }; 19 | return gradeMap[grade]; 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "allowJs": true, 5 | "skipLibCheck": true, 6 | "strict": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "plugins": [ 16 | { 17 | "name": "next" 18 | } 19 | ], 20 | "paths": { 21 | "@/*": ["./src/*"] 22 | } 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /src/app/table/page.tsx: -------------------------------------------------------------------------------- 1 | import { DataType, Grade } from "@/types/lc"; 2 | import { columns } from "@/components/lc/colums"; 3 | import { DataTable } from "@/components/lc/data-table"; 4 | import data from "../../../public/data.json"; // 根据实际路径调整 5 | async function getData(): Promise { 6 | // Fetch data from your API here. 7 | // 直接将导入的JSON赋值给一个变量,类型为DataType[] 8 | const dataList: DataType[] = data.map((item) => ({ 9 | ...item, 10 | grade: item.grade as Grade, 11 | })); 12 | return dataList; 13 | } 14 | 15 | export default async function DemoPage() { 16 | const data = await getData(); 17 | 18 | return ( 19 |
20 | 21 |
22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /src/components/time-line.tsx: -------------------------------------------------------------------------------- 1 | import { ClockCircleOutlined } from "@ant-design/icons"; 2 | import { Timeline } from "antd"; 3 | import React from "react"; 4 | 5 | type Props = {}; 6 | 7 | export default function MyTimeLine({}: Props) { 8 | const items = [ 9 | { 10 | children: ( 11 |
12 | 2024-02-04

初始版本 收录牛客101

{" "} 13 |
14 | ), 15 | }, 16 | { 17 | children: ( 18 |
19 | 2024-02-06

新增🔥 LeetCode 热题 HOT 100

20 |
21 | ), 22 | color: "green", 23 | }, 24 | { 25 | dot: , 26 | children: ( 27 | <> 28 |

本地存储做题记录

29 |

收录完整的牛客101

30 | 31 | ), 32 | }, 33 | ]; 34 | return ; 35 | } 36 | -------------------------------------------------------------------------------- /src/components/ui/separator.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SeparatorPrimitive from "@radix-ui/react-separator" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Separator = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >( 12 | ( 13 | { className, orientation = "horizontal", decorative = true, ...props }, 14 | ref 15 | ) => ( 16 | 27 | ) 28 | ) 29 | Separator.displayName = SeparatorPrimitive.Root.displayName 30 | 31 | export { Separator } 32 | -------------------------------------------------------------------------------- /src/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface InputProps 6 | extends React.InputHTMLAttributes {} 7 | 8 | const Input = React.forwardRef( 9 | ({ className, type, ...props }, ref) => { 10 | return ( 11 | 20 | ) 21 | } 22 | ) 23 | Input.displayName = "Input" 24 | 25 | export { Input } 26 | -------------------------------------------------------------------------------- /src/components/Modal.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { Button, Modal } from "antd"; 3 | 4 | type TModel = { 5 | buttonText: string; 6 | children?: React.ReactNode; 7 | }; 8 | 9 | const CustomModal: React.FC = ({ children, buttonText }: TModel) => { 10 | const [isModalOpen, setIsModalOpen] = useState(false); 11 | 12 | const showModal = () => { 13 | setIsModalOpen(true); 14 | }; 15 | 16 | const handleOk = () => { 17 | setIsModalOpen(false); 18 | }; 19 | 20 | const handleCancel = () => { 21 | setIsModalOpen(false); 22 | }; 23 | 24 | return ( 25 | <> 26 | 29 | 36 | {children} 37 | 38 | 39 | ); 40 | }; 41 | 42 | export default CustomModal; 43 | -------------------------------------------------------------------------------- /src/components/lc/data.tsx: -------------------------------------------------------------------------------- 1 | export const algoCategories = [ 2 | { label: "链表", value: "链表" }, 3 | { label: "二叉树", value: "二叉树" }, 4 | { label: "数组 ", value: "数组" }, 5 | { label: "字符串", value: "字符串" }, 6 | { label: "回溯", value: "回溯" }, 7 | { label: "栈", value: "栈" }, 8 | { label: "队列", value: "队列" }, 9 | { label: "二分查找", value: "二分查找" }, 10 | { label: "哈希", value: "哈希" }, 11 | { label: "动态规划", value: "动态规划" }, 12 | { label: "贪心", value: "贪心" }, 13 | { label: "滑动窗口", value: "滑动窗口" }, 14 | { label: "堆", value: "堆" }, 15 | { label: "图", value: "图" }, 16 | { label: "位运算", value: "位运算" }, 17 | { label: "双指针", value: "双指针" }, 18 | ]; 19 | 20 | export const grade = [ 21 | { label: "easy", value: "easy" }, 22 | { label: "medium", value: "medium" }, 23 | { label: "hard", value: "hard" }, 24 | ]; 25 | 26 | export const source = [ 27 | { label: "🐂 nowcoder101", value: "nowcoder101" }, 28 | { label: "🔥 LeetCode Hot 100", value: "🔥 LeetCode Hot 100" }, 29 | { label: "🪡 剑指offer", value: "剑指offer" }, 30 | ]; 31 | -------------------------------------------------------------------------------- /src/components/SquigglyLines.tsx: -------------------------------------------------------------------------------- 1 | export default function SquigglyLines() { 2 | return ( 3 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RunningCode 2 | 3 | ![image-20240208120136513](https://image.chatrepo.top/image-20240208120136513.png) 4 | 5 | 做了个算法小工具网站,收录了面试最高频的算法题~ 可以按【题目类型】,【题目出处】,以及【难易程度】去索引,帮助一刷,二刷的同学快速准备算法题~ 6 | 7 | 数据都是基于公开数据人工整理 + GPT 进行打标签。希望可以点个 star⭐,给我一点坚持下去的动力,感激不尽! 8 | 9 | 网址是:[ https://code.gpthanghai.com/ ](https://code.gpthanghai.com/) ,下面这个是网站截图,页面也很清爽,欢迎体验给出意见哈~ 10 | 11 | ## 背景 12 | 13 | 其实源自于逼着有一天想重新分类刷题的时候,发现以下痛点 14 | 15 | - 剑指 offer 在 leetcode 已经没有专门的收录页了,看了下目前版权应该在牛客那里,目前 lc 的题目比较分散,没有做题入口 16 | - leetcode hot100 的页面也没有按**_算法题的类型_**去分类做标签,其实对于 **想分门别类** 单点突破的同学来说不太友好 17 | 18 | ## 网站特点 19 | 20 | - 📚 只收录重要的题目:收录了完整的牛客 101 和 leetcode hot100,以及剑指 offer:这些题目对于面试来说都是非常高频的题目,优先级应该是最高的 21 | - 🤖 分门别类:结合笔者秋招经历,分门别类刷题是一种前期快速找到感觉和培养解题框架的做法,所以一方面也是为了服务我自己,另一方面也想让大家更方便的去根据自己薄弱点去刷题 22 | - 📦 聚合多个来源:目前收录了牛客 101 和 leetcode hot 100 以及 leetcode 上的剑指 offer 题目(因为牛客上的剑指 offer 题需要付费买了书才能刷,所以没有贴) 23 | 24 | ## 后续迭代计划 25 | 26 | - [ ] 登录功能+错题本功能:根据用户的历史操作记录,可以标记用户的错题本,针对错题本进行复习(现在是直接编译成 html 的,后面这个功能要上数据库,可能会收费,看大家的投票) 27 | 28 | # 联系我 29 | 30 | 有任何问题或建议,请联系 15889666941@163.com 31 | 32 | 建议关注官方公众号 PigCode,我会记录相关题解,如果感兴趣的话也可以分享建站过程~ 33 | 34 | wechat-yasuo 35 | -------------------------------------------------------------------------------- /src/components/ui/badge.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cva, type VariantProps } from "class-variance-authority" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | const badgeVariants = cva( 7 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", 8 | { 9 | variants: { 10 | variant: { 11 | default: 12 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", 13 | secondary: 14 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", 15 | destructive: 16 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", 17 | outline: "text-foreground", 18 | }, 19 | }, 20 | defaultVariants: { 21 | variant: "default", 22 | }, 23 | } 24 | ) 25 | 26 | export interface BadgeProps 27 | extends React.HTMLAttributes, 28 | VariantProps {} 29 | 30 | function Badge({ className, variant, ...props }: BadgeProps) { 31 | return ( 32 |
33 | ) 34 | } 35 | 36 | export { Badge, badgeVariants } 37 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leetcode-dashboard", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint", 10 | "pages:build": "npx @cloudflare/next-on-pages" 11 | }, 12 | "dependencies": { 13 | "@ant-design/icons": "^5.3.0", 14 | "@ant-design/nextjs-registry": "^1.0.0", 15 | "@radix-ui/react-dialog": "^1.0.5", 16 | "@radix-ui/react-dropdown-menu": "^2.0.6", 17 | "@radix-ui/react-popover": "^1.0.7", 18 | "@radix-ui/react-select": "^2.0.0", 19 | "@radix-ui/react-separator": "^1.0.3", 20 | "@radix-ui/react-slot": "^1.0.2", 21 | "@tanstack/react-table": "^8.11.8", 22 | "antd": "^5.13.3", 23 | "class-variance-authority": "^0.7.0", 24 | "clsx": "^2.1.0", 25 | "cmdk": "^0.2.1", 26 | "lucide-react": "^0.321.0", 27 | "next": "14.1.0", 28 | "react": "^18", 29 | "react-dom": "^18", 30 | "tailwind-merge": "^2.2.1", 31 | "tailwindcss-animate": "^1.0.7" 32 | }, 33 | "devDependencies": { 34 | "@types/node": "^20", 35 | "@types/react": "^18", 36 | "@types/react-dom": "^18", 37 | "autoprefixer": "^10.0.1", 38 | "eslint": "^8", 39 | "eslint-config-next": "14.1.0", 40 | "postcss": "^8", 41 | "tailwindcss": "^3.3.0", 42 | "typescript": "^5" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/components/ui/popover.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as PopoverPrimitive from "@radix-ui/react-popover" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Popover = PopoverPrimitive.Root 9 | 10 | const PopoverTrigger = PopoverPrimitive.Trigger 11 | 12 | const PopoverContent = React.forwardRef< 13 | React.ElementRef, 14 | React.ComponentPropsWithoutRef 15 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( 16 | 17 | 27 | 28 | )) 29 | PopoverContent.displayName = PopoverPrimitive.Content.displayName 30 | 31 | export { Popover, PopoverTrigger, PopoverContent } 32 | -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { AntdRegistry } from "@ant-design/nextjs-registry"; 3 | // import { Inter } from "next/font/google"; 4 | import "./globals.css"; 5 | import { ConfigProvider } from "antd"; 6 | 7 | // const inter = Inter({ subsets: ["latin"] }); 8 | import { Inter as FontSans } from "next/font/google"; 9 | import { cn } from "@/lib/utils"; 10 | import Script from "next/script"; 11 | const fontSans = FontSans({ 12 | subsets: ["latin"], 13 | variable: "--font-sans", 14 | }); 15 | export const metadata: Metadata = { 16 | title: "RunningCode", 17 | description: "按类型收录牛客101 | leetcode hot 100 | 剑指 offer全部题目", 18 | }; 19 | 20 | export default function RootLayout({ 21 | children, 22 | }: Readonly<{ 23 | children: React.ReactNode; 24 | }>) { 25 | return ( 26 | 27 | 33 | 34 | {/* 定制主题 */} 35 | 42 | {children} 43 | 44 | 45 | 46 | 47 | 52 | 53 | ); 54 | } 55 | -------------------------------------------------------------------------------- /src/components/page/ref.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils"; 2 | import Link from "next/link"; 3 | import React from "react"; 4 | 5 | type Props = { 6 | className?: string; 7 | }; 8 | 9 | export default function Ref({ className }: Props) { 10 | return ( 11 |
12 |

13 | Source 14 |

15 |
16 | 21 | 🔥 LeetCode 热题 HOT 100 22 | 23 | 28 | 🐂 牛客 面试必刷101 29 | 30 | 31 | 36 | ⚔ LeetCode 剑指offer对应题目-参考1 37 | 38 | 39 | 44 | ⚔ LeetCode 剑指offer对应题目-参考2 45 | 46 |
47 |
48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /src/hooks/useLocalStorage.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from "react"; 2 | const isBrowser = typeof window !== "undefined"; 3 | // 定义 useLocalStorage 钩子的泛型版本 4 | export function useLocalStorage( 5 | key: string, 6 | initialValue: T 7 | ): [T, (value: T | ((val: T) => T)) => void, () => void] { 8 | // 从 localStorage 获取初始值 9 | const [storedValue, setStoredValue] = useState(() => { 10 | if (!isBrowser) { 11 | return initialValue; 12 | } 13 | try { 14 | const item = localStorage.getItem(key); 15 | console.log("localStorage ", item); 16 | return item ? JSON.parse(item) : initialValue; 17 | } catch (error) { 18 | console.log(error); 19 | return initialValue; 20 | } 21 | }); 22 | 23 | useEffect(() => { 24 | if (!isBrowser) return; 25 | 26 | try { 27 | const item = localStorage.getItem(key); 28 | if (item) { 29 | setStoredValue(JSON.parse(item)); 30 | } 31 | } catch (error) { 32 | console.log(error); 33 | } 34 | }, [key]); 35 | 36 | // 保存值到 localStorage 和状态变量 37 | const setValue = (value: T | ((val: T) => T)) => { 38 | try { 39 | // 允许值是一个函数,这样我们就可以有相同的 API 作为 useState 40 | const valueToStore = 41 | value instanceof Function ? value(storedValue) : value; 42 | // 保存状态 43 | setStoredValue(valueToStore); 44 | // 保存到 localStorage 45 | localStorage.setItem(key, JSON.stringify(valueToStore)); 46 | } catch (error) { 47 | console.log(error); 48 | } 49 | }; 50 | 51 | const removeAll = () => { 52 | localStorage.removeItem(key); 53 | setStoredValue(initialValue); // 重置到初始值 54 | }; 55 | 56 | return [storedValue, setValue, removeAll]; 57 | } 58 | -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer base { 6 | :root { 7 | --background: 0 0% 100%; 8 | --foreground: 222.2 84% 4.9%; 9 | 10 | --card: 0 0% 100%; 11 | --card-foreground: 222.2 84% 4.9%; 12 | 13 | --popover: 0 0% 100%; 14 | --popover-foreground: 222.2 84% 4.9%; 15 | 16 | --primary: 222.2 47.4% 11.2%; 17 | --primary-foreground: 210 40% 98%; 18 | 19 | --secondary: 210 40% 96.1%; 20 | --secondary-foreground: 222.2 47.4% 11.2%; 21 | 22 | --muted: 210 40% 96.1%; 23 | --muted-foreground: 215.4 16.3% 46.9%; 24 | 25 | --accent: 210 40% 96.1%; 26 | --accent-foreground: 222.2 47.4% 11.2%; 27 | 28 | --destructive: 0 84.2% 60.2%; 29 | --destructive-foreground: 210 40% 98%; 30 | 31 | --border: 214.3 31.8% 91.4%; 32 | --input: 214.3 31.8% 91.4%; 33 | --ring: 222.2 84% 4.9%; 34 | 35 | --radius: 0.5rem; 36 | } 37 | 38 | .dark { 39 | --background: 222.2 84% 4.9%; 40 | --foreground: 210 40% 98%; 41 | 42 | --card: 222.2 84% 4.9%; 43 | --card-foreground: 210 40% 98%; 44 | 45 | --popover: 222.2 84% 4.9%; 46 | --popover-foreground: 210 40% 98%; 47 | 48 | --primary: 210 40% 98%; 49 | --primary-foreground: 222.2 47.4% 11.2%; 50 | 51 | --secondary: 217.2 32.6% 17.5%; 52 | --secondary-foreground: 210 40% 98%; 53 | 54 | --muted: 217.2 32.6% 17.5%; 55 | --muted-foreground: 215 20.2% 65.1%; 56 | 57 | --accent: 217.2 32.6% 17.5%; 58 | --accent-foreground: 210 40% 98%; 59 | 60 | --destructive: 0 62.8% 30.6%; 61 | --destructive-foreground: 210 40% 98%; 62 | 63 | --border: 217.2 32.6% 17.5%; 64 | --input: 217.2 32.6% 17.5%; 65 | --ring: 212.7 26.8% 83.9%; 66 | } 67 | } 68 | 69 | @layer base { 70 | * { 71 | @apply border-border; 72 | } 73 | body { 74 | @apply bg-background text-foreground; 75 | } 76 | } -------------------------------------------------------------------------------- /src/components/lc/data-table-view-options.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu"; 4 | // import { MixerHorizontalIcon } from "@radix-ui/react-icons"; 5 | import { Table } from "@tanstack/react-table"; 6 | 7 | import { Button } from "@/components/ui/button"; 8 | import { 9 | DropdownMenu, 10 | DropdownMenuCheckboxItem, 11 | DropdownMenuContent, 12 | DropdownMenuLabel, 13 | DropdownMenuSeparator, 14 | } from "@/components/ui/dropdown-menu"; 15 | import { AlignVerticalDistributeCenter } from "lucide-react"; 16 | 17 | interface DataTableViewOptionsProps { 18 | table: Table; 19 | } 20 | 21 | export function DataTableViewOptions({ 22 | table, 23 | }: DataTableViewOptionsProps) { 24 | return ( 25 | 26 | 27 | 35 | 36 | 37 | Toggle columns 38 | 39 | {table 40 | .getAllColumns() 41 | .filter( 42 | (column) => 43 | typeof column.accessorFn !== "undefined" && column.getCanHide() 44 | ) 45 | .map((column) => { 46 | return ( 47 | column.toggleVisibility(!!value)} 52 | > 53 | {column.id} 54 | 55 | ); 56 | })} 57 | 58 | 59 | ); 60 | } 61 | -------------------------------------------------------------------------------- /src/components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const buttonVariants = cva( 8 | "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", 9 | { 10 | variants: { 11 | variant: { 12 | default: "bg-primary text-primary-foreground hover:bg-primary/90", 13 | destructive: 14 | "bg-destructive text-destructive-foreground hover:bg-destructive/90", 15 | outline: 16 | "border border-input bg-background hover:bg-accent hover:text-accent-foreground", 17 | secondary: 18 | "bg-secondary text-secondary-foreground hover:bg-secondary/80", 19 | ghost: "hover:bg-accent hover:text-accent-foreground", 20 | link: "text-primary underline-offset-4 hover:underline", 21 | }, 22 | size: { 23 | default: "h-10 px-4 py-2", 24 | sm: "h-9 rounded-md px-3", 25 | lg: "h-11 rounded-md px-8", 26 | icon: "h-10 w-10", 27 | }, 28 | }, 29 | defaultVariants: { 30 | variant: "default", 31 | size: "default", 32 | }, 33 | } 34 | ) 35 | 36 | export interface ButtonProps 37 | extends React.ButtonHTMLAttributes, 38 | VariantProps { 39 | asChild?: boolean 40 | } 41 | 42 | const Button = React.forwardRef( 43 | ({ className, variant, size, asChild = false, ...props }, ref) => { 44 | const Comp = asChild ? Slot : "button" 45 | return ( 46 | 51 | ) 52 | } 53 | ) 54 | Button.displayName = "Button" 55 | 56 | export { Button, buttonVariants } 57 | -------------------------------------------------------------------------------- /src/components/lc/data-table-toolbar.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { Table } from "@tanstack/react-table"; 4 | 5 | import { Input } from "@/components/ui/input"; 6 | 7 | // import { priorities, statuses } from "../data/data"; 8 | import { DataTableFacetedFilter } from "./data-table-facet-filter"; 9 | import { Button } from "../ui/button"; 10 | import { DataTableViewOptions } from "./data-table-view-options"; 11 | import { X } from "lucide-react"; 12 | import { algoCategories, grade, source } from "./data"; 13 | 14 | interface DataTableToolbarProps { 15 | table: Table; 16 | } 17 | 18 | export function DataTableToolbar({ 19 | table, 20 | }: DataTableToolbarProps) { 21 | const isFiltered = table.getState().columnFilters.length > 0; 22 | 23 | // console.log(table.getAllColumns()); 24 | 25 | return ( 26 |
27 |
28 | 32 | table.getColumn("name")?.setFilterValue(event.target.value) 33 | } 34 | className="h-8 w-[150px] lg:w-[250px]" 35 | /> 36 | {table.getColumn("algoCategory") && ( 37 | 42 | )} 43 | {table.getColumn("grade") && ( 44 | 49 | )} 50 | {table.getColumn("grade") && ( 51 | 56 | )} 57 | {isFiltered && ( 58 | 66 | )} 67 |
68 | 69 |
70 | ); 71 | } 72 | -------------------------------------------------------------------------------- /src/components/lc/data-table-column-header.tsx: -------------------------------------------------------------------------------- 1 | import { Column } from "@tanstack/react-table"; 2 | 3 | import { cn } from "@/lib/utils"; 4 | 5 | import { 6 | DropdownMenu, 7 | DropdownMenuContent, 8 | DropdownMenuItem, 9 | DropdownMenuSeparator, 10 | DropdownMenuTrigger, 11 | } from "@/components/ui/dropdown-menu"; 12 | import { Button } from "../ui/button"; 13 | import { 14 | ArrowDownIcon, 15 | ArrowUpIcon, 16 | ChevronsUpDown, 17 | EyeOff, 18 | } from "lucide-react"; 19 | 20 | interface DataTableColumnHeaderProps 21 | extends React.HTMLAttributes { 22 | column: Column; 23 | title: string; 24 | } 25 | 26 | export function DataTableColumnHeader({ 27 | column, 28 | title, 29 | className, 30 | }: DataTableColumnHeaderProps) { 31 | if (!column.getCanSort()) { 32 | return
{title}
; 33 | } 34 | 35 | return ( 36 |
37 | 38 | 39 | 53 | 54 | 55 | column.toggleSorting(false)}> 56 | 57 | Asc 58 | 59 | column.toggleSorting(true)}> 60 | 61 | Desc 62 | 63 | 64 | column.toggleVisibility(false)}> 65 | 66 | Hide 67 | 68 | 69 | 70 |
71 | ); 72 | } 73 | -------------------------------------------------------------------------------- /src/components/lc/colums.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { ColumnDef } from "@tanstack/react-table"; 4 | 5 | // This type is used to define the shape of our data. 6 | // You can use a Zod schema here if you want. 7 | import { DataType } from "@/types/lc"; 8 | import Link from "next/link"; 9 | import { Badge } from "../ui/badge"; 10 | import { Button } from "../ui/button"; 11 | import { DataTableColumnHeader } from "./data-table-column-header"; 12 | import { getGradeValue } from "@/lib/utils"; 13 | 14 | export const columns: ColumnDef[] = [ 15 | { 16 | accessorKey: "idx", 17 | header: "idx", 18 | }, 19 | { 20 | accessorKey: "name", 21 | // header: () => "题目名", 22 | header: ({ column }) => ( 23 | 24 | ), 25 | filterFn: "includesString", 26 | }, 27 | 28 | { 29 | accessorKey: "grade", 30 | header: ({ column }) => ( 31 | 32 | ), 33 | sortingFn: (a, b) => { 34 | return ( 35 | getGradeValue(a.getValue("grade")) - getGradeValue(b.getValue("grade")) 36 | ); 37 | }, 38 | 39 | cell: ({ row }) => { 40 | const grade = row.getValue("grade"); 41 | switch (grade) { 42 | case "easy": 43 | return ( 44 | {grade} 45 | ); 46 | 47 | case "medium": 48 | return ( 49 | {grade} 50 | ); 51 | 52 | case "hard": 53 | return {grade}; 54 | 55 | default: 56 | break; 57 | } 58 | }, 59 | filterFn: "arrIncludesSome", 60 | }, 61 | { 62 | accessorKey: "tags", 63 | header: "出处", 64 | filterFn: "arrIncludesSome", 65 | }, 66 | { 67 | accessorKey: "algoCategory", 68 | header: "分类", 69 | filterFn: (row, id, value) => { 70 | console.log("分类: ", row.getValue(id)); 71 | return value.includes(row.getValue(id)); 72 | }, 73 | }, 74 | { 75 | accessorKey: "url", 76 | header: "Url", 77 | cell: (props) => ( 78 | 83 | {/* {`${props.row.original.grade} - ${props.getValue()}`} */} 84 | Url 85 | 86 | ), 87 | }, 88 | { 89 | accessorKey: "ext", 90 | header: "补充", 91 | }, 92 | ]; 93 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | const { fontFamily } = require("tailwindcss/defaultTheme"); 3 | const config = { 4 | darkMode: ["class"], 5 | content: [ 6 | "./pages/**/*.{ts,tsx}", 7 | "./components/**/*.{ts,tsx}", 8 | "./app/**/*.{ts,tsx}", 9 | "./src/**/*.{ts,tsx}", 10 | ], 11 | prefix: "", 12 | theme: { 13 | container: { 14 | center: true, 15 | padding: "5rem", 16 | screens: { 17 | "2xl": "1200px", 18 | }, 19 | }, 20 | extend: { 21 | fontFamily: { 22 | sans: ["var(--font-sans)", ...fontFamily.sans], 23 | }, 24 | colors: { 25 | border: "hsl(var(--border))", 26 | input: "hsl(var(--input))", 27 | ring: "hsl(var(--ring))", 28 | background: "hsl(var(--background))", 29 | foreground: "hsl(var(--foreground))", 30 | primary: { 31 | DEFAULT: "hsl(var(--primary))", 32 | foreground: "hsl(var(--primary-foreground))", 33 | }, 34 | secondary: { 35 | DEFAULT: "hsl(var(--secondary))", 36 | foreground: "hsl(var(--secondary-foreground))", 37 | }, 38 | destructive: { 39 | DEFAULT: "hsl(var(--destructive))", 40 | foreground: "hsl(var(--destructive-foreground))", 41 | }, 42 | muted: { 43 | DEFAULT: "hsl(var(--muted))", 44 | foreground: "hsl(var(--muted-foreground))", 45 | }, 46 | accent: { 47 | DEFAULT: "hsl(var(--accent))", 48 | foreground: "hsl(var(--accent-foreground))", 49 | }, 50 | popover: { 51 | DEFAULT: "hsl(var(--popover))", 52 | foreground: "hsl(var(--popover-foreground))", 53 | }, 54 | card: { 55 | DEFAULT: "hsl(var(--card))", 56 | foreground: "hsl(var(--card-foreground))", 57 | }, 58 | }, 59 | borderRadius: { 60 | lg: "var(--radius)", 61 | md: "calc(var(--radius) - 2px)", 62 | sm: "calc(var(--radius) - 4px)", 63 | }, 64 | keyframes: { 65 | "accordion-down": { 66 | from: { height: "0" }, 67 | to: { height: "var(--radix-accordion-content-height)" }, 68 | }, 69 | "accordion-up": { 70 | from: { height: "var(--radix-accordion-content-height)" }, 71 | to: { height: "0" }, 72 | }, 73 | }, 74 | animation: { 75 | "accordion-down": "accordion-down 0.2s ease-out", 76 | "accordion-up": "accordion-up 0.2s ease-out", 77 | }, 78 | }, 79 | }, 80 | plugins: [require("tailwindcss-animate")], 81 | } satisfies Config; 82 | 83 | export default config; 84 | -------------------------------------------------------------------------------- /src/components/ui/table.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Table = React.forwardRef< 6 | HTMLTableElement, 7 | React.HTMLAttributes 8 | >(({ className, ...props }, ref) => ( 9 |
10 | 15 | 16 | )) 17 | Table.displayName = "Table" 18 | 19 | const TableHeader = React.forwardRef< 20 | HTMLTableSectionElement, 21 | React.HTMLAttributes 22 | >(({ className, ...props }, ref) => ( 23 | 24 | )) 25 | TableHeader.displayName = "TableHeader" 26 | 27 | const TableBody = React.forwardRef< 28 | HTMLTableSectionElement, 29 | React.HTMLAttributes 30 | >(({ className, ...props }, ref) => ( 31 | 36 | )) 37 | TableBody.displayName = "TableBody" 38 | 39 | const TableFooter = React.forwardRef< 40 | HTMLTableSectionElement, 41 | React.HTMLAttributes 42 | >(({ className, ...props }, ref) => ( 43 | tr]:last:border-b-0", 47 | className 48 | )} 49 | {...props} 50 | /> 51 | )) 52 | TableFooter.displayName = "TableFooter" 53 | 54 | const TableRow = React.forwardRef< 55 | HTMLTableRowElement, 56 | React.HTMLAttributes 57 | >(({ className, ...props }, ref) => ( 58 | 66 | )) 67 | TableRow.displayName = "TableRow" 68 | 69 | const TableHead = React.forwardRef< 70 | HTMLTableCellElement, 71 | React.ThHTMLAttributes 72 | >(({ className, ...props }, ref) => ( 73 |
81 | )) 82 | TableHead.displayName = "TableHead" 83 | 84 | const TableCell = React.forwardRef< 85 | HTMLTableCellElement, 86 | React.TdHTMLAttributes 87 | >(({ className, ...props }, ref) => ( 88 | 93 | )) 94 | TableCell.displayName = "TableCell" 95 | 96 | const TableCaption = React.forwardRef< 97 | HTMLTableCaptionElement, 98 | React.HTMLAttributes 99 | >(({ className, ...props }, ref) => ( 100 |
105 | )) 106 | TableCaption.displayName = "TableCaption" 107 | 108 | export { 109 | Table, 110 | TableHeader, 111 | TableBody, 112 | TableFooter, 113 | TableHead, 114 | TableRow, 115 | TableCell, 116 | TableCaption, 117 | } 118 | -------------------------------------------------------------------------------- /src/components/lc/data-table-pagination.tsx: -------------------------------------------------------------------------------- 1 | import { Table } from "@tanstack/react-table"; 2 | 3 | import { 4 | Select, 5 | SelectContent, 6 | SelectItem, 7 | SelectTrigger, 8 | SelectValue, 9 | } from "@/components/ui/select"; 10 | import { Button } from "@/components/ui/button"; 11 | import { 12 | ChevronLeft, 13 | ChevronRight, 14 | ChevronsLeft, 15 | ChevronsRight, 16 | } from "lucide-react"; 17 | 18 | interface DataTablePaginationProps { 19 | table: Table; 20 | } 21 | 22 | export function DataTablePagination({ 23 | table, 24 | }: DataTablePaginationProps) { 25 | return ( 26 |
27 | {/*
28 | {table.getFilteredSelectedRowModel().rows.length} of{" "} 29 | {table.getFilteredRowModel().rows.length} row(s) selected. 30 |
*/} 31 |
32 |
33 |

Rows per page

34 | 51 |
52 |
53 | Page {table.getState().pagination.pageIndex + 1} of{" "} 54 | {table.getPageCount()} 55 |
56 |
57 | 66 | 75 | 84 | 93 |
94 |
95 |
96 | ); 97 | } 98 | -------------------------------------------------------------------------------- /src/components/lc/data-table.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import * as React from "react"; 3 | import { 4 | ColumnDef, 5 | SortingState, 6 | flexRender, 7 | getCoreRowModel, 8 | useReactTable, 9 | getPaginationRowModel, 10 | getSortedRowModel, 11 | getFacetedRowModel, 12 | getFacetedUniqueValues, 13 | ColumnFiltersState, 14 | getFilteredRowModel, 15 | } from "@tanstack/react-table"; 16 | 17 | import { 18 | Table, 19 | TableBody, 20 | TableCell, 21 | TableHead, 22 | TableHeader, 23 | TableRow, 24 | } from "@/components/ui/table"; 25 | import { DataTablePagination } from "./data-table-pagination"; 26 | import { DataTableToolbar } from "./data-table-toolbar"; 27 | 28 | interface DataTableProps { 29 | columns: ColumnDef[]; 30 | data: TData[]; 31 | } 32 | 33 | export function DataTable({ 34 | columns, 35 | data, 36 | }: DataTableProps) { 37 | const [sorting, setSorting] = React.useState([]); 38 | const [columnFilters, setColumnFilters] = React.useState( 39 | [] 40 | ); 41 | const table = useReactTable({ 42 | data, 43 | columns, 44 | getCoreRowModel: getCoreRowModel(), 45 | getPaginationRowModel: getPaginationRowModel(), 46 | onSortingChange: setSorting, 47 | getSortedRowModel: getSortedRowModel(), 48 | state: { 49 | sorting, 50 | columnFilters, 51 | }, 52 | getFacetedRowModel: getFacetedRowModel(), 53 | getFacetedUniqueValues: getFacetedUniqueValues(), 54 | onColumnFiltersChange: setColumnFilters, 55 | getFilteredRowModel: getFilteredRowModel(), 56 | }); 57 | 58 | // console.log(table.getFilteredRowModel()); 59 | 60 | // const paginationRowModel = table.getPaginationRowModel(); 61 | 62 | return ( 63 |
64 | 65 |
66 | 67 | 68 | {table.getHeaderGroups().map((headerGroup) => ( 69 | 70 | {headerGroup.headers.map((header) => { 71 | return ( 72 | 73 | {header.isPlaceholder 74 | ? null 75 | : flexRender( 76 | header.column.columnDef.header, 77 | header.getContext() 78 | )} 79 | 80 | ); 81 | })} 82 | 83 | ))} 84 | 85 | 86 | {table.getRowModel().rows?.length ? ( 87 | table.getRowModel().rows.map((row) => ( 88 | 92 | {row.getVisibleCells().map((cell) => ( 93 | 94 | {flexRender( 95 | cell.column.columnDef.cell, 96 | cell.getContext() 97 | )} 98 | 99 | ))} 100 | 101 | )) 102 | ) : ( 103 | 104 | 108 | No results. 109 | 110 | 111 | )} 112 | 113 |
114 | 115 | {/* 分页 */} 116 |
117 | 118 |
119 |
120 |
121 | ); 122 | } 123 | -------------------------------------------------------------------------------- /src/components/footer.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Icons } from "./icons"; 3 | import Link from "next/link"; 4 | import Image from "next/image"; 5 | import { 6 | Dialog, 7 | DialogContent, 8 | DialogHeader, 9 | DialogTitle, 10 | DialogTrigger, 11 | } from "./ui/dialog"; 12 | 13 | type Props = {}; 14 | 15 | export default function Footer({}: Props) { 16 | return ( 17 |
18 |
19 |

20 | RunningCode 21 |
22 | 27 | GPT变现/开发思考 28 | 29 |

30 | 31 | 后续开发计划 32 | 33 | 34 | 35 | 开发计划 36 | 37 |
    38 |
  • 收藏功能/类错题本
  • 39 |
  • 收录剑指offer leetcode题目
  • 40 |
  • 基于微信公众号做登录, 保存用户的信息
  • 41 |
42 |
43 |
44 |

45 |
46 | 51 | 52 | 53 | 58 | 59 | 60 | 65 | Buy Me a Coffee at ko-fi.com 72 | 73 |
74 |
75 | 76 |
77 |
78 |

Product

79 | 84 | RunningDev | Nextjs 模板站点 85 | 86 | 87 | 91 | RunningCode | 刷题效率工具 92 | 93 | 94 | 99 | GPTs导航站 100 | 101 |
102 |
103 |

Resources

104 | 108 | NextJs 109 | 110 | 114 | React 115 | 116 | 120 | AntD 121 | 122 |
123 |
124 |
125 | ); 126 | } 127 | -------------------------------------------------------------------------------- /src/components/ui/dialog.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as DialogPrimitive from "@radix-ui/react-dialog" 5 | import { X } from "lucide-react" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const Dialog = DialogPrimitive.Root 10 | 11 | const DialogTrigger = DialogPrimitive.Trigger 12 | 13 | const DialogPortal = DialogPrimitive.Portal 14 | 15 | const DialogClose = DialogPrimitive.Close 16 | 17 | const DialogOverlay = React.forwardRef< 18 | React.ElementRef, 19 | React.ComponentPropsWithoutRef 20 | >(({ className, ...props }, ref) => ( 21 | 29 | )) 30 | DialogOverlay.displayName = DialogPrimitive.Overlay.displayName 31 | 32 | const DialogContent = React.forwardRef< 33 | React.ElementRef, 34 | React.ComponentPropsWithoutRef 35 | >(({ className, children, ...props }, ref) => ( 36 | 37 | 38 | 46 | {children} 47 | 48 | 49 | Close 50 | 51 | 52 | 53 | )) 54 | DialogContent.displayName = DialogPrimitive.Content.displayName 55 | 56 | const DialogHeader = ({ 57 | className, 58 | ...props 59 | }: React.HTMLAttributes) => ( 60 |
67 | ) 68 | DialogHeader.displayName = "DialogHeader" 69 | 70 | const DialogFooter = ({ 71 | className, 72 | ...props 73 | }: React.HTMLAttributes) => ( 74 |
81 | ) 82 | DialogFooter.displayName = "DialogFooter" 83 | 84 | const DialogTitle = React.forwardRef< 85 | React.ElementRef, 86 | React.ComponentPropsWithoutRef 87 | >(({ className, ...props }, ref) => ( 88 | 96 | )) 97 | DialogTitle.displayName = DialogPrimitive.Title.displayName 98 | 99 | const DialogDescription = React.forwardRef< 100 | React.ElementRef, 101 | React.ComponentPropsWithoutRef 102 | >(({ className, ...props }, ref) => ( 103 | 108 | )) 109 | DialogDescription.displayName = DialogPrimitive.Description.displayName 110 | 111 | export { 112 | Dialog, 113 | DialogPortal, 114 | DialogOverlay, 115 | DialogClose, 116 | DialogTrigger, 117 | DialogContent, 118 | DialogHeader, 119 | DialogFooter, 120 | DialogTitle, 121 | DialogDescription, 122 | } 123 | -------------------------------------------------------------------------------- /src/components/ui/command.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import { type DialogProps } from "@radix-ui/react-dialog" 5 | import { Command as CommandPrimitive } from "cmdk" 6 | import { Search } from "lucide-react" 7 | 8 | import { cn } from "@/lib/utils" 9 | import { Dialog, DialogContent } from "@/components/ui/dialog" 10 | 11 | const Command = React.forwardRef< 12 | React.ElementRef, 13 | React.ComponentPropsWithoutRef 14 | >(({ className, ...props }, ref) => ( 15 | 23 | )) 24 | Command.displayName = CommandPrimitive.displayName 25 | 26 | interface CommandDialogProps extends DialogProps {} 27 | 28 | const CommandDialog = ({ children, ...props }: CommandDialogProps) => { 29 | return ( 30 | 31 | 32 | 33 | {children} 34 | 35 | 36 | 37 | ) 38 | } 39 | 40 | const CommandInput = React.forwardRef< 41 | React.ElementRef, 42 | React.ComponentPropsWithoutRef 43 | >(({ className, ...props }, ref) => ( 44 |
45 | 46 | 54 |
55 | )) 56 | 57 | CommandInput.displayName = CommandPrimitive.Input.displayName 58 | 59 | const CommandList = React.forwardRef< 60 | React.ElementRef, 61 | React.ComponentPropsWithoutRef 62 | >(({ className, ...props }, ref) => ( 63 | 68 | )) 69 | 70 | CommandList.displayName = CommandPrimitive.List.displayName 71 | 72 | const CommandEmpty = React.forwardRef< 73 | React.ElementRef, 74 | React.ComponentPropsWithoutRef 75 | >((props, ref) => ( 76 | 81 | )) 82 | 83 | CommandEmpty.displayName = CommandPrimitive.Empty.displayName 84 | 85 | const CommandGroup = React.forwardRef< 86 | React.ElementRef, 87 | React.ComponentPropsWithoutRef 88 | >(({ className, ...props }, ref) => ( 89 | 97 | )) 98 | 99 | CommandGroup.displayName = CommandPrimitive.Group.displayName 100 | 101 | const CommandSeparator = React.forwardRef< 102 | React.ElementRef, 103 | React.ComponentPropsWithoutRef 104 | >(({ className, ...props }, ref) => ( 105 | 110 | )) 111 | CommandSeparator.displayName = CommandPrimitive.Separator.displayName 112 | 113 | const CommandItem = React.forwardRef< 114 | React.ElementRef, 115 | React.ComponentPropsWithoutRef 116 | >(({ className, ...props }, ref) => ( 117 | 125 | )) 126 | 127 | CommandItem.displayName = CommandPrimitive.Item.displayName 128 | 129 | const CommandShortcut = ({ 130 | className, 131 | ...props 132 | }: React.HTMLAttributes) => { 133 | return ( 134 | 141 | ) 142 | } 143 | CommandShortcut.displayName = "CommandShortcut" 144 | 145 | export { 146 | Command, 147 | CommandDialog, 148 | CommandInput, 149 | CommandList, 150 | CommandEmpty, 151 | CommandGroup, 152 | CommandItem, 153 | CommandShortcut, 154 | CommandSeparator, 155 | } 156 | -------------------------------------------------------------------------------- /src/components/lc/data-table-facet-filter.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | // import { CheckIcon, PlusCircledIcon } from "@radix-ui/react-icons" 3 | import { Column } from "@tanstack/react-table"; 4 | 5 | import { cn } from "@/lib/utils"; 6 | // import { Badge } from "@/registry/new-york/ui/badge" 7 | // import { Button } from "@/registry/new-york/ui/button" 8 | import { 9 | Command, 10 | CommandEmpty, 11 | CommandGroup, 12 | CommandInput, 13 | CommandItem, 14 | CommandList, 15 | CommandSeparator, 16 | } from "@/components/ui/command"; 17 | import { 18 | Popover, 19 | PopoverContent, 20 | PopoverTrigger, 21 | } from "@/components/ui/popover"; 22 | import { Separator } from "@/components/ui/separator"; 23 | import { Badge } from "../ui/badge"; 24 | import { CheckIcon, PlusCircle } from "lucide-react"; 25 | import { Button } from "../ui/button"; 26 | 27 | interface DataTableFacetedFilterProps { 28 | column?: Column; 29 | title?: string; 30 | options: { 31 | label: string; 32 | value: string; 33 | icon?: React.ComponentType<{ className?: string }>; 34 | }[]; 35 | } 36 | 37 | export function DataTableFacetedFilter({ 38 | column, 39 | title, 40 | options, 41 | }: DataTableFacetedFilterProps) { 42 | const facets = column?.getFacetedUniqueValues(); 43 | const selectedValues = new Set(column?.getFilterValue() as string[]); 44 | 45 | // console.log(facets); 46 | 47 | return ( 48 | 49 | 50 | 87 | 88 | 89 | 90 | 91 | 92 | No results found. 93 | 94 | {options.map((option) => { 95 | const isSelected = selectedValues.has(option.value); 96 | return ( 97 | { 100 | if (isSelected) { 101 | selectedValues.delete(option.value); 102 | } else { 103 | selectedValues.add(option.value); 104 | } 105 | const filterValues = Array.from(selectedValues); 106 | column?.setFilterValue( 107 | filterValues.length ? filterValues : undefined 108 | ); 109 | }} 110 | > 111 |
119 | 120 |
121 | {option.icon && ( 122 | 123 | )} 124 | {option.label} 125 | {facets?.get(option.value) && ( 126 | 127 | {facets.get(option.value)} 128 | 129 | )} 130 |
131 | ); 132 | })} 133 |
134 | {selectedValues.size > 0 && ( 135 | <> 136 | 137 | 138 | column?.setFilterValue(undefined)} 140 | className="justify-center text-center" 141 | > 142 | Clear filters 143 | 144 | 145 | 146 | )} 147 |
148 |
149 |
150 |
151 | ); 152 | } 153 | -------------------------------------------------------------------------------- /src/components/ui/select.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SelectPrimitive from "@radix-ui/react-select" 5 | import { Check, ChevronDown, ChevronUp } from "lucide-react" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const Select = SelectPrimitive.Root 10 | 11 | const SelectGroup = SelectPrimitive.Group 12 | 13 | const SelectValue = SelectPrimitive.Value 14 | 15 | const SelectTrigger = React.forwardRef< 16 | React.ElementRef, 17 | React.ComponentPropsWithoutRef 18 | >(({ className, children, ...props }, ref) => ( 19 | span]:line-clamp-1", 23 | className 24 | )} 25 | {...props} 26 | > 27 | {children} 28 | 29 | 30 | 31 | 32 | )) 33 | SelectTrigger.displayName = SelectPrimitive.Trigger.displayName 34 | 35 | const SelectScrollUpButton = React.forwardRef< 36 | React.ElementRef, 37 | React.ComponentPropsWithoutRef 38 | >(({ className, ...props }, ref) => ( 39 | 47 | 48 | 49 | )) 50 | SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName 51 | 52 | const SelectScrollDownButton = React.forwardRef< 53 | React.ElementRef, 54 | React.ComponentPropsWithoutRef 55 | >(({ className, ...props }, ref) => ( 56 | 64 | 65 | 66 | )) 67 | SelectScrollDownButton.displayName = 68 | SelectPrimitive.ScrollDownButton.displayName 69 | 70 | const SelectContent = React.forwardRef< 71 | React.ElementRef, 72 | React.ComponentPropsWithoutRef 73 | >(({ className, children, position = "popper", ...props }, ref) => ( 74 | 75 | 86 | 87 | 94 | {children} 95 | 96 | 97 | 98 | 99 | )) 100 | SelectContent.displayName = SelectPrimitive.Content.displayName 101 | 102 | const SelectLabel = React.forwardRef< 103 | React.ElementRef, 104 | React.ComponentPropsWithoutRef 105 | >(({ className, ...props }, ref) => ( 106 | 111 | )) 112 | SelectLabel.displayName = SelectPrimitive.Label.displayName 113 | 114 | const SelectItem = React.forwardRef< 115 | React.ElementRef, 116 | React.ComponentPropsWithoutRef 117 | >(({ className, children, ...props }, ref) => ( 118 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | {children} 133 | 134 | )) 135 | SelectItem.displayName = SelectPrimitive.Item.displayName 136 | 137 | const SelectSeparator = React.forwardRef< 138 | React.ElementRef, 139 | React.ComponentPropsWithoutRef 140 | >(({ className, ...props }, ref) => ( 141 | 146 | )) 147 | SelectSeparator.displayName = SelectPrimitive.Separator.displayName 148 | 149 | export { 150 | Select, 151 | SelectGroup, 152 | SelectValue, 153 | SelectTrigger, 154 | SelectContent, 155 | SelectLabel, 156 | SelectItem, 157 | SelectSeparator, 158 | SelectScrollUpButton, 159 | SelectScrollDownButton, 160 | } 161 | -------------------------------------------------------------------------------- /src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image"; 2 | import { GithubOutlined, XOutlined } from "@ant-design/icons"; 3 | import data from "../../public/data.json"; // 根据实际路径调整 4 | import SquigglyLines from "@/components/SquigglyLines"; 5 | import Link from "next/link"; 6 | import Footer from "@/components/footer"; 7 | import Ref from "@/components/page/ref"; 8 | import MyTimeLine from "@/components/time-line"; 9 | 10 | import { DataType, Grade } from "@/types/lc"; 11 | import { columns } from "@/components/lc/colums"; 12 | import { DataTable } from "@/components/lc/data-table"; 13 | 14 | import { 15 | Dialog, 16 | DialogContent, 17 | DialogDescription, 18 | DialogHeader, 19 | DialogTitle, 20 | DialogTrigger, 21 | } from "@/components/ui/dialog"; 22 | import { Button } from "@/components/ui/button"; 23 | import { Icons } from "@/components/icons"; 24 | 25 | async function getData(): Promise { 26 | // Fetch data from your API here. 27 | // 直接将导入的JSON赋值给一个变量,类型为DataType[] 28 | const dataList: DataType[] = data.map((item) => ({ 29 | ...item, 30 | grade: item.grade as Grade, 31 | })); 32 | return dataList; 33 | } 34 | 35 | export default async function Home() { 36 | const data = await getData(); 37 | return ( 38 |
39 |
40 | {/* before:w-full sm:before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] before:absolute before:h-[300px] */} 41 | {/* after:absolute after:-z-20 after:h-[180px] after:w-full sm:after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] */} 42 | {/* Next.js Logo */} 51 |
52 |
53 | 54 | Logo 63 | RunningCode 64 | 65 | 66 | 67 | Changelog 68 | 69 | 70 | 71 | Changelog 72 | 73 | 74 | 75 | 76 | 77 | 82 | ⭐️GPT Plus升级 83 | 84 |
85 | 86 |
87 | 92 | 93 | 94 | 99 | 100 | 101 | 102 | {/* 107 | 108 | */} 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 公众号-记录开发过程以及题解 117 | 118 | wechat 119 | 120 | 121 |
122 |
123 | 124 |

125 | Running 126 | 127 | Code 128 | 129 | 130 |

131 |

132 | 目前面试笔试中大量出现的题目都是出自 剑指 offer、牛客 101 以及 lc 133 | hot100, 所以我按照分类收录了这些题目, 刷题吧, 王子公主们!🤣 134 |

135 |

136 | 目前收录题目数: {data.length} 137 |

138 |
139 | 140 |
141 | {/* max-w-[1200px] mx-auto md:w-[1200px] w-3xl */} 142 | {/* container mx-auto */} 143 | 144 |
145 | 146 | 147 | 148 |
149 |
150 | ); 151 | } 152 | -------------------------------------------------------------------------------- /src/components/ui/dropdown-menu.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" 5 | import { Check, ChevronRight, Circle } from "lucide-react" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const DropdownMenu = DropdownMenuPrimitive.Root 10 | 11 | const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger 12 | 13 | const DropdownMenuGroup = DropdownMenuPrimitive.Group 14 | 15 | const DropdownMenuPortal = DropdownMenuPrimitive.Portal 16 | 17 | const DropdownMenuSub = DropdownMenuPrimitive.Sub 18 | 19 | const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup 20 | 21 | const DropdownMenuSubTrigger = React.forwardRef< 22 | React.ElementRef, 23 | React.ComponentPropsWithoutRef & { 24 | inset?: boolean 25 | } 26 | >(({ className, inset, children, ...props }, ref) => ( 27 | 36 | {children} 37 | 38 | 39 | )) 40 | DropdownMenuSubTrigger.displayName = 41 | DropdownMenuPrimitive.SubTrigger.displayName 42 | 43 | const DropdownMenuSubContent = React.forwardRef< 44 | React.ElementRef, 45 | React.ComponentPropsWithoutRef 46 | >(({ className, ...props }, ref) => ( 47 | 55 | )) 56 | DropdownMenuSubContent.displayName = 57 | DropdownMenuPrimitive.SubContent.displayName 58 | 59 | const DropdownMenuContent = React.forwardRef< 60 | React.ElementRef, 61 | React.ComponentPropsWithoutRef 62 | >(({ className, sideOffset = 4, ...props }, ref) => ( 63 | 64 | 73 | 74 | )) 75 | DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName 76 | 77 | const DropdownMenuItem = React.forwardRef< 78 | React.ElementRef, 79 | React.ComponentPropsWithoutRef & { 80 | inset?: boolean 81 | } 82 | >(({ className, inset, ...props }, ref) => ( 83 | 92 | )) 93 | DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName 94 | 95 | const DropdownMenuCheckboxItem = React.forwardRef< 96 | React.ElementRef, 97 | React.ComponentPropsWithoutRef 98 | >(({ className, children, checked, ...props }, ref) => ( 99 | 108 | 109 | 110 | 111 | 112 | 113 | {children} 114 | 115 | )) 116 | DropdownMenuCheckboxItem.displayName = 117 | DropdownMenuPrimitive.CheckboxItem.displayName 118 | 119 | const DropdownMenuRadioItem = React.forwardRef< 120 | React.ElementRef, 121 | React.ComponentPropsWithoutRef 122 | >(({ className, children, ...props }, ref) => ( 123 | 131 | 132 | 133 | 134 | 135 | 136 | {children} 137 | 138 | )) 139 | DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName 140 | 141 | const DropdownMenuLabel = React.forwardRef< 142 | React.ElementRef, 143 | React.ComponentPropsWithoutRef & { 144 | inset?: boolean 145 | } 146 | >(({ className, inset, ...props }, ref) => ( 147 | 156 | )) 157 | DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName 158 | 159 | const DropdownMenuSeparator = React.forwardRef< 160 | React.ElementRef, 161 | React.ComponentPropsWithoutRef 162 | >(({ className, ...props }, ref) => ( 163 | 168 | )) 169 | DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName 170 | 171 | const DropdownMenuShortcut = ({ 172 | className, 173 | ...props 174 | }: React.HTMLAttributes) => { 175 | return ( 176 | 180 | ) 181 | } 182 | DropdownMenuShortcut.displayName = "DropdownMenuShortcut" 183 | 184 | export { 185 | DropdownMenu, 186 | DropdownMenuTrigger, 187 | DropdownMenuContent, 188 | DropdownMenuItem, 189 | DropdownMenuCheckboxItem, 190 | DropdownMenuRadioItem, 191 | DropdownMenuLabel, 192 | DropdownMenuSeparator, 193 | DropdownMenuShortcut, 194 | DropdownMenuGroup, 195 | DropdownMenuPortal, 196 | DropdownMenuSub, 197 | DropdownMenuSubContent, 198 | DropdownMenuSubTrigger, 199 | DropdownMenuRadioGroup, 200 | } 201 | -------------------------------------------------------------------------------- /public/redbook.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/antd/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { Button, Input, Rate, Table, Tag, message } from "antd"; 3 | import Image from "next/image"; 4 | import type { TableColumnsType, TableProps } from "antd"; 5 | import { GithubOutlined, XOutlined } from "@ant-design/icons"; 6 | import data from "../../../public/data.json"; // 根据实际路径调整 7 | import { useEffect, useState } from "react"; 8 | const { Search } = Input; 9 | import type { SearchProps } from "antd/es/input/Search"; 10 | import SquigglyLines from "@/components/SquigglyLines"; 11 | import Link from "next/link"; 12 | import Footer from "@/components/footer"; 13 | import { Grade, DataType } from "@/types/lc"; 14 | import { getGradeValue } from "@/lib/utils"; 15 | import { useLocalStorage } from "@/hooks/useLocalStorage"; 16 | import Ref from "@/components/page/ref"; 17 | import CustomModal from "@/components/Modal"; 18 | import MyTimeLine from "@/components/time-line"; 19 | // 配置受控 filter 的 type 20 | type OnChange = NonNullable["onChange"]>; 21 | type Filters = Parameters[1]; 22 | type GetSingle = T extends (infer U)[] ? U : never; 23 | type Sorts = GetSingle[2]>; 24 | interface Iretain { 25 | [key: number]: number; 26 | } 27 | 28 | const desc = ["terrible", "bad", "normal", "good", "wonderful"]; 29 | 30 | export default function Home() { 31 | const [filteredInfo, setFilteredInfo] = useState({}); 32 | const [sortedInfo, setSortedInfo] = useState({}); 33 | 34 | // localStorage 存储的记忆数组 35 | const [retain, setRetain, clear] = useLocalStorage("remember", {}); 36 | 37 | const handleRetainClick = (record: DataType, value: number) => { 38 | // 找到对应的 idx 39 | const idx = record.idx; 40 | setRetain({ ...retain, [idx]: value }); 41 | success("成功设置记忆值"); 42 | }; 43 | 44 | const [dataList, setDataList] = useState([]); 45 | 46 | const [filterTableLength, setFilterTableLength] = useState(dataList.length); 47 | // console.log(filterTableLength); 48 | 49 | useEffect(() => { 50 | const updatedDataList = data.map((item) => ({ 51 | ...item, 52 | grade: item.grade as Grade, 53 | retain: retain[item.idx] || 0, 54 | })); 55 | setDataList(updatedDataList); 56 | setFilterTableLength(updatedDataList.length); 57 | }, [retain]); 58 | 59 | // console.log(dataList.length); 60 | 61 | // console.log(loading); 62 | 63 | const columns: TableColumnsType = [ 64 | { 65 | title: "index", 66 | dataIndex: "idx", 67 | key: "idx", 68 | hidden: true, 69 | }, 70 | { 71 | title: "题目名", 72 | dataIndex: "name", 73 | key: "name", 74 | // filterSearch: true, 75 | filteredValue: filteredInfo.name || null, 76 | onFilter: (value, record) => { 77 | // console.log("name filter ", value, record); 78 | if (typeof value === "string") { 79 | return record.name.includes(value); 80 | } 81 | return false; 82 | }, 83 | sorter: (a, b) => a.name.length - b.name.length, 84 | sortDirections: ["descend"], 85 | }, 86 | 87 | { 88 | title: "难度", 89 | dataIndex: "grade", 90 | key: "grade", 91 | filters: [ 92 | { text: "easy", value: "easy" }, 93 | { text: "medium", value: "medium" }, 94 | { text: "hard", value: "hard" }, 95 | ], 96 | filteredValue: filteredInfo.grade || null, 97 | render: (value) => { 98 | switch (value) { 99 | case "easy": 100 | return {value}; 101 | case "medium": 102 | return {value}; 103 | case "hard": 104 | return {value}; 105 | default: 106 | break; 107 | } 108 | return {value}; 109 | }, 110 | onFilter: (value, record) => record.grade === (value as string), 111 | sorter: (a, b) => getGradeValue(a.grade) - getGradeValue(b.grade), 112 | sortDirections: ["ascend", "descend"], 113 | }, 114 | { 115 | title: "分类", 116 | dataIndex: "algoCategory", 117 | key: "algoCategory", 118 | filterMultiple: true, 119 | filters: [ 120 | { text: "链表", value: "链表" }, 121 | { text: "二叉树", value: "二叉树" }, 122 | { text: "数组 ", value: "数组" }, 123 | { text: "字符串", value: "字符串" }, 124 | { text: "回溯", value: "回溯" }, 125 | { text: "栈", value: "栈" }, 126 | { text: "队列", value: "队列" }, 127 | { text: "二分查找", value: "二分查找" }, 128 | { text: "哈希表", value: "哈希表" }, 129 | { text: "动态规划", value: "动态规划" }, 130 | { text: "贪心算法", value: "贪心算法" }, 131 | { text: "滑动窗口", value: "滑动窗口" }, 132 | { text: "堆", value: "堆" }, 133 | { text: "图", value: "图" }, 134 | { text: "位运算", value: "位运算" }, 135 | ], 136 | filteredValue: filteredInfo.algoCategory || null, 137 | onFilter: (value, record) => record.algoCategory === (value as string), 138 | }, 139 | { 140 | title: "出处", 141 | dataIndex: "tags", 142 | key: "tags", 143 | filterSearch: true, 144 | filteredValue: filteredInfo.tags || null, 145 | onFilter: (value, record) => { 146 | // console.log("出处:", value, record); 147 | 148 | if (typeof value === "string") { 149 | return record.tags.includes(value); 150 | } 151 | 152 | return false; 153 | }, 154 | filters: [ 155 | { text: "nowcoder101", value: "nowcoder101" }, 156 | { text: "leetcode", value: "🔥 LeetCode Hot 100" }, 157 | ], 158 | sorter: (a, b) => a.name.length - b.name.length, 159 | sortDirections: ["descend"], 160 | render: (_, { tags }) => ( 161 | <> 162 | {tags.map((tag) => { 163 | let color = tag.length > 5 ? "geekblue" : "green"; 164 | if (tag === "loser") { 165 | color = "volcano"; 166 | } 167 | return ( 168 | 169 | {tag} 170 | 171 | ); 172 | })} 173 | 174 | ), 175 | }, 176 | { 177 | title: "URL", 178 | dataIndex: "url", 179 | key: "url", 180 | render: (value) => ( 181 | 182 | URL 183 | 184 | ), 185 | }, 186 | { 187 | title: "自评熟练度", 188 | dataIndex: "retain", 189 | key: "retain", 190 | render: (_, record) => ( 191 | { 193 | handleRetainClick(record, value); 194 | }} 195 | tooltips={desc} 196 | key={record.idx} 197 | value={retain[record.idx]} 198 | > 199 | ), 200 | }, 201 | ]; 202 | 203 | // 搜索函数 204 | const onSearch: SearchProps["onSearch"] = (value, _e, info) => { 205 | console.log(info?.source, value); 206 | setFilteredInfo({ 207 | name: [value], 208 | }); 209 | }; 210 | 211 | const [messageApi, contextHolder] = message.useMessage(); 212 | 213 | const success = (message: string) => { 214 | messageApi.open({ 215 | type: "success", 216 | content: message, 217 | }); 218 | }; 219 | 220 | const error = (message: string = "error") => { 221 | messageApi.open({ 222 | type: "error", 223 | content: message, 224 | }); 225 | }; 226 | 227 | const handleChange: OnChange = (pagination, filters, sorter) => { 228 | // console.log("Various parameters", pagination, filters, sorter); 229 | setFilteredInfo(filters); 230 | setSortedInfo(sorter as Sorts); 231 | // console.log(filters); 232 | 233 | // 设置长度 234 | const filteredData = dataList.filter((item) => { 235 | return Object.entries(filters).every(([key, value]) => { 236 | if (!value || value.length === 0) { 237 | return true; 238 | } 239 | return value.includes(item[key]); 240 | }); 241 | }); 242 | // console.log("filterData ", filteredData); 243 | 244 | setFilterTableLength(filteredData.length); 245 | }; 246 | 247 | const clearFilters = () => { 248 | setFilteredInfo({}); 249 | success("重置筛选条件"); 250 | }; 251 | 252 | const clearAll = () => { 253 | setFilteredInfo({}); 254 | setSortedInfo({}); 255 | success("重置全部条件"); 256 | }; 257 | 258 | return ( 259 |
260 | {contextHolder} 261 |
262 | {/* before:w-full sm:before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] before:absolute before:h-[300px] */} 263 | {/* after:absolute after:-z-20 after:h-[180px] after:w-full sm:after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] */} 264 | {/* Next.js Logo */} 273 |
274 | 275 | Logo 284 | 285 | 286 |
287 | 292 | 293 | 294 | 299 | 300 | 301 | 302 | 303 | 304 |
305 |
306 | 307 |

308 | Running 309 | 310 | Code 311 | 312 | 313 |

314 |

315 | 目前面试笔试中大量出现的题目都是出自 剑指 offer、牛客 101 以及 lc 316 | hot100, 所以我按照分类收录了这些题目, 刷题吧, 王子公主们!🤣 317 |

318 |
319 | 320 |
321 | 327 | 328 | 329 | 337 |
338 |
339 |
收录题目数: {filterTableLength}
} 352 | /> 353 | 354 | 355 | 356 | 357 |
358 | 359 | ); 360 | } 361 | -------------------------------------------------------------------------------- /public/ai.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/components/icons.tsx: -------------------------------------------------------------------------------- 1 | type IconProps = React.HTMLAttributes; 2 | 3 | export const Icons = { 4 | logo: (props: IconProps) => ( 5 | 6 | 7 | 18 | 29 | 30 | ), 31 | twitter: (props: IconProps) => ( 32 | 39 | 40 | 41 | ), 42 | X: (props: IconProps) => ( 43 | 44 | 48 | 49 | ), 50 | gitHub: (props: IconProps) => ( 51 | 52 | 56 | 57 | ), 58 | radix: (props: IconProps) => ( 59 | 60 | 64 | 65 | 69 | 70 | ), 71 | aria: (props: IconProps) => ( 72 | 73 | 74 | 75 | ), 76 | npm: (props: IconProps) => ( 77 | 78 | 82 | 83 | ), 84 | yarn: (props: IconProps) => ( 85 | 86 | 90 | 91 | ), 92 | pnpm: (props: IconProps) => ( 93 | 94 | 98 | 99 | ), 100 | react: (props: IconProps) => ( 101 | 102 | 106 | 107 | ), 108 | tailwind: (props: IconProps) => ( 109 | 110 | 114 | 115 | ), 116 | google: (props: IconProps) => ( 117 | 125 | 129 | 133 | 137 | 141 | 142 | ), 143 | apple: (props: IconProps) => ( 144 | 145 | 149 | 150 | ), 151 | paypal: (props: IconProps) => ( 152 | 153 | 157 | 158 | ), 159 | spinner: (props: IconProps) => ( 160 | 172 | 173 | 174 | ), 175 | vercel: (props: IconProps) => ( 176 | 184 | 185 | 186 | ), 187 | lemon: (props: IconProps) => ( 188 | 196 | 202 | 203 | ), 204 | redbook: (props: IconProps) => ( 205 | 215 | 220 | 225 | 226 | ), 227 | wechat: (props: IconProps) => ( 228 | 238 | 243 | 244 | ), 245 | }; 246 | --------------------------------------------------------------------------------