refactor: 主题系统 → monorepo 五个独立网站
- packages/core: @aidir/core 底座库(src/pages 页面组件体 1:1 镜像路由树 / kit 站点外壳工厂 / content/blog / scripts) - sites/: 5 个独立 Next.js 网站(ai-stack / launchai / the-ai-ledger / devai-tools / findai) - 每站独立 package.json / next.config / tailwind / messages / .env / 构建 - src/app 约 56 个薄路由文件(re-export 底座页面 + 内联路由段配置 revalidate/dynamic) - src/site/brand.tsx 站点配置 + src/site/home.tsx 站点首页(createMarketingLayout / createHomePage 工厂) - generate-site.mjs: 站点生成器(新增网站 = SITES 加条目,零 Core 修改) - start-all-sites.sh: 一键启动 3001-3005 - next-config.mjs: 底座统一 Next 配置工厂(next-intl + MDX + standalone) - 五站共享同一套 PostgreSQL / Better Auth / Admin(设计文档 §42) - 验证: 5 站 build OK / typecheck OK / 55 路由冒烟 200 / 品牌-内容-截图 差异确认 / 登录-投票-重复检测 e2e PASS
@@ -0,0 +1,14 @@
|
||||
# AI Stack 环境变量(与底座共享同一套 PostgreSQL / Better Auth / Admin)
|
||||
DATABASE_URL="postgresql://postgres:postgres@127.0.0.1:15433/ai_directory"
|
||||
BETTER_AUTH_SECRET="dev-secret-ai-directory-platform-0123456789abcdef"
|
||||
BETTER_AUTH_URL="http://localhost:3001"
|
||||
AUTH_GOOGLE_ID=""
|
||||
AUTH_GOOGLE_SECRET=""
|
||||
NEXT_PUBLIC_AUTH_GOOGLE_ENABLED="false"
|
||||
AUTH_GITHUB_ID=""
|
||||
AUTH_GITHUB_SECRET=""
|
||||
NEXT_PUBLIC_AUTH_GITHUB_ENABLED="false"
|
||||
RESEND_API_KEY=""
|
||||
RESEND_FROM_EMAIL="AI Stack <noreply@localhost>"
|
||||
NEXT_PUBLIC_APP_URL="http://localhost:3001"
|
||||
NEXT_PUBLIC_APP_NAME="AI Stack"
|
||||
@@ -0,0 +1,5 @@
|
||||
/node_modules
|
||||
/.next
|
||||
/.env*.local
|
||||
next-env.d.ts
|
||||
*.tsbuildinfo
|
||||
@@ -0,0 +1 @@
|
||||
export { useMDXComponents } from "@aidir/core/src/mdx-components";
|
||||
@@ -0,0 +1,796 @@
|
||||
{
|
||||
"common": {
|
||||
"brand": {
|
||||
"name": "AI Stack",
|
||||
"tagline": "The professional AI tools directory — ranked by the community.",
|
||||
"copyright": "Copyright © 2025",
|
||||
"allRightsReserved": "All rights reserved"
|
||||
},
|
||||
"actions": {
|
||||
"signIn": "Sign in",
|
||||
"signUp": "Sign Up",
|
||||
"signOut": "Sign Out",
|
||||
"getStarted": "Get Started",
|
||||
"startFree": "Start Free",
|
||||
"learnMore": "Learn More",
|
||||
"viewAll": "View All",
|
||||
"submit": "Submit",
|
||||
"cancel": "Cancel",
|
||||
"save": "Save",
|
||||
"delete": "Delete",
|
||||
"edit": "Edit",
|
||||
"update": "Update",
|
||||
"continue": "Continue",
|
||||
"back": "Back",
|
||||
"next": "Next",
|
||||
"contactSales": "Contact Sales",
|
||||
"startTrial": "Start Free Trial"
|
||||
},
|
||||
"status": {
|
||||
"loading": "Loading...",
|
||||
"verified": "Verified",
|
||||
"pending": "Pending",
|
||||
"active": "Active",
|
||||
"inactive": "Inactive"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"main": {
|
||||
"tools": "Tools",
|
||||
"blog": "Blog",
|
||||
"contact": "Contact",
|
||||
"dashboard": "Dashboard",
|
||||
"profile": "Profile"
|
||||
},
|
||||
"footer": {
|
||||
"legal": {
|
||||
"terms": "Terms of Service",
|
||||
"privacy": "Privacy Policy",
|
||||
"cookies": "Cookie Policy"
|
||||
},
|
||||
"social": {
|
||||
"twitter": "Twitter",
|
||||
"linkedin": "LinkedIn",
|
||||
"github": "GitHub"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hero": {
|
||||
"badge": "Discover the Best AI Tools",
|
||||
"title": "AI Stack — Find the Best AI Tools, Ranked by Real Users",
|
||||
"description": "The professional AI tools directory. 1,000+ AI tools across 14 categories ranked by community votes, reviews and engagement.",
|
||||
"cta": {
|
||||
"primary": "Explore Tools",
|
||||
"secondary": "Read Blog"
|
||||
}
|
||||
},
|
||||
"features": {
|
||||
"title": "Everything You Need to Build Fast",
|
||||
"subtitle": "Stop wasting time on boilerplate. Focus on your unique features while this template handles the foundation.",
|
||||
"items": {
|
||||
"aiOptimized": {
|
||||
"title": "Modern Tech Stack",
|
||||
"description": "Built with Next.js 14, TypeScript, Tailwind CSS, and PostgreSQL. Production-ready from day one."
|
||||
},
|
||||
"zeroPipeline": {
|
||||
"title": "Authentication Ready",
|
||||
"description": "Email/password and Google OAuth configured. Session management and protected routes ready to use."
|
||||
},
|
||||
"nonTechnical": {
|
||||
"title": "Admin Dashboard",
|
||||
"description": "Complete admin panel for user management. Monitor your users and manage permissions easily."
|
||||
},
|
||||
"productionGrade": {
|
||||
"title": "Blog System Included",
|
||||
"description": "MDX-powered blog with i18n support. Create content in multiple languages with SEO optimization."
|
||||
}
|
||||
}
|
||||
},
|
||||
"testimonials": {
|
||||
"title": "Trusted by AI Enthusiasts",
|
||||
"subtitle": "Join thousands of users discovering the best AI tools for their workflows.",
|
||||
"items": [
|
||||
{
|
||||
"name": "Sarah Chen",
|
||||
"quote": "Toolso.AI helped me find the perfect AI writing assistant. The categorization makes discovery so easy!",
|
||||
"designation": "Content Creator"
|
||||
},
|
||||
{
|
||||
"name": "Michael Park",
|
||||
"quote": "Finally, a comprehensive AI tools directory that's well-organized. Saved me hours of research.",
|
||||
"designation": "Product Manager"
|
||||
},
|
||||
{
|
||||
"name": "Emily Rodriguez",
|
||||
"quote": "I discover new AI tools every week on Toolso.AI. It's become my go-to resource for AI exploration.",
|
||||
"designation": "Startup Founder"
|
||||
},
|
||||
{
|
||||
"name": "David Kim",
|
||||
"quote": "The search and filter features are incredibly helpful. Found exactly what I needed in minutes.",
|
||||
"designation": "Software Engineer"
|
||||
},
|
||||
{
|
||||
"name": "Lisa Wang",
|
||||
"quote": "Love the multilingual support! Makes it easy to explore AI tools in both English and Chinese.",
|
||||
"designation": "Digital Marketer"
|
||||
},
|
||||
{
|
||||
"name": "James Liu",
|
||||
"quote": "Great resource for staying up-to-date with the latest AI tools. The blog section is also very informative.",
|
||||
"designation": "AI Researcher"
|
||||
}
|
||||
]
|
||||
},
|
||||
"companies": {
|
||||
"title": "Built with Industry-Leading Technologies",
|
||||
"subtitle": "Built on modern stack trusted by the world's best teams"
|
||||
},
|
||||
"gridFeatures": {
|
||||
"aiReady": {
|
||||
"title": "Extensible Architecture",
|
||||
"description": "Clean, modular code structure. Easy to add new features and integrations."
|
||||
},
|
||||
"creem": {
|
||||
"title": "Database Ready",
|
||||
"description": "PostgreSQL with Drizzle ORM configured. Type-safe queries and migrations ready."
|
||||
},
|
||||
"auth": {
|
||||
"title": "Authentication System",
|
||||
"description": "Better Auth with email/password and OAuth. Session management and protected routes ready."
|
||||
},
|
||||
"deploy": {
|
||||
"title": "One-Click Deploy",
|
||||
"description": "Deploy to Vercel, Railway, or any platform instantly. Production-ready from day one."
|
||||
},
|
||||
"typescript": {
|
||||
"title": "TypeScript + Tailwind",
|
||||
"description": "Modern tech stack with Next.js 14, TypeScript, Tailwind CSS, and shadcn/ui components."
|
||||
},
|
||||
"database": {
|
||||
"title": "Admin Dashboard",
|
||||
"description": "Complete admin panel for user management and system monitoring."
|
||||
},
|
||||
"seo": {
|
||||
"title": "SEO & Marketing",
|
||||
"description": "Meta tags, Open Graph, sitemap, and analytics. Everything for organic growth."
|
||||
},
|
||||
"vibeCoding": {
|
||||
"title": "Blog System",
|
||||
"description": "MDX-powered blog with multi-language support. Create content that ranks."
|
||||
}
|
||||
},
|
||||
"cta": {
|
||||
"title": "Find Your Perfect AI Tool",
|
||||
"description": "Browse our curated collection of AI tools and discover what works best for you.",
|
||||
"button": "Explore Tools"
|
||||
},
|
||||
"auth": {
|
||||
"login": {
|
||||
"title": "Sign in to your account",
|
||||
"emailLabel": "Email address",
|
||||
"emailPlaceholder": "hello@example.com",
|
||||
"passwordLabel": "Password",
|
||||
"passwordPlaceholder": "••••••••",
|
||||
"forgotPassword": "Forgot password?",
|
||||
"noAccount": "Don't have an account?",
|
||||
"signUpLink": "Sign Up",
|
||||
"signInButton": "Sign in",
|
||||
"signingIn": "Signing in...",
|
||||
"errors": {
|
||||
"invalidEmail": "Please enter valid email",
|
||||
"emailRequired": "Please enter email",
|
||||
"passwordRequired": "Please enter password",
|
||||
"loginFailed": "Login failed. Please try again.",
|
||||
"googleLoginFailed": "Google login failed. Please try again."
|
||||
}
|
||||
},
|
||||
"signup": {
|
||||
"title": "Sign up for an account",
|
||||
"nameLabel": "Full name",
|
||||
"namePlaceholder": "John Doe",
|
||||
"emailLabel": "Email address",
|
||||
"emailPlaceholder": "hello@example.com",
|
||||
"passwordLabel": "Password",
|
||||
"passwordPlaceholder": "••••••••",
|
||||
"hasAccount": "Already have an account?",
|
||||
"signInLink": "Sign in",
|
||||
"signUpButton": "Sign Up",
|
||||
"signingUp": "Signing up...",
|
||||
"errors": {
|
||||
"nameRequired": "Please enter your name",
|
||||
"invalidEmail": "Please enter valid email",
|
||||
"emailRequired": "Please enter email",
|
||||
"passwordRequired": "Please enter password",
|
||||
"signupFailed": "Sign up failed. Please try again.",
|
||||
"googleSignupFailed": "Google sign up failed. Please try again."
|
||||
}
|
||||
},
|
||||
"social": {
|
||||
"googleSignIn": "Continue with Google",
|
||||
"or": "Or continue with",
|
||||
"githubSignIn": "Continue with GitHub"
|
||||
},
|
||||
"checkEmail": {
|
||||
"title": "Check Your Email",
|
||||
"description": "We've sent a verification link to your email address. Please click the link to verify your account and get started.",
|
||||
"notReceived": "Didn't receive the email?",
|
||||
"checkSpam": "Check your spam or junk folder",
|
||||
"checkEmailCorrect": "Make sure you entered the correct email",
|
||||
"waitAndCheck": "Wait a few minutes and check again",
|
||||
"resendButton": "Resend Verification Email",
|
||||
"resending": "Sending...",
|
||||
"resendSuccess": "Verification email sent successfully! Please check your inbox.",
|
||||
"resendError": "Failed to resend verification email.",
|
||||
"backToLogin": "Back to Login",
|
||||
"securityNote": "For your security, the verification link will expire in 24 hours."
|
||||
},
|
||||
"verifyEmail": {
|
||||
"verifying": "Verifying Email",
|
||||
"verifyingDescription": "Please wait while we verify your email address...",
|
||||
"success": "Email Verified!",
|
||||
"successDescription": "Your email has been successfully verified! Redirecting to login...",
|
||||
"alreadyVerified": "Already Verified",
|
||||
"failed": "Verification Failed",
|
||||
"goToLogin": "Go to Login",
|
||||
"backToSignUp": "Back to Sign Up",
|
||||
"requestNew": "Request New Verification Email",
|
||||
"checkSpamNote": "Check your spam folder if you don't see our emails"
|
||||
},
|
||||
"emailVerifiedGuard": {
|
||||
"title": "Email Verification Required",
|
||||
"description": "Please verify your email address to access this page. Check your inbox for the verification link we sent to:",
|
||||
"resendButton": "Resend Verification Email",
|
||||
"resending": "Sending...",
|
||||
"resendSuccess": "Verification email sent! Please check your inbox.",
|
||||
"resendError": "Failed to send verification email. Please try again.",
|
||||
"signOutLink": "Sign out and try a different account"
|
||||
}
|
||||
},
|
||||
"Admin": {
|
||||
"sidebar": {
|
||||
"title": "Admin Panel",
|
||||
"subtitle": "System Management",
|
||||
"dashboard": "Dashboard",
|
||||
"tools": "Tools",
|
||||
"categories": "Categories",
|
||||
"tags": "Tags",
|
||||
"users": "Users",
|
||||
"backToDashboard": "Back to User Dashboard",
|
||||
"submissions": "Submissions",
|
||||
"claims": "Claims",
|
||||
"reviews": "Reviews",
|
||||
"discovery": "Discovery",
|
||||
"votes": "Vote Audit",
|
||||
"analytics": "Analytics"
|
||||
},
|
||||
"header": {
|
||||
"welcome": "Welcome",
|
||||
"adminBadge": "Admin"
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "Admin Dashboard",
|
||||
"totalUsers": "Total Users",
|
||||
"activeUsers": "Active Users",
|
||||
"recentUsers": "Recent Users",
|
||||
"viewAllUsers": "View All Users"
|
||||
},
|
||||
"toolsManagement": {
|
||||
"title": "Tools Management",
|
||||
"totalCount": "{count} tools",
|
||||
"searchPlaceholder": "Search tool name or slug...",
|
||||
"allStatus": "All Status",
|
||||
"published": "Published",
|
||||
"draft": "Draft",
|
||||
"addTool": "Add Tool",
|
||||
"tool": "Tool",
|
||||
"slug": "Slug",
|
||||
"status": "Status",
|
||||
"createdAt": "Created",
|
||||
"actions": "Actions",
|
||||
"noData": "No tools data",
|
||||
"previous": "Previous",
|
||||
"next": "Next",
|
||||
"confirmDelete": "Are you sure you want to delete \"{name}\"? This action cannot be undone.",
|
||||
"deleted": "Tool deleted",
|
||||
"deleteFailed": "Delete failed",
|
||||
"statusUpdated": "Status updated",
|
||||
"statusUpdateFailed": "Status update failed",
|
||||
"toDraft": "Set to draft",
|
||||
"publish": "Publish",
|
||||
"edit": "Edit",
|
||||
"visitWebsite": "Visit website",
|
||||
"delete": "Delete",
|
||||
"modal": {
|
||||
"editTitle": "Edit Tool",
|
||||
"addTitle": "Add Tool",
|
||||
"basicInfo": "Basic Information",
|
||||
"linksAndImages": "Links & Images",
|
||||
"categories": "Categories",
|
||||
"tags": "Tags",
|
||||
"slug": "Slug",
|
||||
"status": "Status",
|
||||
"nameEn": "English Name",
|
||||
"nameZh": "Chinese Name",
|
||||
"descriptionEn": "English Description",
|
||||
"descriptionZh": "Chinese Description",
|
||||
"domain": "Domain",
|
||||
"websiteUrl": "Website URL",
|
||||
"logoUrl": "Logo URL",
|
||||
"coverImageUrl": "Cover Image URL",
|
||||
"cancel": "Cancel",
|
||||
"saving": "Saving...",
|
||||
"saveChanges": "Save Changes",
|
||||
"createTool": "Create Tool",
|
||||
"requiredField": "Please fill in required fields",
|
||||
"updated": "Tool updated",
|
||||
"created": "Tool created",
|
||||
"updateFailed": "Update failed",
|
||||
"createFailed": "Create failed",
|
||||
"statusDraft": "Draft",
|
||||
"statusPublished": "Published",
|
||||
"pricing": "Pricing",
|
||||
"pricingNone": "Not set",
|
||||
"pricingFree": "Free",
|
||||
"pricingFreemium": "Freemium",
|
||||
"pricingPaid": "Paid",
|
||||
"featured": "Featured on homepage"
|
||||
}
|
||||
},
|
||||
"categoriesManagement": {
|
||||
"title": "Categories Management",
|
||||
"addCategory": "Add Category",
|
||||
"order": "Order",
|
||||
"category": "Category",
|
||||
"slug": "Slug",
|
||||
"toolCount": "Tools",
|
||||
"toolCountLabel": "{count} tools",
|
||||
"actions": "Actions",
|
||||
"noData": "No categories data",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"cannotDelete": "This category has {count} tools, cannot delete",
|
||||
"confirmDelete": "Are you sure you want to delete category \"{name}\"?",
|
||||
"deleted": "Category deleted",
|
||||
"deleteFailed": "Delete failed",
|
||||
"modal": {
|
||||
"editTitle": "Edit Category",
|
||||
"addTitle": "Add Category",
|
||||
"slug": "Slug",
|
||||
"icon": "Icon (emoji)",
|
||||
"nameEn": "English Name",
|
||||
"nameZh": "Chinese Name",
|
||||
"sortOrder": "Sort Order",
|
||||
"descriptionEn": "English Description",
|
||||
"descriptionZh": "Chinese Description",
|
||||
"cancel": "Cancel",
|
||||
"saving": "Saving...",
|
||||
"saveChanges": "Save Changes",
|
||||
"createCategory": "Create Category",
|
||||
"requiredField": "Please fill in required fields",
|
||||
"updated": "Category updated",
|
||||
"created": "Category created",
|
||||
"updateFailed": "Update failed",
|
||||
"createFailed": "Create failed"
|
||||
}
|
||||
},
|
||||
"tagsManagement": {
|
||||
"title": "Tags Management",
|
||||
"searchPlaceholder": "Search tags...",
|
||||
"addTag": "Add Tag",
|
||||
"toolCountLabel": "{count} tools",
|
||||
"noData": "No tags data",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"confirmDeleteWithTools": "This tag is used by {count} tools. Deleting it will remove the tag from these tools. Continue?",
|
||||
"confirmDelete": "Are you sure you want to delete tag \"{name}\"?",
|
||||
"deleted": "Tag deleted",
|
||||
"deleteFailed": "Delete failed",
|
||||
"modal": {
|
||||
"editTitle": "Edit Tag",
|
||||
"addTitle": "Add Tag",
|
||||
"slug": "Slug",
|
||||
"nameEn": "English Name",
|
||||
"nameZh": "Chinese Name",
|
||||
"cancel": "Cancel",
|
||||
"saving": "Saving...",
|
||||
"saveChanges": "Save Changes",
|
||||
"createTag": "Create Tag",
|
||||
"requiredField": "Please fill in required fields",
|
||||
"updated": "Tag updated",
|
||||
"created": "Tag created",
|
||||
"updateFailed": "Update failed",
|
||||
"createFailed": "Create failed"
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
"searchPlaceholder": "Search by name or email...",
|
||||
"user": "User",
|
||||
"role": "Role",
|
||||
"status": "Status",
|
||||
"joined": "Joined",
|
||||
"actions": "Actions",
|
||||
"admin": "Admin",
|
||||
"banned": "Banned",
|
||||
"active": "Active",
|
||||
"unverified": "Unverified",
|
||||
"verified": "Verified",
|
||||
"emailVerified": "Email Verified",
|
||||
"edit": "Edit",
|
||||
"ban": "Ban",
|
||||
"unban": "Unban",
|
||||
"viewDetails": "View Details",
|
||||
"banReason": "Ban Reason",
|
||||
"banExpires": "Ban Expires",
|
||||
"userDetails": "User Details",
|
||||
"name": "Name",
|
||||
"email": "Email",
|
||||
"lastActive": "Last Active",
|
||||
"close": "Close",
|
||||
"roleUpdated": "Role updated successfully",
|
||||
"roleUpdateFailed": "Failed to update role",
|
||||
"userBanned": "User has been banned",
|
||||
"userUnbanned": "User has been unbanned",
|
||||
"banFailed": "Failed to ban/unban user",
|
||||
"cancel": "Cancel",
|
||||
"pagination": {
|
||||
"previous": "Previous",
|
||||
"next": "Next",
|
||||
"page": "Page {current} of {total}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "Dashboard",
|
||||
"welcome": "Welcome back",
|
||||
"cards": {
|
||||
"personalInfo": {
|
||||
"title": "Personal Info",
|
||||
"labels": {
|
||||
"name": "Name",
|
||||
"email": "Email",
|
||||
"status": "Status",
|
||||
"notSet": "Not set"
|
||||
}
|
||||
},
|
||||
"quickActions": {
|
||||
"title": "Quick Actions",
|
||||
"editProfile": "Edit Profile",
|
||||
"accountSettings": "Account Settings",
|
||||
"securitySettings": "Security Settings"
|
||||
}
|
||||
},
|
||||
"favorites": {
|
||||
"title": "My Favorites",
|
||||
"empty": "No favorite tools yet.",
|
||||
"browseTools": "Browse tools and save your favorites"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"title": "Profile",
|
||||
"subtitle": "Manage your account settings and preferences",
|
||||
"sections": {
|
||||
"basicInfo": {
|
||||
"title": "Basic Information",
|
||||
"fullName": "Full Name",
|
||||
"email": "Email Address",
|
||||
"verificationStatus": "Verification Status",
|
||||
"notSet": "Not set",
|
||||
"nameNotSet": "Name not set",
|
||||
"accountId": "Account ID"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "Account Settings",
|
||||
"memberSince": "Member Since",
|
||||
"lastLogin": "Last Login",
|
||||
"accountType": "Account Type"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"nameLabel": "Name",
|
||||
"namePlaceholder": "Enter your name",
|
||||
"emailLabel": "Email",
|
||||
"emailPlaceholder": "Enter your email",
|
||||
"updateButton": "Update Profile",
|
||||
"updating": "Updating...",
|
||||
"updateSuccess": "Profile updated successfully!",
|
||||
"updateError": "Failed to update profile. Please try again."
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"title": "Contact Us",
|
||||
"subtitle": "We'd love to hear from you. Send us a message and we'll respond as soon as possible.",
|
||||
"description": "Please reach out to us and we will get back to you shortly.",
|
||||
"testimonial": {
|
||||
"title": "We're here to help",
|
||||
"description": "Our team is ready to assist you with any questions or feedback."
|
||||
},
|
||||
"form": {
|
||||
"nameLabel": "Full Name",
|
||||
"namePlaceholder": "John Doe",
|
||||
"emailLabel": "Email address",
|
||||
"emailPlaceholder": "hello@example.com",
|
||||
"companyLabel": "Company",
|
||||
"companyPlaceholder": "Your Company",
|
||||
"messageLabel": "Message",
|
||||
"messagePlaceholder": "Enter your message here",
|
||||
"submitButton": "Submit",
|
||||
"submitting": "Sending...",
|
||||
"submitSuccess": "Message sent successfully!",
|
||||
"submitError": "Failed to send message. Please try again."
|
||||
}
|
||||
},
|
||||
"blog": {
|
||||
"title": "Blog",
|
||||
"subtitle": "Latest insights and updates from our team",
|
||||
"readMore": "Read More",
|
||||
"minRead": "min read"
|
||||
},
|
||||
"errors": {
|
||||
"404": {
|
||||
"title": "404 - Page Not Found",
|
||||
"message": "The page you are looking for doesn't exist.",
|
||||
"backHome": "Go to Homepage"
|
||||
},
|
||||
"500": {
|
||||
"title": "Something Went Wrong",
|
||||
"message": "We're experiencing technical difficulties. Please try again later.",
|
||||
"backHome": "Back to Home"
|
||||
},
|
||||
"general": {
|
||||
"title": "An Error Occurred",
|
||||
"message": "Something unexpected happened. Please try again.",
|
||||
"tryAgain": "Try Again"
|
||||
}
|
||||
},
|
||||
"featuredTestimonials": {
|
||||
"people": [
|
||||
{
|
||||
"name": "John Doe",
|
||||
"designation": "Software Engineer"
|
||||
},
|
||||
{
|
||||
"name": "Jane Smith",
|
||||
"designation": "Product Manager"
|
||||
},
|
||||
{
|
||||
"name": "Bob Johnson",
|
||||
"designation": "Designer"
|
||||
},
|
||||
{
|
||||
"name": "Alice Brown",
|
||||
"designation": "Developer"
|
||||
}
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"tagline": "Discover the best AI tools to boost your productivity.",
|
||||
"product": {
|
||||
"title": "Product",
|
||||
"features": "Features",
|
||||
"documentation": "Documentation"
|
||||
},
|
||||
"company": {
|
||||
"title": "Company",
|
||||
"about": "About",
|
||||
"blog": "Blog",
|
||||
"careers": "Careers"
|
||||
},
|
||||
"legal": {
|
||||
"title": "Legal",
|
||||
"privacy": "Privacy",
|
||||
"terms": "Terms",
|
||||
"cookies": "Cookies"
|
||||
},
|
||||
"social": {
|
||||
"title": "Social",
|
||||
"twitter": "Twitter",
|
||||
"linkedin": "LinkedIn",
|
||||
"github": "GitHub"
|
||||
},
|
||||
"newsletter": {
|
||||
"title": "Subscribe to Newsletter",
|
||||
"description": "Get the latest updates and news directly in your inbox.",
|
||||
"placeholder": "Enter your email",
|
||||
"subscribe": "Subscribe",
|
||||
"success": "Subscribed! Thanks for joining.",
|
||||
"invalidEmail": "Please enter a valid email address.",
|
||||
"error": "Subscription failed. Please try again."
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"title": "AI Tools Directory",
|
||||
"subtitle": "Discover the best AI tools to boost your productivity",
|
||||
"searchPlaceholder": "Search tools...",
|
||||
"all": "All",
|
||||
"foundTools": "Found {count} tools",
|
||||
"visitWebsite": "Visit website",
|
||||
"noTools": "No tools found",
|
||||
"backToTools": "Back to tools",
|
||||
"about": "About",
|
||||
"categories": "Categories",
|
||||
"tags": "Tags",
|
||||
"visitButton": "Visit Website",
|
||||
"toolInfo": "Tool Info",
|
||||
"domain": "Domain",
|
||||
"added": "Added",
|
||||
"notFound": "Tool Not Found",
|
||||
"favorites": {
|
||||
"add": "Save to Favorites",
|
||||
"remove": "Remove from Favorites",
|
||||
"loginRequired": "Please sign in to save favorites",
|
||||
"error": "Action failed. Please try again."
|
||||
},
|
||||
"pricing": {
|
||||
"free": "Free",
|
||||
"freemium": "Freemium",
|
||||
"paid": "Paid"
|
||||
},
|
||||
"categoryPage": {
|
||||
"viewAll": "View all {count} tools"
|
||||
},
|
||||
"reviewCta": "Ratings and reviews come from verified community members. Voted Helpful counts are shown next to each review.",
|
||||
"alternatives": "Alternatives",
|
||||
"seeAllAlternatives": "See all alternatives",
|
||||
"stats": {
|
||||
"votes": "Upvotes",
|
||||
"views": "Views"
|
||||
},
|
||||
"share": {
|
||||
"share": "Share",
|
||||
"copy": "Copy",
|
||||
"copyLink": "Copy link",
|
||||
"copied": "Link copied to clipboard"
|
||||
},
|
||||
"sort": {
|
||||
"latest": "Latest",
|
||||
"trending": "Trending"
|
||||
}
|
||||
},
|
||||
"seo": {
|
||||
"home": {
|
||||
"title": "AI Stack — Find the Best AI Tools, Ranked by Real Users",
|
||||
"description": "The professional AI tools directory. 1,000+ AI tools across 14 categories ranked by community votes, reviews and engagement.",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"blog": {
|
||||
"title": "Blog - Toolso.AI",
|
||||
"description": "Latest insights, tutorials and updates about AI tools. Stay informed about the best AI tools and industry trends.",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"contact": {
|
||||
"title": "Contact Us - Toolso.AI",
|
||||
"description": "Get in touch with us. We'd love to hear your feedback and tool suggestions.",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"login": {
|
||||
"title": "Login - Toolso.AI",
|
||||
"description": "Sign in to your account to submit tools, save favorites, and contribute to our AI tools directory.",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"signup": {
|
||||
"title": "Sign Up - Toolso.AI",
|
||||
"description": "Create your account and start contributing to our AI tools directory. Submit tools and join our community.",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"terms": {
|
||||
"title": "Terms of Service - Toolso.AI",
|
||||
"description": "Read our terms of service to understand the rules and guidelines for using Toolso.AI.",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"privacy": {
|
||||
"title": "Privacy Policy - Toolso.AI",
|
||||
"description": "Learn how we collect, use, and protect your personal information and data on Toolso.AI.",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"cookies": {
|
||||
"title": "Cookie Policy - Toolso.AI",
|
||||
"description": "Understand how we use cookies and similar tracking technologies on Toolso.AI.",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"tools": {
|
||||
"title": "AI Tools Directory - Discover the Best AI Tools",
|
||||
"description": "Explore our curated collection of AI tools. Find the best AI tools for productivity, creativity, and more."
|
||||
}
|
||||
},
|
||||
"featuredTools": {
|
||||
"title": "Featured Tools",
|
||||
"subtitle": "Curated collection of AI tools to boost your productivity",
|
||||
"visitWebsite": "Visit website",
|
||||
"empty": "No tools yet. Add some in the admin panel.",
|
||||
"viewAll": "View All Tools"
|
||||
},
|
||||
"voting": {
|
||||
"vote": "Upvote",
|
||||
"voted": "Upvoted",
|
||||
"unvote": "Remove vote",
|
||||
"loginRequired": "Please sign in to vote — you'll be brought right back.",
|
||||
"rateLimited": "Slow down a bit — too many votes in a short time.",
|
||||
"error": "Vote failed. Please try again."
|
||||
},
|
||||
"reviews": {
|
||||
"title": "Reviews",
|
||||
"writeReview": "Write a review",
|
||||
"empty": "No reviews yet — be the first to share your experience.",
|
||||
"loadMore": "Load more",
|
||||
"loading": "Loading...",
|
||||
"helpful": "Helpful",
|
||||
"verifiedUser": "Verified user",
|
||||
"pros": "Pros",
|
||||
"cons": "Cons",
|
||||
"yourRating": "Your rating",
|
||||
"ratingRequired": "Please pick a star rating first.",
|
||||
"titlePlaceholder": "Sum it up in one line (optional)",
|
||||
"contentPlaceholder": "What did you use it for? How well does it work?",
|
||||
"prosPlaceholder": "What do you like about it?",
|
||||
"consPlaceholder": "What could be better?",
|
||||
"useCasePlaceholder": "Your use case (e.g. social media content)",
|
||||
"saving": "Saving...",
|
||||
"submit": "Publish review",
|
||||
"update": "Update review",
|
||||
"cancel": "Cancel",
|
||||
"delete": "Delete my review",
|
||||
"deleted": "Review deleted",
|
||||
"tooShort": "Review is a bit short — tell us at least a sentence.",
|
||||
"error": "Could not save your review. Please try again.",
|
||||
"basedOn": "Based on {count} reviews"
|
||||
},
|
||||
"submission": {
|
||||
"name": "Tool name",
|
||||
"websiteUrl": "Website URL",
|
||||
"tagline": "Tagline",
|
||||
"taglinePlaceholder": "One-line pitch shown on cards",
|
||||
"description": "Description",
|
||||
"descriptionPlaceholder": "What does it do? Who is it for? What makes it different?",
|
||||
"logoUrl": "Logo URL",
|
||||
"category": "Category",
|
||||
"pricingLabel": "Pricing model",
|
||||
"pricing": {
|
||||
"free": "Free",
|
||||
"freemium": "Freemium",
|
||||
"paid": "Paid",
|
||||
"freeTrial": "Free Trial",
|
||||
"openSource": "Open Source",
|
||||
"contact": "Contact for pricing"
|
||||
},
|
||||
"founderName": "Founder / company",
|
||||
"contactEmail": "Contact email",
|
||||
"socialLinks": "Social links",
|
||||
"note": "Notes for the editors",
|
||||
"notePlaceholder": "Anything that helps us review faster (launch date, metrics...)",
|
||||
"selectPlaceholder": "Select...",
|
||||
"submit": "Submit for review",
|
||||
"submitting": "Submitting...",
|
||||
"submitted": "Submitted! We'll review it within 48 hours.",
|
||||
"reviewNote": "Free listing · reviewed within 48h",
|
||||
"duplicateFound": "Looks like this tool may already be listed:",
|
||||
"duplicateBlocked": "This tool appears to be already listed. Duplicate submissions are not allowed.",
|
||||
"error": "Submission failed. Please check your inputs."
|
||||
},
|
||||
"claim": {
|
||||
"claimThisTool": "Claim this tool",
|
||||
"verifiedOwner": "Verified owner",
|
||||
"formTitle": "Claim ownership of this listing",
|
||||
"rolePlaceholder": "Your role (e.g. Founder, Marketing lead)",
|
||||
"messagePlaceholder": "How should we verify you? (same-domain email, press page...)",
|
||||
"proofPlaceholder": "Proof URL (optional)",
|
||||
"submit": "Send claim",
|
||||
"submitting": "Sending...",
|
||||
"submitted": "Claim sent! We'll review it shortly.",
|
||||
"pendingExists": "You already have a pending claim for this tool.",
|
||||
"cancel": "Cancel",
|
||||
"error": "Could not send your claim."
|
||||
},
|
||||
"rankings": {
|
||||
"title": "Community Rankings",
|
||||
"subtitle": "Seven live leaderboards powered by votes, reviews, saves and engagement — not sponsored placement.",
|
||||
"trending": "Trending",
|
||||
"popular": "Popular",
|
||||
"mostVoted": "Most Voted",
|
||||
"mostSaved": "Most Saved",
|
||||
"highestRated": "Highest Rated",
|
||||
"new": "New",
|
||||
"editorsChoice": "Editor's Choice",
|
||||
"empty": "No tools on this board yet."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,804 @@
|
||||
{
|
||||
"common": {
|
||||
"brand": {
|
||||
"name": "AI Stack",
|
||||
"tagline": "The professional AI tools directory — ranked by the community.",
|
||||
"copyright": "版权所有 © 2025",
|
||||
"allRightsReserved": "保留所有权利"
|
||||
},
|
||||
"actions": {
|
||||
"signIn": "登录",
|
||||
"signUp": "注册",
|
||||
"signOut": "退出登录",
|
||||
"getStarted": "开始使用",
|
||||
"startFree": "免费开始",
|
||||
"startTrial": "开始试用",
|
||||
"contactSales": "联系销售",
|
||||
"learnMore": "了解更多",
|
||||
"viewAll": "查看全部",
|
||||
"submit": "提交",
|
||||
"cancel": "取消",
|
||||
"save": "保存",
|
||||
"delete": "删除",
|
||||
"edit": "编辑",
|
||||
"update": "更新",
|
||||
"continue": "继续",
|
||||
"back": "返回",
|
||||
"next": "下一步"
|
||||
},
|
||||
"status": {
|
||||
"loading": "加载中...",
|
||||
"verified": "已验证",
|
||||
"pending": "待处理",
|
||||
"active": "已激活",
|
||||
"inactive": "未激活"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"main": {
|
||||
"tools": "工具库",
|
||||
"blog": "博客",
|
||||
"contact": "联系我们",
|
||||
"dashboard": "仪表盘",
|
||||
"profile": "个人资料"
|
||||
},
|
||||
"footer": {
|
||||
"legal": {
|
||||
"terms": "服务条款",
|
||||
"privacy": "隐私政策",
|
||||
"cookies": "Cookie 政策"
|
||||
},
|
||||
"social": {
|
||||
"twitter": "Twitter",
|
||||
"linkedin": "领英",
|
||||
"github": "GitHub"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hero": {
|
||||
"badge": "发现最好的 AI 工具",
|
||||
"title": "AI Stack — 由真实用户排名的 AI 工具目录",
|
||||
"description": "专业 AI 工具导航:14 个分类、1000+ 工具,由社区投票、评论与互动数据实时排名。",
|
||||
"cta": {
|
||||
"primary": "探索工具",
|
||||
"secondary": "阅读博客"
|
||||
}
|
||||
},
|
||||
"features": {
|
||||
"title": "开始构建所需的一切",
|
||||
"subtitle": "告别重复的样板代码。专注于你的独特功能,基础设施已为你准备就绪。",
|
||||
"items": {
|
||||
"aiOptimized": {
|
||||
"title": "现代技术栈",
|
||||
"description": "基于 Next.js 14、TypeScript、Tailwind CSS 和 PostgreSQL 构建。采用行业最佳实践和企业级架构。"
|
||||
},
|
||||
"zeroPipeline": {
|
||||
"title": "开箱即用的认证",
|
||||
"description": "Better Auth 驱动的完整认证系统,支持邮箱密码和 OAuth 登录、邮箱验证、密码重置和会话管理。"
|
||||
},
|
||||
"nonTechnical": {
|
||||
"title": "管理后台",
|
||||
"description": "功能齐全的管理面板,包含用户管理、角色权限控制和业务数据监控。轻松扩展满足你的需求。"
|
||||
},
|
||||
"productionGrade": {
|
||||
"title": "博客系统",
|
||||
"description": "内置 MDX 博客系统,支持语法高亮、SEO 优化和国际化。非常适合内容营销和产品更新。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"testimonials": {
|
||||
"title": "用户评价",
|
||||
"subtitle": "来自使用 Toolso.AI 发现优质 AI 工具的真实用户反馈。",
|
||||
"items": [
|
||||
{
|
||||
"name": "张伟",
|
||||
"quote": "Toolso.AI 帮我找到了完美的 AI 写作助手,分类清晰让发现变得非常简单!",
|
||||
"designation": "内容创作者"
|
||||
},
|
||||
{
|
||||
"name": "王强",
|
||||
"quote": "终于有了一个组织良好的 AI 工具目录,节省了我大量的研究时间。",
|
||||
"designation": "产品经理"
|
||||
},
|
||||
{
|
||||
"name": "李娜",
|
||||
"quote": "每周都能在 Toolso.AI 上发现新的 AI 工具,已经成为我探索 AI 的首选资源。",
|
||||
"designation": "创业者"
|
||||
},
|
||||
{
|
||||
"name": "陈婷",
|
||||
"quote": "搜索和筛选功能非常好用,几分钟就找到了我需要的工具。",
|
||||
"designation": "软件工程师"
|
||||
},
|
||||
{
|
||||
"name": "赵明",
|
||||
"quote": "喜欢中英文双语支持!可以轻松探索各种 AI 工具。",
|
||||
"designation": "数字营销专家"
|
||||
},
|
||||
{
|
||||
"name": "朱悦",
|
||||
"quote": "了解最新 AI 工具的好资源,博客板块也很有价值。",
|
||||
"designation": "AI 研究员"
|
||||
}
|
||||
]
|
||||
},
|
||||
"companies": {
|
||||
"title": "采用行业领先技术构建",
|
||||
"subtitle": "基于现代技术栈,被全球顶尖团队信赖"
|
||||
},
|
||||
"gridFeatures": {
|
||||
"aiReady": {
|
||||
"title": "可扩展架构",
|
||||
"description": "模块化设计,轻松添加新功能。遵循 Next.js 最佳实践,便于维护。"
|
||||
},
|
||||
"creem": {
|
||||
"title": "邮件系统",
|
||||
"description": "集成 Resend 邮件服务,支持交易邮件、验证邮件和新闻通讯。"
|
||||
},
|
||||
"auth": {
|
||||
"title": "身份认证",
|
||||
"description": "Better Auth 提供邮箱密码和 OAuth 支持。会话管理和路由保护已就绪。"
|
||||
},
|
||||
"deploy": {
|
||||
"title": "一键部署",
|
||||
"description": "即刻部署到 Vercel、Railway 或任何平台。从第一天起即可投入生产。"
|
||||
},
|
||||
"typescript": {
|
||||
"title": "TypeScript + Tailwind",
|
||||
"description": "现代技术栈包括 Next.js 14、TypeScript、Tailwind CSS 和 shadcn/ui 组件。"
|
||||
},
|
||||
"database": {
|
||||
"title": "数据库 + ORM",
|
||||
"description": "PostgreSQL 配合 Drizzle ORM。类型安全的查询和迁移已配置。"
|
||||
},
|
||||
"seo": {
|
||||
"title": "SEO 和营销",
|
||||
"description": "元标签、Open Graph、站点地图和分析。为有机增长准备的一切。"
|
||||
},
|
||||
"vibeCoding": {
|
||||
"title": "国际化支持",
|
||||
"description": "内置中英文支持,使用 next-intl 实现。轻松添加更多语言。"
|
||||
}
|
||||
},
|
||||
"cta": {
|
||||
"title": "找到最适合你的 AI 工具",
|
||||
"description": "浏览精选 AI 工具集合,发现能帮助你提升效率的最佳工具。",
|
||||
"button": "探索工具"
|
||||
},
|
||||
"auth": {
|
||||
"login": {
|
||||
"title": "登录您的账户",
|
||||
"emailLabel": "邮箱地址",
|
||||
"emailPlaceholder": "hello@example.com",
|
||||
"passwordLabel": "密码",
|
||||
"passwordPlaceholder": "••••••••",
|
||||
"forgotPassword": "忘记密码?",
|
||||
"noAccount": "还没有账户?",
|
||||
"signUpLink": "注册",
|
||||
"signInButton": "登录",
|
||||
"signingIn": "登录中...",
|
||||
"errors": {
|
||||
"invalidEmail": "请输入有效的邮箱地址",
|
||||
"emailRequired": "请输入邮箱地址",
|
||||
"passwordRequired": "请输入密码",
|
||||
"loginFailed": "登录失败,请重试。",
|
||||
"googleLoginFailed": "Google 登录失败,请重试。"
|
||||
}
|
||||
},
|
||||
"signup": {
|
||||
"title": "注册一个新账户",
|
||||
"nameLabel": "姓名",
|
||||
"namePlaceholder": "张三",
|
||||
"emailLabel": "邮箱地址",
|
||||
"emailPlaceholder": "hello@example.com",
|
||||
"passwordLabel": "密码",
|
||||
"passwordPlaceholder": "••••••••",
|
||||
"hasAccount": "已经有账户了?",
|
||||
"signInLink": "登录",
|
||||
"signUpButton": "注册",
|
||||
"signingUp": "注册中...",
|
||||
"errors": {
|
||||
"nameRequired": "请输入您的姓名",
|
||||
"invalidEmail": "请输入有效的邮箱地址",
|
||||
"emailRequired": "请输入邮箱地址",
|
||||
"passwordRequired": "请输入密码",
|
||||
"signupFailed": "注册失败,请重试。",
|
||||
"googleSignupFailed": "Google 注册失败,请重试。"
|
||||
}
|
||||
},
|
||||
"social": {
|
||||
"googleSignIn": "使用 Google 继续",
|
||||
"or": "或者继续使用",
|
||||
"githubSignIn": "使用 GitHub 登录"
|
||||
},
|
||||
"checkEmail": {
|
||||
"title": "请查收您的邮件",
|
||||
"description": "我们已向您的邮箱发送了验证链接。请点击链接验证您的账户并开始使用。",
|
||||
"notReceived": "没有收到邮件?",
|
||||
"checkSpam": "检查垃圾邮件文件夹",
|
||||
"checkEmailCorrect": "确认输入的邮箱地址是否正确",
|
||||
"waitAndCheck": "等待几分钟后再次查看",
|
||||
"resendButton": "重新发送验证邮件",
|
||||
"resending": "发送中...",
|
||||
"resendSuccess": "验证邮件发送成功!请查收您的邮箱。",
|
||||
"resendError": "发送验证邮件失败,请重试。",
|
||||
"backToLogin": "返回登录",
|
||||
"securityNote": "为了您的安全,验证链接将在24小时后失效。"
|
||||
},
|
||||
"verifyEmail": {
|
||||
"verifying": "正在验证邮箱",
|
||||
"verifyingDescription": "请稍候,我们正在验证您的邮箱地址...",
|
||||
"success": "邮箱验证成功!",
|
||||
"successDescription": "您的邮箱已成功验证!正在跳转到登录页面...",
|
||||
"alreadyVerified": "已验证",
|
||||
"failed": "验证失败",
|
||||
"goToLogin": "前往登录",
|
||||
"backToSignUp": "返回注册",
|
||||
"requestNew": "重新发送验证邮件",
|
||||
"checkSpamNote": "如果没有收到邮件,请检查垃圾邮件文件夹"
|
||||
},
|
||||
"emailVerifiedGuard": {
|
||||
"title": "需要验证邮箱",
|
||||
"description": "请验证您的邮箱地址以访问此页面。请查收我们发送到以下邮箱的验证链接:",
|
||||
"resendButton": "重新发送验证邮件",
|
||||
"resending": "发送中...",
|
||||
"resendSuccess": "验证邮件已发送!请查收您的邮箱。",
|
||||
"resendError": "发送验证邮件失败,请重试。",
|
||||
"signOutLink": "退出并使用其他账户"
|
||||
}
|
||||
},
|
||||
"Admin": {
|
||||
"sidebar": {
|
||||
"title": "管理后台",
|
||||
"subtitle": "系统管理",
|
||||
"dashboard": "仪表板",
|
||||
"tools": "工具管理",
|
||||
"categories": "分类管理",
|
||||
"tags": "标签管理",
|
||||
"users": "用户管理",
|
||||
"backToDashboard": "返回用户面板",
|
||||
"submissions": "提交审核",
|
||||
"claims": "认领审核",
|
||||
"reviews": "评论审核",
|
||||
"discovery": "发现管理",
|
||||
"votes": "投票审计",
|
||||
"analytics": "数据分析"
|
||||
},
|
||||
"header": {
|
||||
"welcome": "欢迎",
|
||||
"adminBadge": "管理员"
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "管理员仪表板",
|
||||
"totalUsers": "总用户数",
|
||||
"activeUsers": "活跃用户",
|
||||
"recentUsers": "最近注册用户",
|
||||
"viewAllUsers": "查看所有用户"
|
||||
},
|
||||
"toolsManagement": {
|
||||
"title": "工具管理",
|
||||
"totalCount": "共 {count} 个工具",
|
||||
"searchPlaceholder": "搜索工具名称或 slug...",
|
||||
"allStatus": "全部状态",
|
||||
"published": "已发布",
|
||||
"draft": "草稿",
|
||||
"addTool": "添加工具",
|
||||
"tool": "工具",
|
||||
"slug": "Slug",
|
||||
"status": "状态",
|
||||
"createdAt": "创建时间",
|
||||
"actions": "操作",
|
||||
"noData": "暂无工具数据",
|
||||
"previous": "上一页",
|
||||
"next": "下一页",
|
||||
"confirmDelete": "确定要删除工具 \"{name}\" 吗?此操作不可恢复。",
|
||||
"deleted": "工具已删除",
|
||||
"deleteFailed": "删除失败",
|
||||
"statusUpdated": "状态已更新",
|
||||
"statusUpdateFailed": "状态更新失败",
|
||||
"toDraft": "转为草稿",
|
||||
"publish": "发布",
|
||||
"edit": "编辑",
|
||||
"visitWebsite": "访问网站",
|
||||
"delete": "删除",
|
||||
"modal": {
|
||||
"editTitle": "编辑工具",
|
||||
"addTitle": "添加工具",
|
||||
"basicInfo": "基本信息",
|
||||
"linksAndImages": "链接和图片",
|
||||
"categories": "分类",
|
||||
"tags": "标签",
|
||||
"slug": "Slug",
|
||||
"status": "状态",
|
||||
"nameEn": "英文名称",
|
||||
"nameZh": "中文名称",
|
||||
"descriptionEn": "英文描述",
|
||||
"descriptionZh": "中文描述",
|
||||
"domain": "域名",
|
||||
"websiteUrl": "网站链接",
|
||||
"logoUrl": "Logo URL",
|
||||
"coverImageUrl": "封面图 URL",
|
||||
"cancel": "取消",
|
||||
"saving": "保存中...",
|
||||
"saveChanges": "保存更改",
|
||||
"createTool": "创建工具",
|
||||
"requiredField": "请填写必填字段",
|
||||
"updated": "工具已更新",
|
||||
"created": "工具已创建",
|
||||
"updateFailed": "更新失败",
|
||||
"createFailed": "创建失败",
|
||||
"statusDraft": "草稿",
|
||||
"statusPublished": "已发布",
|
||||
"pricing": "定价",
|
||||
"pricingNone": "未设置",
|
||||
"pricingFree": "免费",
|
||||
"pricingFreemium": "免费增值",
|
||||
"pricingPaid": "付费",
|
||||
"featured": "首页精选"
|
||||
}
|
||||
},
|
||||
"categoriesManagement": {
|
||||
"title": "分类管理",
|
||||
"addCategory": "添加分类",
|
||||
"order": "排序",
|
||||
"category": "分类",
|
||||
"slug": "Slug",
|
||||
"toolCount": "工具数",
|
||||
"toolCountLabel": "{count} 个工具",
|
||||
"actions": "操作",
|
||||
"noData": "暂无分类数据",
|
||||
"edit": "编辑",
|
||||
"delete": "删除",
|
||||
"cannotDelete": "该分类下有 {count} 个工具,无法删除",
|
||||
"confirmDelete": "确定要删除分类 \"{name}\" 吗?",
|
||||
"deleted": "分类已删除",
|
||||
"deleteFailed": "删除失败",
|
||||
"modal": {
|
||||
"editTitle": "编辑分类",
|
||||
"addTitle": "添加分类",
|
||||
"slug": "Slug",
|
||||
"icon": "图标 (emoji)",
|
||||
"nameEn": "英文名称",
|
||||
"nameZh": "中文名称",
|
||||
"sortOrder": "排序",
|
||||
"descriptionEn": "英文描述",
|
||||
"descriptionZh": "中文描述",
|
||||
"cancel": "取消",
|
||||
"saving": "保存中...",
|
||||
"saveChanges": "保存更改",
|
||||
"createCategory": "创建分类",
|
||||
"requiredField": "请填写必填字段",
|
||||
"updated": "分类已更新",
|
||||
"created": "分类已创建",
|
||||
"updateFailed": "更新失败",
|
||||
"createFailed": "创建失败"
|
||||
}
|
||||
},
|
||||
"tagsManagement": {
|
||||
"title": "标签管理",
|
||||
"searchPlaceholder": "搜索标签...",
|
||||
"addTag": "添加标签",
|
||||
"toolCountLabel": "{count} 个工具",
|
||||
"noData": "暂无标签数据",
|
||||
"edit": "编辑",
|
||||
"delete": "删除",
|
||||
"confirmDeleteWithTools": "该标签被 {count} 个工具使用,删除后这些工具将失去该标签。确定要删除吗?",
|
||||
"confirmDelete": "确定要删除标签 \"{name}\" 吗?",
|
||||
"deleted": "标签已删除",
|
||||
"deleteFailed": "删除失败",
|
||||
"modal": {
|
||||
"editTitle": "编辑标签",
|
||||
"addTitle": "添加标签",
|
||||
"slug": "Slug",
|
||||
"nameEn": "英文名称",
|
||||
"nameZh": "中文名称",
|
||||
"cancel": "取消",
|
||||
"saving": "保存中...",
|
||||
"saveChanges": "保存更改",
|
||||
"createTag": "创建标签",
|
||||
"requiredField": "请填写必填字段",
|
||||
"updated": "标签已更新",
|
||||
"created": "标签已创建",
|
||||
"updateFailed": "更新失败",
|
||||
"createFailed": "创建失败"
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
"searchPlaceholder": "搜索用户姓名或邮箱...",
|
||||
"user": "用户",
|
||||
"role": "角色",
|
||||
"status": "状态",
|
||||
"joined": "加入时间",
|
||||
"actions": "操作",
|
||||
"admin": "管理员",
|
||||
"banned": "已禁用",
|
||||
"active": "活跃",
|
||||
"unverified": "未验证",
|
||||
"edit": "编辑",
|
||||
"ban": "禁用",
|
||||
"unban": "解禁",
|
||||
"viewDetails": "查看详情",
|
||||
"banReason": "禁用原因",
|
||||
"banExpires": "禁用到期",
|
||||
"userDetails": "用户详情",
|
||||
"name": "姓名",
|
||||
"email": "邮箱",
|
||||
"emailVerified": "邮箱验证",
|
||||
"verified": "已验证",
|
||||
"lastActive": "最后活跃",
|
||||
"close": "关闭",
|
||||
"roleUpdated": "角色已更新",
|
||||
"roleUpdateFailed": "角色更新失败",
|
||||
"userBanned": "用户已禁用",
|
||||
"userUnbanned": "用户已解禁",
|
||||
"banFailed": "禁用操作失败",
|
||||
"pagination": {
|
||||
"previous": "上一页",
|
||||
"next": "下一页",
|
||||
"page": "第 {current} / {total} 页"
|
||||
},
|
||||
"cancel": "取消"
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "仪表盘",
|
||||
"welcome": "欢迎回来",
|
||||
"cards": {
|
||||
"personalInfo": {
|
||||
"title": "个人信息",
|
||||
"labels": {
|
||||
"name": "姓名",
|
||||
"email": "邮箱",
|
||||
"status": "状态",
|
||||
"notSet": "未设置"
|
||||
}
|
||||
},
|
||||
"quickActions": {
|
||||
"title": "快捷操作",
|
||||
"editProfile": "编辑个人资料",
|
||||
"accountSettings": "账户设置",
|
||||
"securitySettings": "安全设置"
|
||||
}
|
||||
},
|
||||
"favorites": {
|
||||
"title": "我的收藏",
|
||||
"empty": "还没有收藏的工具。",
|
||||
"browseTools": "去浏览工具并收藏"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"title": "个人资料",
|
||||
"subtitle": "管理您的账户设置和偏好",
|
||||
"sections": {
|
||||
"basicInfo": {
|
||||
"title": "基本信息",
|
||||
"fullName": "姓名",
|
||||
"email": "邮箱地址",
|
||||
"verificationStatus": "验证状态",
|
||||
"notSet": "未设置",
|
||||
"nameNotSet": "姓名未设置",
|
||||
"accountId": "账户 ID"
|
||||
},
|
||||
"accountSettings": {
|
||||
"title": "账户详情",
|
||||
"memberSince": "注册于",
|
||||
"lastLogin": "最近登录",
|
||||
"accountType": "账户类型"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"nameLabel": "姓名",
|
||||
"namePlaceholder": "请输入您的姓名",
|
||||
"emailLabel": "邮箱",
|
||||
"emailPlaceholder": "请输入您的邮箱地址",
|
||||
"updateButton": "更新资料",
|
||||
"updating": "更新中...",
|
||||
"updateSuccess": "个人资料更新成功",
|
||||
"updateError": "个人资料更新失败"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"title": "联系我们",
|
||||
"subtitle": "我们很乐意倾听您的声音。给我们发送消息,我们会尽快回复。",
|
||||
"description": "请联系我们,我们会尽快回复。",
|
||||
"testimonial": {
|
||||
"title": "帮助用户发现最佳 AI 工具",
|
||||
"description": "Toolso.AI 致力于为用户提供精选的 AI 工具目录,帮助大家找到最适合的 AI 助手。"
|
||||
},
|
||||
"form": {
|
||||
"nameLabel": "姓名",
|
||||
"namePlaceholder": "张三",
|
||||
"emailLabel": "邮箱地址",
|
||||
"emailPlaceholder": "hello@example.com",
|
||||
"companyLabel": "公司",
|
||||
"companyPlaceholder": "某某科技有限公司",
|
||||
"messageLabel": "消息",
|
||||
"messagePlaceholder": "请在此处输入您的消息",
|
||||
"submitButton": "提交",
|
||||
"submitting": "发送中...",
|
||||
"submitSuccess": "消息发送成功!",
|
||||
"submitError": "消息发送失败,请重试。"
|
||||
}
|
||||
},
|
||||
"blog": {
|
||||
"title": "博客",
|
||||
"subtitle": "来自我们团队的最新见解与更新",
|
||||
"readMore": "阅读更多",
|
||||
"minRead": "分钟阅读"
|
||||
},
|
||||
"errors": {
|
||||
"404": {
|
||||
"title": "404 - 页面未找到",
|
||||
"message": "您正在寻找的页面不存在。",
|
||||
"backHome": "返回首页"
|
||||
},
|
||||
"500": {
|
||||
"title": "出错了",
|
||||
"message": "我们遇到了一些技术问题,请稍后重试。",
|
||||
"backHome": "返回首页"
|
||||
},
|
||||
"general": {
|
||||
"title": "发生错误",
|
||||
"message": "发生了一些意外情况,请重试。",
|
||||
"tryAgain": "重试"
|
||||
}
|
||||
},
|
||||
"featuredTestimonials": {
|
||||
"people": [
|
||||
{
|
||||
"name": "张伟",
|
||||
"designation": "软件工程师"
|
||||
},
|
||||
{
|
||||
"name": "王强",
|
||||
"designation": "产品经理"
|
||||
},
|
||||
{
|
||||
"name": "李娜",
|
||||
"designation": "数据科学家"
|
||||
},
|
||||
{
|
||||
"name": "陈婷",
|
||||
"designation": "UX设计师"
|
||||
},
|
||||
{
|
||||
"name": "赵明",
|
||||
"designation": "全栈开发者"
|
||||
},
|
||||
{
|
||||
"name": "朱悦",
|
||||
"designation": "独立开发者"
|
||||
}
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"tagline": "发现最好的 AI 工具,提升你的工作效率。",
|
||||
"product": {
|
||||
"title": "产品",
|
||||
"features": "功能",
|
||||
"documentation": "文档"
|
||||
},
|
||||
"company": {
|
||||
"title": "公司",
|
||||
"about": "关于我们",
|
||||
"blog": "博客",
|
||||
"careers": "招聘"
|
||||
},
|
||||
"legal": {
|
||||
"title": "法律",
|
||||
"privacy": "隐私政策",
|
||||
"terms": "服务条款",
|
||||
"cookies": "Cookie 政策"
|
||||
},
|
||||
"social": {
|
||||
"title": "社交",
|
||||
"twitter": "Twitter",
|
||||
"linkedin": "领英",
|
||||
"github": "GitHub"
|
||||
},
|
||||
"newsletter": {
|
||||
"title": "订阅邮件",
|
||||
"description": "获取最新动态和资讯,直接发送到您的邮箱。",
|
||||
"placeholder": "输入您的邮箱",
|
||||
"subscribe": "订阅",
|
||||
"success": "订阅成功!感谢加入。",
|
||||
"invalidEmail": "请输入有效的邮箱地址。",
|
||||
"error": "订阅失败,请重试。"
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"title": "AI 工具库",
|
||||
"subtitle": "发现最好的 AI 工具,提升您的工作效率",
|
||||
"searchPlaceholder": "搜索工具...",
|
||||
"all": "全部",
|
||||
"foundTools": "共找到 {count} 个工具",
|
||||
"visitWebsite": "访问网站",
|
||||
"noTools": "暂无工具",
|
||||
"backToTools": "返回工具列表",
|
||||
"about": "介绍",
|
||||
"categories": "分类",
|
||||
"tags": "标签",
|
||||
"visitButton": "访问网站",
|
||||
"toolInfo": "工具信息",
|
||||
"domain": "域名",
|
||||
"added": "添加时间",
|
||||
"notFound": "工具未找到",
|
||||
"favorites": {
|
||||
"add": "收藏",
|
||||
"remove": "取消收藏",
|
||||
"loginRequired": "请先登录后再收藏",
|
||||
"error": "操作失败,请重试。"
|
||||
},
|
||||
"pricing": {
|
||||
"free": "免费",
|
||||
"freemium": "免费增值",
|
||||
"paid": "付费"
|
||||
},
|
||||
"categoryPage": {
|
||||
"viewAll": "查看该分类全部 {count} 个工具"
|
||||
},
|
||||
"reviewCta": "评分与评论来自已验证的社区用户,每条评论旁展示“有用”计数。",
|
||||
"alternatives": "替代品",
|
||||
"seeAllAlternatives": "查看全部替代品",
|
||||
"stats": {
|
||||
"votes": "票数",
|
||||
"views": "浏览量"
|
||||
},
|
||||
"share": {
|
||||
"share": "分享",
|
||||
"copy": "复制",
|
||||
"copyLink": "复制链接",
|
||||
"copied": "链接已复制"
|
||||
},
|
||||
"sort": {
|
||||
"latest": "最新",
|
||||
"trending": "最热"
|
||||
}
|
||||
},
|
||||
"seo": {
|
||||
"home": {
|
||||
"title": "AI Stack — 由真实用户排名的 AI 工具目录",
|
||||
"description": "专业 AI 工具导航:14 个分类、1000+ 工具,由社区投票、评论与互动数据实时排名。",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"blog": {
|
||||
"title": "博客 - Toolso.AI",
|
||||
"description": "关于 AI 工具的最新资讯、教程和更新。了解最佳 AI 工具和行业趋势。",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"contact": {
|
||||
"title": "联系我们 - Toolso.AI",
|
||||
"description": "与我们取得联系。我们期待听到您的反馈和工具推荐建议。",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"login": {
|
||||
"title": "登录 - Toolso.AI",
|
||||
"description": "登录您的账户,提交工具、收藏喜爱的工具,为 AI 工具目录做贡献。",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"signup": {
|
||||
"title": "注册 - Toolso.AI",
|
||||
"description": "创建您的账户,开始为 AI 工具目录做贡献。提交工具、加入我们的社区。",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"terms": {
|
||||
"title": "服务条款 - Toolso.AI",
|
||||
"description": "阅读我们的服务条款,了解使用 Toolso.AI 的规则和指南。",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"privacy": {
|
||||
"title": "隐私政策 - Toolso.AI",
|
||||
"description": "了解我们如何在 Toolso.AI 上收集、使用和保护您的个人信息和数据。",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"cookies": {
|
||||
"title": "Cookie 政策 - Toolso.AI",
|
||||
"description": "了解我们如何在 Toolso.AI 上使用 cookies 和类似的跟踪技术。",
|
||||
"ogImage": "https://toolso.ai/banner.png"
|
||||
},
|
||||
"tools": {
|
||||
"title": "AI 工具库 - 发现最好的 AI 工具",
|
||||
"description": "浏览精选的 AI 工具集合。找到提升效率、激发创意的最佳 AI 工具。"
|
||||
}
|
||||
},
|
||||
"featuredTools": {
|
||||
"title": "精选工具",
|
||||
"subtitle": "精选优质 AI 工具,助力提升工作效率",
|
||||
"visitWebsite": "访问网站",
|
||||
"empty": "暂无工具,请先在后台添加",
|
||||
"viewAll": "查看全部工具"
|
||||
},
|
||||
"voting": {
|
||||
"vote": "投票",
|
||||
"voted": "已投",
|
||||
"unvote": "取消投票",
|
||||
"loginRequired": "投票需要先登录,登录后会自动回到本页。",
|
||||
"rateLimited": "操作太快了,请稍后再试。",
|
||||
"error": "投票失败,请重试。"
|
||||
},
|
||||
"reviews": {
|
||||
"title": "用户评论",
|
||||
"writeReview": "写评论",
|
||||
"empty": "还没有评论——来分享你的使用体验吧。",
|
||||
"loadMore": "加载更多",
|
||||
"loading": "加载中...",
|
||||
"helpful": "有用",
|
||||
"verifiedUser": "已验证用户",
|
||||
"pros": "优点",
|
||||
"cons": "缺点",
|
||||
"yourRating": "你的评分",
|
||||
"ratingRequired": "请先选择星级评分。",
|
||||
"titlePlaceholder": "一句话总结(可选)",
|
||||
"contentPlaceholder": "你用它做什么?效果如何?",
|
||||
"prosPlaceholder": "它哪里做得好?",
|
||||
"consPlaceholder": "哪里还可以改进?",
|
||||
"useCasePlaceholder": "你的使用场景(如 社媒内容创作)",
|
||||
"saving": "保存中...",
|
||||
"submit": "发布评论",
|
||||
"update": "更新评论",
|
||||
"cancel": "取消",
|
||||
"delete": "删除我的评论",
|
||||
"deleted": "评论已删除",
|
||||
"tooShort": "评论有点短——至少写一句话吧。",
|
||||
"error": "评论保存失败,请重试。",
|
||||
"basedOn": "共 {count} 条评论"
|
||||
},
|
||||
"submission": {
|
||||
"name": "工具名称",
|
||||
"websiteUrl": "官网地址",
|
||||
"tagline": "一句话简介",
|
||||
"taglinePlaceholder": "展示在卡片上的一句话卖点",
|
||||
"description": "详细介绍",
|
||||
"descriptionPlaceholder": "它是做什么的?适合谁?有什么不同?",
|
||||
"logoUrl": "Logo 地址",
|
||||
"category": "分类",
|
||||
"pricingLabel": "定价模式",
|
||||
"pricing": {
|
||||
"free": "免费",
|
||||
"freemium": "免费增值",
|
||||
"paid": "付费",
|
||||
"freeTrial": "免费试用",
|
||||
"openSource": "开源",
|
||||
"contact": "联系定价"
|
||||
},
|
||||
"founderName": "创始人 / 公司",
|
||||
"contactEmail": "联系邮箱",
|
||||
"socialLinks": "社交链接",
|
||||
"note": "给编辑的备注",
|
||||
"notePlaceholder": "任何能加快审核的信息(上线时间、数据等)",
|
||||
"selectPlaceholder": "请选择...",
|
||||
"submit": "提交审核",
|
||||
"submitting": "提交中...",
|
||||
"submitted": "已提交!我们会在 48 小时内完成审核。",
|
||||
"reviewNote": "免费收录 · 48 小时内审核",
|
||||
"duplicateFound": "这个工具可能已经被收录:",
|
||||
"duplicateBlocked": "该工具似乎已被收录,不允许重复提交。",
|
||||
"error": "提交失败,请检查填写内容。"
|
||||
},
|
||||
"claim": {
|
||||
"claimThisTool": "认领此工具",
|
||||
"verifiedOwner": "已认证所有者",
|
||||
"formTitle": "认领该收录页的所有权",
|
||||
"rolePlaceholder": "你的身份(如 创始人、市场负责人)",
|
||||
"messagePlaceholder": "我们如何验证你的身份?(同域名邮箱、官方报道页等)",
|
||||
"proofPlaceholder": "证明链接(可选)",
|
||||
"submit": "发送认领申请",
|
||||
"submitting": "发送中...",
|
||||
"submitted": "认领申请已发送,我们会尽快审核。",
|
||||
"pendingExists": "你已有一条待审核的认领申请。",
|
||||
"cancel": "取消",
|
||||
"error": "认领申请发送失败。"
|
||||
},
|
||||
"rankings": {
|
||||
"title": "社区榜单",
|
||||
"subtitle": "七个实时榜单由投票、评论、收藏与互动数据驱动——不接受赞助排名。",
|
||||
"trending": "趋势榜",
|
||||
"popular": "热门榜",
|
||||
"mostVoted": "最多投票",
|
||||
"mostSaved": "最多收藏",
|
||||
"highestRated": "最高评分",
|
||||
"new": "最新收录",
|
||||
"editorsChoice": "编辑精选",
|
||||
"empty": "该榜单暂无工具。"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import createSiteConfig from "@aidir/core/next-config";
|
||||
|
||||
export default createSiteConfig({
|
||||
requestPath: "./src/i18n/request.ts",
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "site-ai-stack",
|
||||
"version": "1.0.0",
|
||||
"description": "AI Stack — AI directory site powered by @aidir/core",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev -p 3001",
|
||||
"build": "next build",
|
||||
"start": "next start -p 3001",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aidir/core": "workspace:*",
|
||||
"next": "16.1.1",
|
||||
"react": "^19.2.3",
|
||||
"react-dom": "^19.2.3",
|
||||
"next-intl": "^4.7.0",
|
||||
"next-themes": "^0.4.6",
|
||||
"next-view-transitions": "^0.3.5",
|
||||
"sonner": "^2.0.7",
|
||||
"geist": "^1.3.0",
|
||||
"lucide-react": "^0.562.0",
|
||||
"framer-motion": "^12.43.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/mdx": "^2.0.13",
|
||||
"typescript": "^5",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"postcss": "^8"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
const config = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 293 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" rx="14" fill="currentColor"/><text x="32" y="44" font-family="system-ui,sans-serif" font-size="36" font-weight="700" text-anchor="middle" fill="#fff">A</text></svg>
|
||||
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 715 KiB |
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,24 @@
|
||||
# robots.txt for Toolso.AI - AI Tools Directory
|
||||
# https://toolso.ai
|
||||
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
# Disallow admin and API pages
|
||||
Disallow: /admin/
|
||||
Disallow: /api/
|
||||
|
||||
# Disallow authentication pages
|
||||
Disallow: /*/signup
|
||||
Disallow: /*/login
|
||||
Disallow: /*/check-email
|
||||
Disallow: /*/verify-email
|
||||
Disallow: /*/forgot-password
|
||||
Disallow: /*/reset-password
|
||||
|
||||
# Disallow protected user pages
|
||||
Disallow: /*/dashboard
|
||||
Disallow: /*/profile
|
||||
|
||||
# Sitemap location
|
||||
Sitemap: https://toolso.ai/sitemap.xml
|
||||
|
After Width: | Height: | Size: 574 KiB |
|
After Width: | Height: | Size: 336 KiB |
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/admin/analytics/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/admin/analytics/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/admin/categories/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/admin/categories/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/admin/claims/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/admin/claims/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/admin/discovery/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/admin/discovery/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/admin/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/admin/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/admin/reviews/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/admin/reviews/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/admin/submissions/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/admin/submissions/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/admin/tags/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/admin/tags/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/admin/tools/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/admin/tools/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/admin/users/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/admin/users/page";
|
||||
@@ -0,0 +1,3 @@
|
||||
// 自动生成:[locale]/(admin)/admin/votes/page.tsx 的薄路由
|
||||
export const revalidate = 0;
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/admin/votes/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(admin)/layout.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(admin)/layout";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(auth)/forgot-password/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(auth)/forgot-password/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(auth)/layout.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(auth)/layout";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(auth)/login/page.tsx 的薄路由
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(auth)/login/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(auth)/reset-password/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(auth)/reset-password/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(auth)/signup/page.tsx 的薄路由
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(auth)/signup/page";
|
||||
@@ -0,0 +1,3 @@
|
||||
// 自动生成:[locale]/(marketing)/ai-tools-for/[slug]/page.tsx 的薄路由
|
||||
export const revalidate = 3600;
|
||||
export { default, generateStaticParams, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/ai-tools-for/[slug]/page";
|
||||
@@ -0,0 +1,3 @@
|
||||
// 自动生成:[locale]/(marketing)/ai-tools-for/page.tsx 的薄路由
|
||||
export const revalidate = 3600;
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/ai-tools-for/page";
|
||||
@@ -0,0 +1,3 @@
|
||||
// 自动生成:[locale]/(marketing)/best/[slug]/page.tsx 的薄路由
|
||||
export const revalidate = 3600;
|
||||
export { default, generateStaticParams, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/best/[slug]/page";
|
||||
@@ -0,0 +1,3 @@
|
||||
// 自动生成:[locale]/(marketing)/best/page.tsx 的薄路由
|
||||
export const revalidate = 3600;
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/best/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(marketing)/blog/[slug]/page.tsx 的薄路由
|
||||
export { default, generateStaticParams, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/blog/[slug]/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(marketing)/blog/page.tsx 的薄路由
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/blog/page";
|
||||
@@ -0,0 +1,3 @@
|
||||
// 自动生成:[locale]/(marketing)/category/[slug]/page.tsx 的薄路由
|
||||
export const revalidate = 3600;
|
||||
export { default, generateStaticParams, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/category/[slug]/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(marketing)/contact/page.tsx 的薄路由
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/contact/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(marketing)/cookies/page.tsx 的薄路由
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/cookies/page";
|
||||
@@ -0,0 +1,4 @@
|
||||
import { createMarketingLayout } from "@aidir/core/kit/create-marketing-layout";
|
||||
import { siteConfig } from "@/site/brand";
|
||||
|
||||
export default createMarketingLayout(siteConfig);
|
||||
@@ -0,0 +1,9 @@
|
||||
import { createHomePage, createHomeMetadata } from "@aidir/core/kit/create-home";
|
||||
import { siteConfig } from "@/site/brand";
|
||||
import { SiteHome } from "@/site/home";
|
||||
|
||||
// 首页内容变化不频繁,ISR 每小时再生
|
||||
export const revalidate = 3600;
|
||||
|
||||
export const generateMetadata = createHomeMetadata(siteConfig);
|
||||
export default createHomePage(siteConfig, SiteHome);
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(marketing)/privacy/page.tsx 的薄路由
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/privacy/page";
|
||||
@@ -0,0 +1,3 @@
|
||||
// 自动生成:[locale]/(marketing)/rankings/page.tsx 的薄路由
|
||||
export const revalidate = 1800;
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/rankings/page";
|
||||
@@ -0,0 +1,3 @@
|
||||
// 自动生成:[locale]/(marketing)/submit/page.tsx 的薄路由
|
||||
export const revalidate = 3600;
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/submit/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(marketing)/terms/page.tsx 的薄路由
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/terms/page";
|
||||
@@ -0,0 +1,3 @@
|
||||
// 自动生成:[locale]/(marketing)/tools/[slug]/page.tsx 的薄路由
|
||||
export const revalidate = 3600;
|
||||
export { default, generateStaticParams, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/tools/[slug]/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(marketing)/tools/page.tsx 的薄路由
|
||||
export { default, generateMetadata } from "@aidir/core/pages/[locale]/(marketing)/tools/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(protected)/dashboard/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(protected)/dashboard/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(protected)/layout.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(protected)/layout";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/(protected)/profile/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/(protected)/profile/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/check-email/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/check-email/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/layout.tsx 的薄路由
|
||||
export { default, generateStaticParams } from "@aidir/core/pages/[locale]/layout";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:[locale]/verify-email/page.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/[locale]/verify-email/page";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/auth/[...all]/route.ts 的薄路由
|
||||
export { POST, GET } from "@aidir/core/pages/api/auth/[...all]/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/auth/forgot-password/route.ts 的薄路由
|
||||
export { POST } from "@aidir/core/pages/api/auth/forgot-password/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/auth/resend-verification/route.ts 的薄路由
|
||||
export { POST } from "@aidir/core/pages/api/auth/resend-verification/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/auth/reset-password/route.ts 的薄路由
|
||||
export { POST } from "@aidir/core/pages/api/auth/reset-password/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/auth/verify-email/route.ts 的薄路由
|
||||
export { GET } from "@aidir/core/pages/api/auth/verify-email/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/auth/verify-reset-token/route.ts 的薄路由
|
||||
export { GET } from "@aidir/core/pages/api/auth/verify-reset-token/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/newsletter/unsubscribe/route.ts 的薄路由
|
||||
export { GET } from "@aidir/core/pages/api/newsletter/unsubscribe/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/outbound/route.ts 的薄路由
|
||||
export { GET } from "@aidir/core/pages/api/outbound/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/search/route.ts 的薄路由
|
||||
export { GET } from "@aidir/core/pages/api/search/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/tools/[id]/vote/route.ts 的薄路由
|
||||
export { POST, DELETE } from "@aidir/core/pages/api/tools/[id]/vote/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/upload/image/route.ts 的薄路由
|
||||
export { POST } from "@aidir/core/pages/api/upload/image/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/upload/simple/route.ts 的薄路由
|
||||
export { POST } from "@aidir/core/pages/api/upload/simple/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/user/admin-status/route.ts 的薄路由
|
||||
export { GET } from "@aidir/core/pages/api/user/admin-status/route";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:api/user/profile/route.ts 的薄路由
|
||||
export { GET } from "@aidir/core/pages/api/user/profile/route";
|
||||
@@ -0,0 +1,3 @@
|
||||
import "@aidir/core/styles/globals.css";
|
||||
|
||||
export { default } from "@aidir/core/pages/app-layout";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:manifest.ts 的薄路由
|
||||
export { default } from "@aidir/core/pages/manifest";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:not-found.tsx 的薄路由
|
||||
export { default } from "@aidir/core/pages/not-found";
|
||||
@@ -0,0 +1,2 @@
|
||||
// 自动生成:sitemap.ts 的薄路由
|
||||
export { default } from "@aidir/core/pages/sitemap";
|
||||
@@ -0,0 +1,37 @@
|
||||
import { getRequestConfig } from "next-intl/server";
|
||||
import { notFound } from "next/navigation";
|
||||
import { locales, defaultLocale, type Locale } from "@aidir/core/i18n.config";
|
||||
|
||||
/** 站点品牌 SEO 文案覆盖(每个网站不同) */
|
||||
const brandMessages = {
|
||||
en: {
|
||||
seo: { home: {"title":"AI Stack — Find the Best AI Tools, Ranked by Real Users","description":"The professional AI tools directory. 1,000+ AI tools across 14 categories ranked by community votes, reviews and engagement.","ogImage":"/og-image.png"} },
|
||||
hero: { title: "AI Stack — Find the Best AI Tools, Ranked by Real Users", description: "The professional AI tools directory. 1,000+ AI tools across 14 categories ranked by community votes, reviews and engagement." },
|
||||
common: { brand: { name: "AI Stack", tagline: "The professional AI tools directory — ranked by the community." } },
|
||||
},
|
||||
zh: {
|
||||
seo: { home: {"title":"AI Stack — 由真实用户排名的 AI 工具目录","description":"专业 AI 工具导航:14 个分类、1000+ 工具,由社区投票、评论与互动数据实时排名。","ogImage":"/og-image.png"} },
|
||||
hero: { title: "AI Stack — 由真实用户排名的 AI 工具目录", description: "专业 AI 工具导航:14 个分类、1000+ 工具,由社区投票、评论与互动数据实时排名。" },
|
||||
common: { brand: { name: "AI Stack", tagline: "The professional AI tools directory — ranked by the community." } },
|
||||
},
|
||||
} as const;
|
||||
|
||||
export default getRequestConfig(async ({ requestLocale }) => {
|
||||
let locale = await requestLocale;
|
||||
if (!locale || !locales.includes(locale as Locale)) {
|
||||
locale = defaultLocale;
|
||||
}
|
||||
try {
|
||||
// 底座基础文案 + 站点品牌覆盖(浅合并到顶层命名空间)
|
||||
const base = (await import(`../../messages/${locale}.json`)).default;
|
||||
const override = brandMessages[locale as keyof typeof brandMessages];
|
||||
const messages = { ...base };
|
||||
for (const [ns, value] of Object.entries(override)) {
|
||||
messages[ns] = { ...(messages[ns] ?? {}), ...value };
|
||||
}
|
||||
return { locale, messages };
|
||||
} catch (error) {
|
||||
console.error("Error loading messages for locale:", locale, error);
|
||||
notFound();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import { proxy } from "@aidir/core/proxy";
|
||||
|
||||
export default proxy;
|
||||
|
||||
export const config = {
|
||||
matcher: [
|
||||
"/",
|
||||
"/((?!api|_next|_vercel|.*\\..*).*)"
|
||||
]
|
||||
};
|
||||
@@ -0,0 +1,107 @@
|
||||
import type { SiteConfig } from "@/kit/types";
|
||||
|
||||
// AI Stack —— 独立站点的全部品牌/导航/页脚配置
|
||||
export const siteConfig: SiteConfig = {
|
||||
"port": 3001,
|
||||
"brand": {
|
||||
"name": "AI Stack",
|
||||
"tagline": "The professional AI tools directory — ranked by the community.",
|
||||
"headline": "Find the best AI tools, ranked by real users",
|
||||
"subheadline": "1,000+ AI tools across 14 categories. Compare votes, reviews and pricing to pick the right one."
|
||||
},
|
||||
"navItems": [
|
||||
{
|
||||
"label": "Discover",
|
||||
"href": "/tools"
|
||||
},
|
||||
{
|
||||
"label": "Use Cases",
|
||||
"href": "/ai-tools-for"
|
||||
},
|
||||
{
|
||||
"label": "Best Lists",
|
||||
"href": "/best"
|
||||
},
|
||||
{
|
||||
"label": "Rankings",
|
||||
"href": "/rankings"
|
||||
},
|
||||
{
|
||||
"label": "Blog",
|
||||
"href": "/blog"
|
||||
},
|
||||
{
|
||||
"label": "Submit",
|
||||
"href": "/submit"
|
||||
}
|
||||
],
|
||||
"footerGroups": [
|
||||
{
|
||||
"title": "Discover",
|
||||
"links": [
|
||||
{
|
||||
"label": "All Tools",
|
||||
"href": "/tools"
|
||||
},
|
||||
{
|
||||
"label": "Use Cases",
|
||||
"href": "/ai-tools-for"
|
||||
},
|
||||
{
|
||||
"label": "Best Lists",
|
||||
"href": "/best"
|
||||
},
|
||||
{
|
||||
"label": "Rankings",
|
||||
"href": "/rankings"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Community",
|
||||
"links": [
|
||||
{
|
||||
"label": "Submit a Tool",
|
||||
"href": "/submit"
|
||||
},
|
||||
{
|
||||
"label": "Blog",
|
||||
"href": "/blog"
|
||||
},
|
||||
{
|
||||
"label": "Dashboard",
|
||||
"href": "/dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Legal",
|
||||
"links": [
|
||||
{
|
||||
"label": "Terms",
|
||||
"href": "/terms"
|
||||
},
|
||||
{
|
||||
"label": "Privacy",
|
||||
"href": "/privacy"
|
||||
},
|
||||
{
|
||||
"label": "Contact",
|
||||
"href": "/contact"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"searchPlaceholder": "Search AI tools...",
|
||||
"seo": {
|
||||
"en": {
|
||||
"title": "AI Stack — Find the Best AI Tools, Ranked by Real Users",
|
||||
"description": "The professional AI tools directory. 1,000+ AI tools across 14 categories ranked by community votes, reviews and engagement."
|
||||
},
|
||||
"zh": {
|
||||
"title": "AI Stack — 由真实用户排名的 AI 工具目录",
|
||||
"description": "专业 AI 工具导航:14 个分类、1000+ 工具,由社区投票、评论与互动数据实时排名。"
|
||||
}
|
||||
},
|
||||
"id": "ai-stack"
|
||||
};
|
||||
@@ -0,0 +1,277 @@
|
||||
// 自动生成:站点首页组件(源自底座 classic 形态,品牌来自 @/site/brand)
|
||||
import { siteConfig } from "@/site/brand";
|
||||
import { Search, TrendingUp, Sparkles, Clock, Award, LayoutGrid, MessageSquareQuote } from "lucide-react";
|
||||
import { ToolCard, ToolCardGrid } from "@/components/tool-card";
|
||||
import { LocaleLink } from "@/components/locale-link";
|
||||
import { SectionHeader } from "@/kit/section";
|
||||
import { ThemeHeader } from "@/kit/theme-header";
|
||||
import { ThemeFooter } from "@/kit/theme-footer";
|
||||
import { getHomeDataSafe } from "@/kit/home-data";
|
||||
|
||||
/** Classic:专业 AI Directory(Clean / Dense / Professional) */
|
||||
|
||||
|
||||
const navItems = [
|
||||
{ label: "Discover", href: "/tools" },
|
||||
{ label: "Categories", href: "/tools" },
|
||||
{ label: "Use Cases", href: "/ai-tools-for" },
|
||||
{ label: "Best Lists", href: "/best" },
|
||||
{ label: "Rankings", href: "/rankings" },
|
||||
{ label: "Blog", href: "/blog" },
|
||||
{ label: "Submit", href: "/submit" },
|
||||
];
|
||||
|
||||
const footerGroups = [
|
||||
{
|
||||
title: "Discover",
|
||||
links: [
|
||||
{ label: "All Tools", href: "/tools" },
|
||||
{ label: "Use Cases", href: "/ai-tools-for" },
|
||||
{ label: "Best Lists", href: "/best" },
|
||||
{ label: "Rankings", href: "/rankings" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Community",
|
||||
links: [
|
||||
{ label: "Submit a Tool", href: "/submit" },
|
||||
{ label: "Blog", href: "/blog" },
|
||||
{ label: "Dashboard", href: "/dashboard" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Legal",
|
||||
links: [
|
||||
{ label: "Terms", href: "/terms" },
|
||||
{ label: "Privacy", href: "/privacy" },
|
||||
{ label: "Contact", href: "/contact" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
async function SiteHome({ locale }: { locale: string }) {
|
||||
const data = await getHomeDataSafe(8);
|
||||
|
||||
return (
|
||||
<div className="bg-background">
|
||||
{/* Hero */}
|
||||
<section className="border-b border-border bg-gradient-to-b from-secondary/40 to-background">
|
||||
<div className="mx-auto max-w-7xl px-4 py-16 text-center sm:px-6 md:py-24">
|
||||
<h1 className="mx-auto max-w-3xl text-3xl font-bold tracking-tight text-foreground sm:text-4xl md:text-5xl">
|
||||
{siteConfig.brand.headline}
|
||||
</h1>
|
||||
<p className="mx-auto mt-4 max-w-2xl text-sm text-muted-foreground sm:text-base">
|
||||
{siteConfig.brand.subheadline}
|
||||
</p>
|
||||
<form action={`/${locale}/tools`} className="mx-auto mt-8 max-w-xl">
|
||||
<div className="relative">
|
||||
<Search className="absolute left-4 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
|
||||
<input
|
||||
name="search"
|
||||
placeholder="Search 1,000+ AI tools..."
|
||||
className="h-12 w-full rounded-full border border-border bg-background pl-11 pr-28 text-sm text-foreground shadow-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30"
|
||||
aria-label="Search AI tools"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="absolute right-1.5 top-1.5 h-9 rounded-full bg-primary px-5 text-xs font-semibold text-primary-foreground transition-opacity hover:opacity-90"
|
||||
>
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div className="mt-4 flex flex-wrap items-center justify-center gap-2 text-xs text-muted-foreground">
|
||||
<span>Popular:</span>
|
||||
{["writing", "video", "coding", "image"].map((q) => (
|
||||
<LocaleLink
|
||||
key={q}
|
||||
href={`/tools?search=${q}`}
|
||||
className="rounded-full bg-secondary px-2.5 py-1 transition-colors hover:bg-hover"
|
||||
>
|
||||
{q}
|
||||
</LocaleLink>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="mx-auto max-w-7xl space-y-12 px-4 py-12 sm:px-6">
|
||||
{/* Trending */}
|
||||
{data.trending.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader
|
||||
title="Trending this week"
|
||||
subtitle="Ranked by votes, reviews and engagement over the last 7 days"
|
||||
viewAllHref="/rankings?board=trending"
|
||||
viewAllLabel="All rankings"
|
||||
/>
|
||||
<ToolCardGrid tools={data.trending} locale={locale} ranked />
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Categories */}
|
||||
{data.categories.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader
|
||||
title="Browse by category"
|
||||
viewAllHref="/tools"
|
||||
viewAllLabel="All tools"
|
||||
/>
|
||||
<div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5">
|
||||
{data.categories.slice(0, 10).map((category) => (
|
||||
<LocaleLink
|
||||
key={category.id}
|
||||
href={`/category/${category.slug}`}
|
||||
className="group rounded-xl border border-border p-4 transition-all hover:border-primary/30 hover:shadow-sm"
|
||||
>
|
||||
<LayoutGrid className="h-4 w-4 text-primary" />
|
||||
<h3 className="mt-2 truncate text-sm font-medium text-foreground group-hover:text-primary">
|
||||
{locale === "zh" && category.nameZh
|
||||
? category.nameZh
|
||||
: category.nameEn}
|
||||
</h3>
|
||||
<p className="mt-0.5 text-xs text-muted-foreground tabular-nums">
|
||||
{category.toolCount} tools
|
||||
</p>
|
||||
</LocaleLink>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* New + Editor's Choice 两列 */}
|
||||
<div className="grid gap-12 lg:grid-cols-2">
|
||||
{data.newest.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader
|
||||
title="New AI tools"
|
||||
viewAllHref="/rankings?board=new"
|
||||
/>
|
||||
<ToolCardGrid tools={data.newest.slice(0, 4)} locale={locale} />
|
||||
</section>
|
||||
)}
|
||||
{data.editorsChoice.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader
|
||||
title="Editor's Choice"
|
||||
viewAllHref="/rankings?board=editors-choice"
|
||||
/>
|
||||
<ToolCardGrid tools={data.editorsChoice.slice(0, 4)} locale={locale} />
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Use Cases */}
|
||||
{data.useCases.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader
|
||||
title="Tools by use case"
|
||||
subtitle="What do you want to get done?"
|
||||
viewAllHref="/ai-tools-for"
|
||||
viewAllLabel="All use cases"
|
||||
/>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{data.useCases.slice(0, 12).map((uc) => (
|
||||
<LocaleLink
|
||||
key={uc.id}
|
||||
href={`/ai-tools-for/${uc.slug}`}
|
||||
className="rounded-full border border-border px-3.5 py-1.5 text-xs text-foreground transition-colors hover:border-primary/40 hover:bg-primary/5"
|
||||
>
|
||||
{locale === "zh" && uc.nameZh ? uc.nameZh : uc.nameEn}
|
||||
<span className="ml-1.5 text-muted-foreground tabular-nums">
|
||||
{uc.toolCount}
|
||||
</span>
|
||||
</LocaleLink>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Best Lists */}
|
||||
{data.collections.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader
|
||||
title="Best AI tool lists"
|
||||
subtitle="Curated rankings by our editors"
|
||||
viewAllHref="/best"
|
||||
viewAllLabel="All lists"
|
||||
/>
|
||||
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{data.collections.slice(0, 3).map((col) => (
|
||||
<LocaleLink
|
||||
key={col.id}
|
||||
href={`/best/${col.slug}`}
|
||||
className="group rounded-xl border border-border p-5 transition-all hover:border-primary/30 hover:shadow-sm"
|
||||
>
|
||||
<Award className="h-4 w-4 text-primary" />
|
||||
<h3 className="mt-2 text-sm font-semibold text-foreground group-hover:text-primary">
|
||||
{locale === "zh" && col.nameZh ? col.nameZh : col.nameEn}
|
||||
</h3>
|
||||
<p className="mt-1 line-clamp-2 text-xs text-muted-foreground">
|
||||
{locale === "zh" && col.introZh ? col.introZh : col.introEn}
|
||||
</p>
|
||||
<p className="mt-2 text-xs text-muted-foreground tabular-nums">
|
||||
{col.toolCount} tools
|
||||
</p>
|
||||
</LocaleLink>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Latest Reviews */}
|
||||
{data.latestReviews.length > 0 && (
|
||||
<section>
|
||||
<SectionHeader title="Latest community reviews" />
|
||||
<div className="grid gap-3 md:grid-cols-2">
|
||||
{data.latestReviews.map((review, i) => (
|
||||
<LocaleLink
|
||||
key={i}
|
||||
href={`/tools/${review.toolSlug}#reviews`}
|
||||
className="rounded-xl border border-border p-4 transition-colors hover:border-primary/30"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<MessageSquareQuote className="h-3.5 w-3.5 text-primary" />
|
||||
<span className="text-xs font-medium text-foreground">
|
||||
{review.authorName}
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
on {review.toolName}
|
||||
</span>
|
||||
<span className="ml-auto text-xs font-semibold text-amber-500 tabular-nums">
|
||||
{review.rating}/5
|
||||
</span>
|
||||
</div>
|
||||
<p className="mt-2 line-clamp-2 text-xs leading-relaxed text-muted-foreground">
|
||||
{review.content}
|
||||
</p>
|
||||
</LocaleLink>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Submit CTA */}
|
||||
<section className="rounded-2xl border border-border bg-secondary/30 p-8 text-center">
|
||||
<Sparkles className="mx-auto h-5 w-5 text-primary" />
|
||||
<h2 className="mt-3 text-lg font-semibold text-foreground">
|
||||
Built an AI tool?
|
||||
</h2>
|
||||
<p className="mx-auto mt-1 max-w-md text-sm text-muted-foreground">
|
||||
Submit it to {siteConfig.brand.name} and get discovered by thousands of users
|
||||
looking for tools like yours.
|
||||
</p>
|
||||
<LocaleLink
|
||||
href="/submit"
|
||||
className="mt-4 inline-flex items-center gap-1.5 rounded-full bg-primary px-5 py-2 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90"
|
||||
>
|
||||
<TrendingUp className="h-4 w-4" />
|
||||
Submit your tool
|
||||
</LocaleLink>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export { SiteHome };
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { Config } from "tailwindcss";
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
"./src/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"../../packages/core/src/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
presets: [require("../../packages/core/tailwind.preset.cjs")],
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react-jsx",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./src/*",
|
||||
"../../packages/core/src/*"
|
||||
],
|
||||
"@aidir/core/pages/*": [
|
||||
"../../packages/core/src/pages/*"
|
||||
],
|
||||
"@aidir/core/kit/*": [
|
||||
"../../packages/core/src/kit/*"
|
||||
],
|
||||
"@aidir/core/src/*": [
|
||||
"../../packages/core/src/*"
|
||||
],
|
||||
"@aidir/core/proxy": [
|
||||
"../../packages/core/src/proxy.ts"
|
||||
],
|
||||
"@aidir/core/i18n.config": [
|
||||
"../../packages/core/src/i18n.config.ts"
|
||||
],
|
||||
"@aidir/core/styles/globals.css": [
|
||||
"../../packages/core/src/styles/globals.css"
|
||||
],
|
||||
"@aidir/core/*": [
|
||||
"../../packages/core/src/*",
|
||||
"../../packages/core/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts",
|
||||
".next/dev/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||