design/fix/clean: minor design tweaks and improvements, update ccusage, add Perplexity to /ai, ToolReviews -> FavoriteTools for flow
This commit is contained in:
parent
7121ec926f
commit
e706ae8307
7 changed files with 111 additions and 41 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import { Bot } from 'lucide-react'
|
import { TbStack2 } from 'react-icons/tb'
|
||||||
import Link from '@/components/objects/Link'
|
import Link from '@/components/objects/Link'
|
||||||
import type { AITool } from '../types'
|
import type { AITool } from '../types'
|
||||||
|
|
||||||
|
|
@ -27,10 +27,13 @@ export default function AIStack({ tools }: AIStackProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="p-4 sm:p-8 border-2 border-gray-700 rounded-lg hover:border-gray-600 transition-colors duration-300">
|
<section className="p-4 sm:p-8 border-2 border-gray-700 rounded-lg hover:border-gray-600 transition-colors duration-300">
|
||||||
|
<div className="flex flex-row justify-between">
|
||||||
<h2 className="text-2xl font-semibold mb-6 text-gray-200 flex items-center gap-2">
|
<h2 className="text-2xl font-semibold mb-6 text-gray-200 flex items-center gap-2">
|
||||||
<Bot size={24} />
|
<TbStack2 size={24} />
|
||||||
My AI Stack
|
My AI Stack
|
||||||
</h2>
|
</h2>
|
||||||
|
<p className="text-muted-foreground">The AI tools I use as a part of my routine and workflow.</p>
|
||||||
|
</div>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
{tools.map((tool, index) => (
|
{tools.map((tool, index) => (
|
||||||
<div key={index} className="p-4 border border-gray-700 rounded-lg hover:border-gray-500 transition-all duration-300 flex flex-col">
|
<div key={index} className="p-4 border border-gray-700 rounded-lg hover:border-gray-500 transition-all duration-300 flex flex-col">
|
||||||
|
|
@ -54,7 +57,7 @@ export default function AIStack({ tools }: AIStackProps) {
|
||||||
</span>
|
</span>
|
||||||
<span className="flex flex-row items-center gap-4">
|
<span className="flex flex-row items-center gap-4">
|
||||||
{tool.link && (
|
{tool.link && (
|
||||||
<Link href={tool.link} className="text-blue-400 hover:text-blue-300 text-sm">
|
<Link href={tool.link} className="text-blue-400 hover:text-blue-300 text-sm" target="_blank" rel="noopener noreferrer">
|
||||||
View →
|
View →
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Star } from 'lucide-react'
|
import { Brain, Star } from 'lucide-react'
|
||||||
import type { FavoriteModel } from '../types'
|
import type { FavoriteModel } from '../types'
|
||||||
|
|
||||||
interface FavoriteModelsProps {
|
interface FavoriteModelsProps {
|
||||||
|
|
@ -8,10 +8,13 @@ interface FavoriteModelsProps {
|
||||||
export default function FavoriteModels({ models }: FavoriteModelsProps) {
|
export default function FavoriteModels({ models }: FavoriteModelsProps) {
|
||||||
return (
|
return (
|
||||||
<section className="p-4 sm:p-8 border-2 border-gray-700 rounded-lg hover:border-gray-600 transition-colors duration-300">
|
<section className="p-4 sm:p-8 border-2 border-gray-700 rounded-lg hover:border-gray-600 transition-colors duration-300">
|
||||||
|
<div className="flex flex-row justify-between">
|
||||||
<h2 className="text-2xl font-semibold mb-6 text-gray-200 flex items-center gap-2">
|
<h2 className="text-2xl font-semibold mb-6 text-gray-200 flex items-center gap-2">
|
||||||
<Star size={24} />
|
<Brain size={24} />
|
||||||
Favorite Models
|
Favorite Models
|
||||||
</h2>
|
</h2>
|
||||||
|
<p className="text-muted-foreground italic text-sm">Based on personal preference</p>
|
||||||
|
</div>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{models.map((model, index) => (
|
{models.map((model, index) => (
|
||||||
<div key={index} className="p-4 bg-gray-800/50 rounded-lg">
|
<div key={index} className="p-4 bg-gray-800/50 rounded-lg">
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,21 @@
|
||||||
import { MessageSquare, Star } from 'lucide-react'
|
import { Star } from 'lucide-react'
|
||||||
|
import { TbTool } from 'react-icons/tb'
|
||||||
import type { AIReview } from '../types'
|
import type { AIReview } from '../types'
|
||||||
|
|
||||||
interface ToolReviewsProps {
|
interface FavoriteToolsProps {
|
||||||
reviews: AIReview[]
|
reviews: AIReview[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ToolReviews({ reviews }: ToolReviewsProps) {
|
export default function FavoriteTools({ reviews }: FavoriteToolsProps) {
|
||||||
return (
|
return (
|
||||||
<section className="p-4 sm:p-8 border-2 border-gray-700 rounded-lg hover:border-gray-600 transition-colors duration-300">
|
<section className="p-4 sm:p-8 border-2 border-gray-700 rounded-lg hover:border-gray-600 transition-colors duration-300">
|
||||||
|
<div className="flex flex-row justify-between">
|
||||||
<h2 className="text-2xl font-semibold mb-6 text-gray-200 flex items-center gap-2">
|
<h2 className="text-2xl font-semibold mb-6 text-gray-200 flex items-center gap-2">
|
||||||
<MessageSquare size={24} />
|
<TbTool size={24} />
|
||||||
Tool Reviews
|
Favorite Tools
|
||||||
</h2>
|
</h2>
|
||||||
|
<p className="text-muted-foreground italic text-sm">Based on personal preference</p>
|
||||||
|
</div>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{reviews.map((review, index) => (
|
{reviews.map((review, index) => (
|
||||||
<div key={index} className="p-4 bg-gray-800/50 rounded-lg">
|
<div key={index} className="p-4 bg-gray-800/50 rounded-lg">
|
||||||
|
|
@ -6,8 +6,8 @@ export default function TopPick() {
|
||||||
return (
|
return (
|
||||||
<div className="px-4 mb-4">
|
<div className="px-4 mb-4">
|
||||||
<h2 className="text-4xl font-semibold mb-6 text-gray-200 flex items-center gap-2">
|
<h2 className="text-4xl font-semibold mb-6 text-gray-200 flex items-center gap-2">
|
||||||
<Trophy size={32} />
|
<Trophy size={32} className="text-orange-300" />
|
||||||
Top Pick of 2025
|
Top Pick of <i className="-ml-[1.55px]">2025</i>
|
||||||
</h2>
|
</h2>
|
||||||
<div className="p-6 sm:p-8 border-2 border-[#c15f3c] rounded-lg bg-orange-500/5">
|
<div className="p-6 sm:p-8 border-2 border-[#c15f3c] rounded-lg bg-orange-500/5">
|
||||||
<div className="grid md:grid-cols-2 gap-6">
|
<div className="grid md:grid-cols-2 gap-6">
|
||||||
|
|
@ -18,7 +18,7 @@ export default function TopPick() {
|
||||||
<p className="text-gray-400">by Anthropic</p>
|
<p className="text-gray-400">by Anthropic</p>
|
||||||
<div className="flex items-center gap-2 mt-2">
|
<div className="flex items-center gap-2 mt-2">
|
||||||
<Link href="/ai/claude" className="text-blue-400 hover:text-blue-300 flex items-center gap-1">
|
<Link href="/ai/claude" className="text-blue-400 hover:text-blue-300 flex items-center gap-1">
|
||||||
View My Usage <ChevronRight size={16} />
|
My Usage <ChevronRight size={16} />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -30,15 +30,9 @@ export default function TopPick() {
|
||||||
</p>
|
</p>
|
||||||
<div className='flex flex-col items-center gap-y-6 sm:flex-row sm:justify-between'>
|
<div className='flex flex-col items-center gap-y-6 sm:flex-row sm:justify-between'>
|
||||||
<div className="flex gap-2 flex-wrap">
|
<div className="flex gap-2 flex-wrap">
|
||||||
<span className="px-2 py-1 bg-gray-700 rounded text-xs text-gray-300">Claude Code</span>
|
<span className="px-2 py-1 bg-gray-700 rounded text-xs text-gray-300">Top-Tier Tool Calling</span>
|
||||||
<span className="px-2 py-1 bg-gray-700 rounded text-xs text-gray-300">Best Tool Calling</span>
|
<span className="px-2 py-1 bg-gray-700 rounded text-xs text-gray-300">Max Plan is High Value</span>
|
||||||
<span className="px-2 py-1 bg-gray-700 rounded text-xs text-gray-300">High Value in Max Plan</span>
|
<span className="px-2 py-1 bg-gray-700 rounded text-xs text-gray-300">Fast Interface</span>
|
||||||
<span className="px-2 py-1 bg-gray-700 rounded text-xs text-gray-300">Quite Fast Interface</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center justify-end">
|
|
||||||
<span className="px-3 py-1 bg-[#c15f3c]/20 text-[#c15f3c] rounded-full text-sm font-medium">
|
|
||||||
Top Overall Pick
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import {
|
import {
|
||||||
SiClaude,
|
SiClaude,
|
||||||
SiGithubcopilot,
|
SiGithubcopilot,
|
||||||
SiGooglegemini
|
SiGooglegemini,
|
||||||
|
SiPerplexity
|
||||||
} from 'react-icons/si'
|
} from 'react-icons/si'
|
||||||
import type { AITool, FavoriteModel, AIReview } from './types'
|
import type { AITool, FavoriteModel, AIReview } from './types'
|
||||||
|
|
||||||
|
|
@ -58,6 +59,13 @@ export const aiTools: AITool[] = [
|
||||||
status: "occasional",
|
status: "occasional",
|
||||||
link: "https://chat.qwen.ai/"
|
link: "https://chat.qwen.ai/"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Perplexity",
|
||||||
|
icon: SiPerplexity,
|
||||||
|
description: "Reliable for more in-depth searching",
|
||||||
|
status: "occasional",
|
||||||
|
link: "https://perplexity.ai/"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
export const favoriteModels: FavoriteModel[] = [
|
export const favoriteModels: FavoriteModel[] = [
|
||||||
|
|
@ -70,7 +78,13 @@ export const favoriteModels: FavoriteModel[] = [
|
||||||
{
|
{
|
||||||
name: "Claude 4.1 Opus",
|
name: "Claude 4.1 Opus",
|
||||||
provider: "Anthropic",
|
provider: "Anthropic",
|
||||||
review: "Amazing planner, useful for Plan Mode in Claude Code. Useful in code generation too.",
|
review: "Amazing planner, useful for Plan Mode in Claude Code. Useful in code generation, albeit at a higher cost.",
|
||||||
|
rating: 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Qwen3-Max-Preview",
|
||||||
|
provider: "Alibaba",
|
||||||
|
review: "A new personality for Qwen3 at a larger size, amazing for use in chats. I'm not so happy that it's closed source (for now).",
|
||||||
rating: 5
|
rating: 5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,10 @@ import { Brain } from 'lucide-react'
|
||||||
import TopPick from './components/TopPick'
|
import TopPick from './components/TopPick'
|
||||||
import AIStack from './components/AIStack'
|
import AIStack from './components/AIStack'
|
||||||
import FavoriteModels from './components/FavoriteModels'
|
import FavoriteModels from './components/FavoriteModels'
|
||||||
import ToolReviews from './components/ToolReviews'
|
import FavoriteTools from './components/FavoriteTools'
|
||||||
import { aiTools, favoriteModels, aiReviews } from './data'
|
import { aiTools, favoriteModels, aiReviews } from './data'
|
||||||
|
|
||||||
export default function AI() {
|
export default function AI() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen flex flex-col">
|
<div className="min-h-screen flex flex-col">
|
||||||
<Header />
|
<Header />
|
||||||
|
|
@ -31,7 +30,7 @@ export default function AI() {
|
||||||
|
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 p-4">
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 p-4">
|
||||||
<FavoriteModels models={favoriteModels} />
|
<FavoriteModels models={favoriteModels} />
|
||||||
<ToolReviews reviews={aiReviews} />
|
<FavoriteTools reviews={aiReviews} />
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|
|
||||||
|
|
@ -574,14 +574,67 @@
|
||||||
"cost": 34.53813299999999
|
"cost": 34.53813299999999
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2025-09-06",
|
||||||
|
"inputTokens": 1668,
|
||||||
|
"outputTokens": 33964,
|
||||||
|
"cacheCreationTokens": 833152,
|
||||||
|
"cacheReadTokens": 7717866,
|
||||||
|
"totalTokens": 8586650,
|
||||||
|
"totalCost": 27.341439,
|
||||||
|
"modelsUsed": [
|
||||||
|
"claude-opus-4-1-20250805",
|
||||||
|
"claude-sonnet-4-20250514"
|
||||||
|
],
|
||||||
|
"modelBreakdowns": [
|
||||||
|
{
|
||||||
|
"modelName": "claude-opus-4-1-20250805",
|
||||||
|
"inputTokens": 590,
|
||||||
|
"outputTokens": 32624,
|
||||||
|
"cacheCreationTokens": 715702,
|
||||||
|
"cacheReadTokens": 7239371,
|
||||||
|
"cost": 26.734119
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"modelName": "claude-sonnet-4-20250514",
|
||||||
|
"inputTokens": 1078,
|
||||||
|
"outputTokens": 1340,
|
||||||
|
"cacheCreationTokens": 117450,
|
||||||
|
"cacheReadTokens": 478495,
|
||||||
|
"cost": 0.6073200000000001
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2025-09-07",
|
||||||
|
"inputTokens": 114,
|
||||||
|
"outputTokens": 1815,
|
||||||
|
"cacheCreationTokens": 34842,
|
||||||
|
"cacheReadTokens": 441584,
|
||||||
|
"totalTokens": 478355,
|
||||||
|
"totalCost": 0.2906997,
|
||||||
|
"modelsUsed": [
|
||||||
|
"claude-sonnet-4-20250514"
|
||||||
|
],
|
||||||
|
"modelBreakdowns": [
|
||||||
|
{
|
||||||
|
"modelName": "claude-sonnet-4-20250514",
|
||||||
|
"inputTokens": 114,
|
||||||
|
"outputTokens": 1815,
|
||||||
|
"cacheCreationTokens": 34842,
|
||||||
|
"cacheReadTokens": 441584,
|
||||||
|
"cost": 0.2906997
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"totals": {
|
"totals": {
|
||||||
"inputTokens": 210111,
|
"inputTokens": 211893,
|
||||||
"outputTokens": 1247590,
|
"outputTokens": 1283369,
|
||||||
"cacheCreationTokens": 25422815,
|
"cacheCreationTokens": 26290809,
|
||||||
"cacheReadTokens": 522838726,
|
"cacheReadTokens": 530998176,
|
||||||
"totalCost": 710.6193022500001,
|
"totalCost": 738.2514409500002,
|
||||||
"totalTokens": 549719242
|
"totalTokens": 558784247
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue