├── .github └── ISSUE_TEMPLATE │ └── suggest-a-new-tool.md ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── astro.config.mjs ├── package.json ├── pnpm-lock.yaml ├── public ├── fonts │ └── InterVariable.woff2 ├── rise-of-machine.png └── sitemap.txt ├── src ├── components │ ├── Card.css │ ├── Card.jsx │ ├── CardsContainer.css │ ├── CardsContainer.jsx │ ├── CategoryNav.css │ ├── CategoryNav.jsx │ ├── CategoryNavItem.css │ ├── CategoryNavItem.jsx │ └── Dashboard.jsx ├── data │ └── tools.json ├── env.d.ts ├── layouts │ └── Layout.astro └── pages │ ├── 404.astro │ ├── categories │ └── [category].astro │ └── index.astro └── tsconfig.json /.github/ISSUE_TEMPLATE/suggest-a-new-tool.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Suggest a new tool 3 | about: Suggest a new tool for riseofmachine.com 4 | title: "[Add] riseofmachine.com" 5 | labels: '' 6 | assignees: planetabhi 7 | 8 | --- 9 | 10 | ### 1. Website Link 11 | - Example: `https://riseofmachine.com/` 12 | 13 | ### 2. Category (Optional) 14 | - What category best describes this tool? 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # generated types 5 | .astro/ 6 | 7 | # dependencies 8 | node_modules/ 9 | .netlify 10 | 11 | # logs 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | pnpm-debug.log* 16 | 17 | # environment variables 18 | .env 19 | .env.production 20 | 21 | # macOS-specific files 22 | .DS_Store 23 | 24 | # vscode 25 | .vscode 26 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Rise of Machine 2 | 3 | ### Getting Started 4 | 5 | ```bash 6 | # Clone the repository 7 | git clone https://github.com/NewDesignFile/template-directory.git 8 | cd template-directory 9 | 10 | # Create a new branch for your AI tool 11 | git checkout -b add/your-ai-tool 12 | ``` 13 | 14 | 15 | ### Adding a Tool 16 | Tools data is stored in `src/data/tools.json`. This file contains all AI tools organized by category in alphabetical order. 17 | 18 | Add your tool entry to the appropriate category in the JSON file. Make sure to place your entry in alphabetical order within its category. Each tool entry should follow this format: 19 | 20 | ```json 21 | { 22 | "title": "Your AI Tool Name", 23 | "body": "A brief description.", 24 | "tag": "Pricing tag comes here.", 25 | "url": "https://your-ai-tool.com?ref=riseofmachine.com", 26 | "date-added": "YYYY-MM-DD" 27 | } 28 | ``` 29 | 30 | Note: Always add `?ref=riseofmachine.com` to the end of your AI tool's URL. 31 | 32 | ### Creating a Pull Request 33 | After adding your tool to the JSON file, submit your changes: 34 | 35 | ```bash 36 | # Add and commit your changes 37 | git add . 38 | git commit -m "Add [Tool Name] to [Category]" 39 | 40 | # Push to your branch 41 | git push -u origin add/your-ai-tool 42 | ``` 43 | 44 | Then go to the [repository page](https://github.com/NewDesignFile/template-directory) and create a pull request. 45 | 46 | ### Guidelines 47 | - Choose the most appropriate category for your tool. 48 | - Make sure to place your entry in alphabetical order within its category. 49 | - Don't create new categories yourself. If you don't find an appropriate category, add your tool under the "Xtras" category and suggest a new category by creating an issue. 50 | - Keep the description concise and informative. 51 | - For the pricing tag, choose one of: `Free` | `Freemium` | `From $X/mo` | `$X One-time` | `Not available` 52 | - Make sure the URL includes the reference parameter: `?ref=riseofmachine.com` 53 | - Include today's date in the "date-added" field. 54 | - Verify your JSON syntax is valid before submitting. -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Abhimanyu Rana @planetabhi 4 | Copyright (c) 2024 Method Black Studio 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, and/or publish copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Directory 2 | 3 | ![Directory Preview](https://new-ui.com/assets/images/templates/preview-directory.png) 4 | 5 | - An Astro directory template. 6 | - Install: `pnpm create astro@latest --template NewDesignFile/template-directory` 7 | - Usage: [Getting started guide](https://new-ui.com/docs/templates/directory). 8 | -------------------------------------------------------------------------------- /astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'astro/config'; 2 | import react from "@astrojs/react"; 3 | import netlify from "@astrojs/netlify"; 4 | 5 | import partytown from "@astrojs/partytown"; 6 | 7 | export default defineConfig({ 8 | integrations: [ 9 | react(), 10 | partytown( 11 | { 12 | config: { 13 | forward: ["dataLayer.push"], 14 | }, 15 | } 16 | )], 17 | 18 | output: "server", 19 | adapter: netlify() 20 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "riseofmachine", 3 | "version": "2.05.0", 4 | "rhyver": "v2.25Q1.05.0", 5 | "description": "Discover AI tools curated for makers and SMBs.", 6 | "type": "module", 7 | "private": false, 8 | "main": "src/data/tools.json", 9 | "files": [ 10 | "src/data/tools.json" 11 | ], 12 | "scripts": { 13 | "dev": "astro dev", 14 | "start": "astro dev", 15 | "build": "astro build", 16 | "preview": "astro preview", 17 | "astro": "astro" 18 | }, 19 | "dependencies": { 20 | "@astrojs/netlify": "^6.3.4", 21 | "@astrojs/partytown": "^2.1.4", 22 | "@astrojs/react": "^4.3.0", 23 | "@types/react": "^19.1.6", 24 | "@types/react-dom": "^19.1.5", 25 | "astro": "^5.8.1", 26 | "react": "^19.1.0", 27 | "react-dom": "^19.1.0" 28 | }, 29 | "devDependencies": { 30 | "@new-ui/foundations": "^0.2.5" 31 | }, 32 | "repository": { 33 | "type": "git", 34 | "url": "git+https://github.com/NewDesignFile/template-directory.git" 35 | }, 36 | "bugs": { 37 | "url": "https://github.com/NewDesignFile/template-directory/issues" 38 | }, 39 | "keywords": [ 40 | "directory", 41 | "ai", 42 | "astro", 43 | "template", 44 | "listing", 45 | "astro" 46 | ], 47 | "author": "@planetabhi", 48 | "license": "MIT", 49 | "publishConfig": { 50 | "access": "public" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /public/fonts/InterVariable.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewDesignFile/template-directory/9ab4da1d895a70a7dc9b4541444a0a9778fa6de2/public/fonts/InterVariable.woff2 -------------------------------------------------------------------------------- /public/rise-of-machine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NewDesignFile/template-directory/9ab4da1d895a70a7dc9b4541444a0a9778fa6de2/public/rise-of-machine.png -------------------------------------------------------------------------------- /public/sitemap.txt: -------------------------------------------------------------------------------- 1 | https://riseofmachine.com/ 2 | https://riseofmachine.com/categories/all 3 | https://riseofmachine.com/categories/art 4 | https://riseofmachine.com/categories/audio 5 | https://riseofmachine.com/categories/code 6 | https://riseofmachine.com/categories/copywriting 7 | https://riseofmachine.com/categories/design 8 | https://riseofmachine.com/categories/developer 9 | https://riseofmachine.com/categories/education 10 | https://riseofmachine.com/categories/enterprise 11 | https://riseofmachine.com/categories/fashion 12 | https://riseofmachine.com/categories/gaming 13 | https://riseofmachine.com/categories/health 14 | https://riseofmachine.com/categories/legal 15 | https://riseofmachine.com/categories/llm 16 | https://riseofmachine.com/categories/music 17 | https://riseofmachine.com/categories/nocode 18 | https://riseofmachine.com/categories/photos 19 | https://riseofmachine.com/categories/productivity 20 | https://riseofmachine.com/categories/prompts 21 | https://riseofmachine.com/categories/research 22 | https://riseofmachine.com/categories/seo 23 | https://riseofmachine.com/categories/social 24 | https://riseofmachine.com/categories/video 25 | https://riseofmachine.com/categories/xtras -------------------------------------------------------------------------------- /src/components/Card.css: -------------------------------------------------------------------------------- 1 | .link-card { 2 | list-style: none; 3 | display: flex; 4 | background-color: var(--background-secondary); 5 | background-position: 100%; 6 | border-radius: var(--spacing-03); 7 | height: 8.5rem; 8 | position: relative; 9 | --shadow-color: rgb(0 0 0 / 0.04); 10 | box-shadow: 11 | 0px 0px 0px 1px var(--background-selected), 12 | 0px 1px 1px -0.5px var(--shadow-color), 13 | 0px 3px 3px -1.5px var(--shadow-color), 14 | 0px 12px 12px -6px var(--shadow-color); 15 | content-visibility: auto; 16 | contain-intrinsic-size: 8.5rem; 17 | will-change: transform; 18 | } 19 | 20 | .link-card > a { 21 | width: 100%; 22 | text-decoration: none; 23 | padding: 0.8rem 1.2rem; 24 | color: var(--accent); 25 | justify-content: space-between; 26 | } 27 | 28 | p { 29 | color: var(--text-secondary); 30 | } 31 | 32 | .link-card:is(:hover, :focus-within) { 33 | transition: box-shadow 0.2s ease-out; 34 | background-position: 0; 35 | background: var(--background); 36 | box-shadow: 37 | 0px 0px 0px 2px var(--link), 38 | 0px 1px 1px -0.5px var(--shadow-color), 39 | 0px 3px 3px -1.5px var(--shadow-color), 40 | 0px 12px 12px -6px var(--shadow-color); 41 | } 42 | 43 | p.distribution { 44 | margin: var(--spacing-00); 45 | position: absolute; 46 | bottom: var(--spacing-06); 47 | } 48 | 49 | span.tag { 50 | background-color: var(--background-selected); 51 | padding: calc(0.25rem - 1px) calc(0.5rem - 1px); 52 | border-radius: var(--spacing-02); 53 | display: inline-block; 54 | color: var(--text-secondary); 55 | margin-top: var(--spacing-08); 56 | font-size: var(--desktop-caption); 57 | line-height: var(--lh-desktop-caption); 58 | font-family: var(--body-copy); 59 | } 60 | 61 | span.tag-new { 62 | background-color: var(--background-selected); 63 | padding: calc(0.25rem - 1px) calc(0.5rem - 1px); 64 | border-radius: var(--spacing-02); 65 | display: inline-block; 66 | color: var(--text-warning); 67 | margin-top: var(--spacing-08); 68 | font-size: var(--desktop-caption); 69 | line-height: var(--lh-desktop-caption); 70 | font-family: var(--body-copy); 71 | } -------------------------------------------------------------------------------- /src/components/Card.jsx: -------------------------------------------------------------------------------- 1 | import "./Card.css"; 2 | 3 | export default function Card(props) { 4 | const { href, title, body, tag, dateAdded } = props; 5 | 6 | const isNew = () => { 7 | if (!dateAdded) return false; 8 | 9 | const addedDate = new Date(dateAdded); 10 | const today = new Date(); 11 | const differenceInTime = today.getTime() - addedDate.getTime(); 12 | const differenceInDays = differenceInTime / (1000 * 3600 * 24); 13 | 14 | return differenceInDays <= 30; 15 | }; 16 | 17 | return ( 18 |
  • 19 | 20 | {title} 21 |

    {body}

    22 |

    23 | {isNew() && 🔥} 24 | {tag} 25 |

    26 |
    27 |
  • 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /src/components/CardsContainer.css: -------------------------------------------------------------------------------- 1 | .link-card-grid { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr)); 4 | gap: var(--spacing-05); 5 | padding: var(--spacing-00); 6 | } -------------------------------------------------------------------------------- /src/components/CardsContainer.jsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import Card from "./Card"; 3 | import "./CardsContainer.css"; 4 | import data from "../data/tools.json"; 5 | 6 | export default function CardsContainer({ filter }) { 7 | const filteredCards = useMemo(() => { 8 | return data.tools 9 | .filter((item) => filter === "all" || filter === item.category) 10 | .flatMap((item) => item.content) 11 | .sort((a, b) => a.title.localeCompare(b.title)); 12 | }, [filter]); 13 | 14 | return ( 15 |
    16 | 28 |
    29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /src/components/CategoryNav.css: -------------------------------------------------------------------------------- 1 | .category-nav-container { 2 | position: sticky; 3 | top: 0; 4 | width: 100%; 5 | z-index: 999999; 6 | background-color: var(--background); 7 | -webkit-backdrop-filter: blur(.5rem); 8 | backdrop-filter: blur(.5rem); 9 | } 10 | 11 | .category-nav { 12 | width: 100%; 13 | box-shadow: inset 0px -1px 0px var(--border-muted); 14 | white-space: nowrap; 15 | overflow-x: scroll; 16 | overflow-y: hidden; 17 | display: flex; 18 | align-items: center; 19 | background-color: transparent; 20 | scrollbar-width: none; 21 | -webkit-overflow-scrolling: touch; 22 | scroll-behavior: smooth; 23 | overflow: scroll hidden; 24 | } 25 | 26 | .category-nav::-webkit-scrollbar { 27 | display: none; 28 | } 29 | 30 | .nav-fade { 31 | position: absolute; 32 | top: -1px; 33 | height: 100%; 34 | width: var(--spacing-11); 35 | display: flex; 36 | align-items: center; 37 | justify-content: center; 38 | z-index: 999; 39 | cursor: pointer; 40 | pointer-events: none; 41 | } 42 | 43 | .nav-fade-left { 44 | left: -16px; 45 | background: linear-gradient(to right, var(--background) 30%, rgba(0, 0, 0, 0)); 46 | opacity: 0; 47 | } 48 | 49 | .nav-fade-right { 50 | right: -16px; 51 | background: linear-gradient(to left, var(--background) 30%, rgba(0, 0, 0, 0)); 52 | } 53 | 54 | .nav-arrow-icon { 55 | width: var(--spacing-09); 56 | height: var(--spacing-09); 57 | border-radius: 50%; 58 | padding: var(--spacing-02); 59 | pointer-events: auto; 60 | color: var(--icon-secondary); 61 | -webkit-backdrop-filter: blur(.5rem); 62 | backdrop-filter: blur(.5rem); 63 | } 64 | 65 | .nav-fade:hover .nav-arrow-icon { 66 | color: var(--icon-primary); 67 | } 68 | 69 | .nav-fade-left.show { 70 | opacity: 1; 71 | } 72 | 73 | .nav-fade-right.hide { 74 | opacity: 0; 75 | } -------------------------------------------------------------------------------- /src/components/CategoryNav.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import "./CategoryNav.css"; 3 | import data from "../data/tools.json"; 4 | import CategoryNavItem from "./CategoryNavItem"; 5 | 6 | export default function CategoryNav({ filter }) { 7 | const navItems = [{ title: "All Tools", category: "all" }, ...data.tools]; 8 | 9 | useEffect(() => { 10 | const nav = document.querySelector('.category-nav'); 11 | const leftFade = document.querySelector('.nav-fade-left'); 12 | const rightFade = document.querySelector('.nav-fade-right'); 13 | 14 | function checkScroll() { 15 | if (nav.scrollLeft > 0) { 16 | leftFade.classList.add('show'); 17 | } else { 18 | leftFade.classList.remove('show'); 19 | } 20 | 21 | if (nav.scrollLeft >= nav.scrollWidth - nav.clientWidth - 5) { 22 | rightFade.classList.add('hide'); 23 | } else { 24 | rightFade.classList.remove('hide'); 25 | } 26 | } 27 | 28 | nav.addEventListener('scroll', checkScroll); 29 | 30 | checkScroll(); 31 | 32 | leftFade.addEventListener('click', () => { 33 | nav.scrollBy({ left: -200, behavior: 'smooth' }); 34 | }); 35 | 36 | rightFade.addEventListener('click', () => { 37 | nav.scrollBy({ left: 200, behavior: 'smooth' }); 38 | }); 39 | 40 | return () => { 41 | nav.removeEventListener('scroll', checkScroll); 42 | leftFade.removeEventListener('click', () => {}); 43 | rightFade.removeEventListener('click', () => {}); 44 | }; 45 | }, []); 46 | 47 | return ( 48 |
    49 | 61 | 62 |
    63 | 64 | 65 | 66 |
    67 | 68 |
    69 | 70 | 71 | 72 |
    73 | 74 |
    75 | ); 76 | } -------------------------------------------------------------------------------- /src/components/CategoryNavItem.css: -------------------------------------------------------------------------------- 1 | .nav__item { 2 | display: inline-block; 3 | text-decoration: none; 4 | border: none; 5 | outline: none; 6 | background: none; 7 | cursor: pointer; 8 | border-bottom: 2px solid transparent; 9 | font-family: var(--body-copy); 10 | font-weight: 400; 11 | color: var(--text-secondary); 12 | } 13 | 14 | span.category-count { 15 | color: var(--text-secondary-alt); 16 | display: inline-block; 17 | min-width: var(--spacing-07); 18 | text-align: center; 19 | border-radius: var(--spacing-02); 20 | } 21 | 22 | .nav__item:hover { 23 | color: var(--text-primary); 24 | } 25 | 26 | .nav__item.is-active { 27 | color: var(--text-primary); 28 | border-bottom: 2px solid var(--accent); 29 | } 30 | 31 | .nav__item:hover span.category-count, 32 | .nav__item.is-active span.category-count { 33 | color: var(--text-primary); 34 | } 35 | -------------------------------------------------------------------------------- /src/components/CategoryNavItem.jsx: -------------------------------------------------------------------------------- 1 | import { navigate } from "astro:transitions/client"; 2 | import { useState, useEffect, useRef } from "react"; 3 | import data from "../data/tools.json"; 4 | import "./CategoryNavItem.css"; 5 | 6 | export default function CategoryNavItem(props) { 7 | const buttonRef = useRef(null); 8 | const { title, category, filter } = props; 9 | const [isActive, setIsActive] = useState(false); 10 | 11 | const handleNavigation = (e) => { 12 | e.preventDefault(); 13 | navigate(`/categories/${category}`, { 14 | history: "push", 15 | state: { category }, 16 | }); 17 | }; 18 | 19 | const getCategoryCount = () => { 20 | if (category === "all") { 21 | return data.tools.reduce((acc, item) => acc + item.content.length, 0); 22 | } 23 | 24 | const navItemData = data.tools.filter((item) => item.category === category); 25 | return navItemData[0]?.content.length; 26 | }; 27 | 28 | useEffect(() => { 29 | let subscription = true; 30 | 31 | if (filter === category) { 32 | setIsActive(true); 33 | } else { 34 | setIsActive(false); 35 | } 36 | 37 | return () => (subscription = !subscription); 38 | }, [filter]); 39 | 40 | useEffect(() => { 41 | let subscription = true; 42 | const activeButton = buttonRef.current.classList.contains("is-active"); 43 | 44 | if (activeButton) { 45 | buttonRef.current.scrollIntoView({ 46 | behavior: "instant", 47 | block: "nearest", 48 | inline: "center", 49 | }); 50 | } 51 | 52 | return () => (subscription = !subscription); 53 | }, [isActive]); 54 | 55 | return ( 56 | 67 | ); 68 | } 69 | -------------------------------------------------------------------------------- /src/components/Dashboard.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import CategoryNav from "./CategoryNav"; 3 | import CardsContainer from "./CardsContainer"; 4 | 5 | export default function Dashboard({ category }) { 6 | const [currentCategory, setCurrentCategory] = useState(category); 7 | 8 | useEffect(() => { 9 | setCurrentCategory(category); 10 | }, [category]); 11 | 12 | return ( 13 | <> 14 | 15 | 16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /src/layouts/Layout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { ViewTransitions } from "astro:transitions"; 3 | 4 | export interface Props { 5 | site: string; 6 | title: string; 7 | tagline: string; 8 | } 9 | 10 | const { site, title, tagline } = Astro.props; 11 | --- 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | {site} — Discover AI tools curated for makers and SMBs. 22 | 23 | 27 | 28 | 29 | 33 | 37 | 38 | 39 | 40 | 41 | 42 | 49 | 50 | 51 | 52 | 53 |
    54 | 65 |
    66 | Submit a Tool 72 | 93 |
    94 |
    95 | 96 |
    97 |
    98 |

    101 | {title} 102 |

    103 |

    104 | {tagline} 105 |

    106 |
    107 |
    108 | 109 | 110 | 119 | 120 | 121 | 284 | 285 | 346 | 347 | 408 | -------------------------------------------------------------------------------- /src/pages/404.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from "../layouts/Layout.astro"; 3 | 4 | import "@new-ui/foundations"; 5 | --- 6 | 7 | 12 |
    13 |
    14 | Back to Home 19 |
    20 |
    21 |
    22 | -------------------------------------------------------------------------------- /src/pages/categories/[category].astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from "../../layouts/Layout.astro"; 3 | 4 | import "@new-ui/foundations"; 5 | import Dashboard from "../../components/Dashboard"; 6 | 7 | export function getStaticPaths() { 8 | return [ 9 | {params: {category: 'all'}}, 10 | {params: {category: 'art'}}, 11 | {params: {category: 'audio'}}, 12 | {params: {category: 'code'}}, 13 | {params: {category: 'copywriting'}}, 14 | {params: {category: 'design'}}, 15 | {params: {category: 'developer'}}, 16 | {params: {category: 'education'}}, 17 | {params: {category: 'enterprise'}}, 18 | {params: {category: 'fashion'}}, 19 | {params: {category: 'gaming'}}, 20 | {params: {category: 'health'}}, 21 | {params: {category: 'legal'}}, 22 | {params: {category: 'llm'}}, 23 | {params: {category: 'music'}}, 24 | {params: {category: 'nocode'}}, 25 | {params: {category: 'photos'}}, 26 | {params: {category: 'productivity'}}, 27 | {params: {category: 'prompts'}}, 28 | {params: {category: 'research'}}, 29 | {params: {category: 'seo'}}, 30 | {params: {category: 'social'}}, 31 | {params: {category: 'xtras'}}, 32 | ]; 33 | } 34 | 35 | const { category } = Astro.params; 36 | --- 37 | 38 | 43 |
    44 | 45 |
    46 |
    -------------------------------------------------------------------------------- /src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Layout from "../layouts/Layout.astro"; 3 | 4 | import "@new-ui/foundations"; 5 | import Dashboard from "../components/Dashboard"; 6 | --- 7 | 8 | 13 |
    14 | 15 |
    16 |
    17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "jsxImportSource": "react" 6 | } 7 | } --------------------------------------------------------------------------------