veryfront 0.0.39 → 0.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/components.js +48 -47
- package/dist/ai/components.js.map +2 -2
- package/dist/ai/dev.js +3 -3
- package/dist/ai/dev.js.map +2 -2
- package/dist/ai/index.js +49 -23
- package/dist/ai/index.js.map +3 -3
- package/dist/cli.js +3828 -2948
- package/dist/components.js +23 -23
- package/dist/components.js.map +2 -2
- package/dist/config.js +2 -2
- package/dist/config.js.map +2 -2
- package/dist/data.js +1 -1
- package/dist/data.js.map +1 -1
- package/dist/index.js +23 -26
- package/dist/index.js.map +2 -2
- package/dist/templates/ai/ai/agents/assistant.ts +5 -3
- package/dist/templates/ai/ai/prompts/assistant.ts +7 -6
- package/dist/templates/ai/ai/tools/.gitkeep +0 -0
- package/dist/templates/ai/app/page.tsx +7 -13
- package/dist/templates/app/app/dashboard/page.tsx +5 -5
- package/dist/templates/app/app/layout.tsx +2 -2
- package/dist/templates/app/app/login/page.tsx +53 -125
- package/dist/templates/app/components/DashboardLayout.tsx +29 -95
- package/dist/templates/app/components/FeatureGrid.tsx +24 -30
- package/dist/templates/app/components/Header.tsx +13 -16
- package/dist/templates/app/components/HeroSection.tsx +19 -29
- package/dist/templates/blog/app/layout.tsx +13 -13
- package/dist/templates/blog/app/page.tsx +2 -2
- package/dist/templates/blog/components/BlogPostList.tsx +15 -24
- package/dist/templates/docs/app/layout.tsx +4 -4
- package/dist/templates/docs/components/Header.tsx +25 -22
- package/dist/templates/docs/components/Sidebar.tsx +8 -8
- package/dist/templates/minimal/app/layout.tsx +4 -2
- package/dist/templates/minimal/app/page.tsx +8 -8
- package/package.json +1 -1
- package/dist/templates/ai/ai/tools/get-weather.ts +0 -29
|
@@ -3,90 +3,84 @@ const features = [
|
|
|
3
3
|
title: "Authentication",
|
|
4
4
|
description: "Secure user authentication with sessions and JWT tokens",
|
|
5
5
|
icon: (
|
|
6
|
-
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
7
|
-
<path strokeLinecap="round" strokeLinejoin="round"
|
|
6
|
+
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
|
7
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z" />
|
|
8
8
|
</svg>
|
|
9
9
|
),
|
|
10
|
-
color: "bg-blue-500",
|
|
11
10
|
},
|
|
12
11
|
{
|
|
13
12
|
title: "API Routes",
|
|
14
13
|
description: "Full-featured API with middleware and validation",
|
|
15
14
|
icon: (
|
|
16
|
-
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
17
|
-
<path strokeLinecap="round" strokeLinejoin="round"
|
|
15
|
+
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
|
16
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" />
|
|
18
17
|
</svg>
|
|
19
18
|
),
|
|
20
|
-
color: "bg-purple-500",
|
|
21
19
|
},
|
|
22
20
|
{
|
|
23
21
|
title: "Database Ready",
|
|
24
22
|
description: "Easy to connect any database with our data layer",
|
|
25
23
|
icon: (
|
|
26
|
-
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
27
|
-
<path strokeLinecap="round" strokeLinejoin="round"
|
|
24
|
+
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
|
25
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125" />
|
|
28
26
|
</svg>
|
|
29
27
|
),
|
|
30
|
-
color: "bg-pink-500",
|
|
31
28
|
},
|
|
32
29
|
{
|
|
33
30
|
title: "Type Safe",
|
|
34
31
|
description: "Full TypeScript support with runtime validation",
|
|
35
32
|
icon: (
|
|
36
|
-
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
37
|
-
<path strokeLinecap="round" strokeLinejoin="round"
|
|
33
|
+
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
|
34
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
38
35
|
</svg>
|
|
39
36
|
),
|
|
40
|
-
color: "bg-green-500",
|
|
41
37
|
},
|
|
42
38
|
{
|
|
43
39
|
title: "Modern UI",
|
|
44
40
|
description: "Beautiful components built with Tailwind CSS",
|
|
45
41
|
icon: (
|
|
46
|
-
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
47
|
-
<path strokeLinecap="round" strokeLinejoin="round"
|
|
42
|
+
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
|
43
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M9.53 16.122a3 3 0 00-5.78 1.128 2.25 2.25 0 01-2.4 2.245 4.5 4.5 0 008.4-2.245c0-.399-.078-.78-.22-1.128zm0 0a15.998 15.998 0 003.388-1.62m-5.043-.025a15.994 15.994 0 011.622-3.395m3.42 3.42a15.995 15.995 0 004.764-4.648l3.876-5.814a1.151 1.151 0 00-1.597-1.597L14.146 6.32a15.996 15.996 0 00-4.649 4.763m3.42 3.42a6.776 6.776 0 00-3.42-3.42" />
|
|
48
44
|
</svg>
|
|
49
45
|
),
|
|
50
|
-
color: "bg-orange-500",
|
|
51
46
|
},
|
|
52
47
|
{
|
|
53
48
|
title: "Production Ready",
|
|
54
49
|
description: "Security, caching, and performance optimized",
|
|
55
50
|
icon: (
|
|
56
|
-
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
57
|
-
<path strokeLinecap="round" strokeLinejoin="round"
|
|
51
|
+
<svg className="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
|
52
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M9.75 3.104v5.714a2.25 2.25 0 01-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 014.5 0m0 0v5.714c0 .597.237 1.17.659 1.591L19.8 15.3M14.25 3.104c.251.023.501.05.75.082M19.8 15.3l-1.57.393A9.065 9.065 0 0112 15a9.065 9.065 0 00-6.23.693L5 14.5m14.8.8l1.402 1.402c1.232 1.232.65 3.318-1.067 3.611A48.309 48.309 0 0112 21c-2.773 0-5.491-.235-8.135-.687-1.718-.293-2.3-2.379-1.067-3.61L5 14.5" />
|
|
58
53
|
</svg>
|
|
59
54
|
),
|
|
60
|
-
color: "bg-teal-500",
|
|
61
55
|
},
|
|
62
56
|
];
|
|
63
57
|
|
|
64
58
|
export function FeatureGrid() {
|
|
65
59
|
return (
|
|
66
|
-
<section className="py-24 bg-
|
|
67
|
-
<div className="max-w-
|
|
60
|
+
<section className="py-24 bg-neutral-50 dark:bg-neutral-900/50">
|
|
61
|
+
<div className="max-w-5xl mx-auto px-6">
|
|
68
62
|
<div className="text-center mb-16">
|
|
69
|
-
<h2 className="text-3xl
|
|
70
|
-
Everything
|
|
63
|
+
<h2 className="text-3xl font-bold text-neutral-900 dark:text-white mb-4">
|
|
64
|
+
Everything you need
|
|
71
65
|
</h2>
|
|
72
|
-
<p className="text-
|
|
73
|
-
Start with a solid foundation and
|
|
66
|
+
<p className="text-lg text-neutral-600 dark:text-neutral-400 max-w-xl mx-auto">
|
|
67
|
+
Start with a solid foundation and focus on your product.
|
|
74
68
|
</p>
|
|
75
69
|
</div>
|
|
76
70
|
|
|
77
|
-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-
|
|
71
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
78
72
|
{features.map((feature) => (
|
|
79
73
|
<div
|
|
80
74
|
key={feature.title}
|
|
81
|
-
className="
|
|
75
|
+
className="bg-white dark:bg-neutral-800 rounded-2xl p-6 border border-neutral-200 dark:border-neutral-700"
|
|
82
76
|
>
|
|
83
|
-
<div className=
|
|
77
|
+
<div className="w-10 h-10 bg-blue-500/10 rounded-xl flex items-center justify-center text-blue-500 mb-4">
|
|
84
78
|
{feature.icon}
|
|
85
79
|
</div>
|
|
86
|
-
<h3 className="text-
|
|
80
|
+
<h3 className="text-base font-semibold text-neutral-900 dark:text-white mb-2">
|
|
87
81
|
{feature.title}
|
|
88
82
|
</h3>
|
|
89
|
-
<p className="text-
|
|
83
|
+
<p className="text-sm text-neutral-600 dark:text-neutral-400">
|
|
90
84
|
{feature.description}
|
|
91
85
|
</p>
|
|
92
86
|
</div>
|
|
@@ -95,4 +89,4 @@ export function FeatureGrid() {
|
|
|
95
89
|
</div>
|
|
96
90
|
</section>
|
|
97
91
|
);
|
|
98
|
-
}
|
|
92
|
+
}
|
|
@@ -7,29 +7,26 @@ export function Header() {
|
|
|
7
7
|
const { user, logout } = useAuth();
|
|
8
8
|
|
|
9
9
|
return (
|
|
10
|
-
<header className="bg-white
|
|
11
|
-
<nav className="max-w-
|
|
12
|
-
<div className="flex justify-between h-
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
</a>
|
|
17
|
-
</div>
|
|
10
|
+
<header className="sticky top-0 z-50 bg-white/80 dark:bg-neutral-900/80 backdrop-blur-lg border-b border-neutral-200 dark:border-neutral-800">
|
|
11
|
+
<nav className="max-w-5xl mx-auto px-6">
|
|
12
|
+
<div className="flex justify-between h-14 items-center">
|
|
13
|
+
<a href="/" className="text-lg font-semibold text-neutral-900 dark:text-white">
|
|
14
|
+
My App
|
|
15
|
+
</a>
|
|
18
16
|
|
|
19
|
-
<div className="flex items-center
|
|
17
|
+
<div className="flex items-center gap-6">
|
|
20
18
|
{user ? (
|
|
21
19
|
<>
|
|
22
20
|
<a
|
|
23
21
|
href="/dashboard"
|
|
24
|
-
className="text-
|
|
22
|
+
className="text-sm text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors"
|
|
25
23
|
>
|
|
26
24
|
Dashboard
|
|
27
25
|
</a>
|
|
28
|
-
<span className="text-
|
|
29
|
-
<span className="text-gray-700">{user.name}</span>
|
|
26
|
+
<span className="text-sm text-neutral-500">{user.name}</span>
|
|
30
27
|
<button
|
|
31
28
|
onClick={logout}
|
|
32
|
-
className="text-
|
|
29
|
+
className="text-sm text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors"
|
|
33
30
|
>
|
|
34
31
|
Sign out
|
|
35
32
|
</button>
|
|
@@ -38,13 +35,13 @@ export function Header() {
|
|
|
38
35
|
<>
|
|
39
36
|
<a
|
|
40
37
|
href="/login"
|
|
41
|
-
className="text-
|
|
38
|
+
className="text-sm text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors"
|
|
42
39
|
>
|
|
43
40
|
Sign in
|
|
44
41
|
</a>
|
|
45
42
|
<a
|
|
46
43
|
href="/register"
|
|
47
|
-
className="px-4 py-2 bg-
|
|
44
|
+
className="text-sm px-4 py-2 bg-blue-500 text-white rounded-full hover:bg-blue-600 transition-colors"
|
|
48
45
|
>
|
|
49
46
|
Get started
|
|
50
47
|
</a>
|
|
@@ -55,4 +52,4 @@ export function Header() {
|
|
|
55
52
|
</nav>
|
|
56
53
|
</header>
|
|
57
54
|
);
|
|
58
|
-
}
|
|
55
|
+
}
|
|
@@ -1,49 +1,39 @@
|
|
|
1
1
|
export function HeroSection() {
|
|
2
2
|
return (
|
|
3
|
-
<section className="
|
|
4
|
-
|
|
5
|
-
<div className="absolute inset-0 z-0 opacity-20">
|
|
6
|
-
<div className="absolute top-0 -left-4 w-72 h-72 bg-purple-500 rounded-full mix-blend-multiply filter blur-xl animate-blob"></div>
|
|
7
|
-
<div className="absolute top-0 -right-4 w-72 h-72 bg-indigo-500 rounded-full mix-blend-multiply filter blur-xl animate-blob animation-delay-2000"></div>
|
|
8
|
-
<div className="absolute -bottom-8 left-20 w-72 h-72 bg-pink-500 rounded-full mix-blend-multiply filter blur-xl animate-blob animation-delay-4000"></div>
|
|
9
|
-
</div>
|
|
10
|
-
|
|
11
|
-
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-32">
|
|
3
|
+
<section className="py-24 md:py-32">
|
|
4
|
+
<div className="max-w-5xl mx-auto px-6">
|
|
12
5
|
<div className="text-center max-w-3xl mx-auto">
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
6
|
+
<p className="text-sm font-medium text-blue-500 mb-4">
|
|
7
|
+
Now available
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<h1 className="text-4xl md:text-6xl font-bold tracking-tight text-neutral-900 dark:text-white mb-6">
|
|
11
|
+
Build something
|
|
12
|
+
<br />
|
|
13
|
+
extraordinary.
|
|
21
14
|
</h1>
|
|
22
|
-
|
|
23
|
-
<p className="text-
|
|
15
|
+
|
|
16
|
+
<p className="text-lg text-neutral-600 dark:text-neutral-400 mb-10 max-w-xl mx-auto">
|
|
24
17
|
A modern full-stack application template with authentication,
|
|
25
|
-
API routes, and a beautiful UI.
|
|
18
|
+
API routes, and a beautiful UI.
|
|
26
19
|
</p>
|
|
27
|
-
|
|
20
|
+
|
|
28
21
|
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
|
29
22
|
<a
|
|
30
23
|
href="/register"
|
|
31
|
-
className="px-
|
|
24
|
+
className="px-6 py-3 bg-blue-500 text-white rounded-full font-medium hover:bg-blue-600 transition-colors"
|
|
32
25
|
>
|
|
33
|
-
Get
|
|
26
|
+
Get started
|
|
34
27
|
</a>
|
|
35
28
|
<a
|
|
36
29
|
href="/docs"
|
|
37
|
-
className="px-
|
|
30
|
+
className="px-6 py-3 bg-neutral-100 dark:bg-neutral-800 text-neutral-900 dark:text-white rounded-full font-medium hover:bg-neutral-200 dark:hover:bg-neutral-700 transition-colors"
|
|
38
31
|
>
|
|
39
|
-
|
|
32
|
+
Documentation
|
|
40
33
|
</a>
|
|
41
34
|
</div>
|
|
42
35
|
</div>
|
|
43
36
|
</div>
|
|
44
|
-
|
|
45
|
-
{/* Bottom fade */}
|
|
46
|
-
<div className="absolute bottom-0 left-0 right-0 h-24 bg-gradient-to-t from-slate-50 dark:from-slate-900 to-transparent"></div>
|
|
47
37
|
</section>
|
|
48
38
|
);
|
|
49
|
-
}
|
|
39
|
+
}
|
|
@@ -11,35 +11,35 @@ export default function RootLayout({
|
|
|
11
11
|
children: React.ReactNode
|
|
12
12
|
}) {
|
|
13
13
|
return (
|
|
14
|
-
<div className="min-h-screen bg-
|
|
15
|
-
<header className="bg-white
|
|
16
|
-
<nav className="max-w-
|
|
17
|
-
<div className="flex justify-between items-center">
|
|
18
|
-
<a href="/" className="text-
|
|
14
|
+
<div className="min-h-screen bg-white dark:bg-neutral-900">
|
|
15
|
+
<header className="sticky top-0 z-50 bg-white/80 dark:bg-neutral-900/80 backdrop-blur-lg border-b border-neutral-200 dark:border-neutral-800">
|
|
16
|
+
<nav className="max-w-2xl mx-auto px-6">
|
|
17
|
+
<div className="flex justify-between h-14 items-center">
|
|
18
|
+
<a href="/" className="text-lg font-semibold text-neutral-900 dark:text-white">
|
|
19
19
|
My Blog
|
|
20
20
|
</a>
|
|
21
21
|
<div className="flex gap-6">
|
|
22
|
-
<a href="/" className="text-
|
|
22
|
+
<a href="/" className="text-sm text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors">
|
|
23
23
|
Home
|
|
24
24
|
</a>
|
|
25
|
-
<a href="/about" className="text-
|
|
25
|
+
<a href="/about" className="text-sm text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors">
|
|
26
26
|
About
|
|
27
27
|
</a>
|
|
28
|
-
<a href="/archive" className="text-
|
|
28
|
+
<a href="/archive" className="text-sm text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors">
|
|
29
29
|
Archive
|
|
30
30
|
</a>
|
|
31
31
|
</div>
|
|
32
32
|
</div>
|
|
33
33
|
</nav>
|
|
34
34
|
</header>
|
|
35
|
-
<main className="max-w-
|
|
35
|
+
<main className="max-w-2xl mx-auto px-6 py-12">
|
|
36
36
|
{children}
|
|
37
37
|
</main>
|
|
38
|
-
<footer className="
|
|
39
|
-
<div className="max-w-
|
|
40
|
-
|
|
38
|
+
<footer className="border-t border-neutral-200 dark:border-neutral-800 mt-16">
|
|
39
|
+
<div className="max-w-2xl mx-auto px-6 py-8 text-center text-sm text-neutral-500 dark:text-neutral-400">
|
|
40
|
+
Built with Veryfront
|
|
41
41
|
</div>
|
|
42
42
|
</footer>
|
|
43
43
|
</div>
|
|
44
44
|
);
|
|
45
|
-
}
|
|
45
|
+
}
|
|
@@ -6,8 +6,8 @@ export default async function HomePage() {
|
|
|
6
6
|
|
|
7
7
|
return (
|
|
8
8
|
<div>
|
|
9
|
-
<h1 className="text-
|
|
9
|
+
<h1 className="text-3xl font-bold text-neutral-900 dark:text-white mb-8">Latest Posts</h1>
|
|
10
10
|
<BlogPostList posts={posts} />
|
|
11
11
|
</div>
|
|
12
12
|
);
|
|
13
|
-
}
|
|
13
|
+
}
|
|
@@ -11,43 +11,34 @@ interface Post {
|
|
|
11
11
|
|
|
12
12
|
export function BlogPostList({ posts }: { posts: Post[] }) {
|
|
13
13
|
return (
|
|
14
|
-
<div className="space-y-
|
|
14
|
+
<div className="space-y-10">
|
|
15
15
|
{posts.map(post => (
|
|
16
|
-
<article key={post.slug}
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
>
|
|
16
|
+
<article key={post.slug}>
|
|
17
|
+
<a href={`/blog/${post.slug}`} className="group block">
|
|
18
|
+
<time className="text-sm text-neutral-500 dark:text-neutral-400">
|
|
19
|
+
{formatDate(post.date)}
|
|
20
|
+
</time>
|
|
21
|
+
<h2 className="text-xl font-semibold text-neutral-900 dark:text-white mt-1 group-hover:text-blue-500 transition-colors">
|
|
22
22
|
{post.title}
|
|
23
|
-
</
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
</
|
|
28
|
-
{post.excerpt && (
|
|
29
|
-
<p className="text-gray-700 mb-4">{post.excerpt}</p>
|
|
30
|
-
)}
|
|
23
|
+
</h2>
|
|
24
|
+
{post.excerpt && (
|
|
25
|
+
<p className="text-neutral-600 dark:text-neutral-400 mt-2 line-clamp-2">{post.excerpt}</p>
|
|
26
|
+
)}
|
|
27
|
+
</a>
|
|
31
28
|
{post.tags && (
|
|
32
|
-
<div className="flex gap-2">
|
|
29
|
+
<div className="flex gap-2 mt-3">
|
|
33
30
|
{post.tags.map(tag => (
|
|
34
31
|
<span
|
|
35
32
|
key={tag}
|
|
36
|
-
className="px-2 py-1 bg-
|
|
33
|
+
className="px-2 py-1 bg-neutral-100 dark:bg-neutral-800 text-neutral-600 dark:text-neutral-400 rounded-md text-xs"
|
|
37
34
|
>
|
|
38
35
|
{tag}
|
|
39
36
|
</span>
|
|
40
37
|
))}
|
|
41
38
|
</div>
|
|
42
39
|
)}
|
|
43
|
-
<a
|
|
44
|
-
href={`/blog/${post.slug}`}
|
|
45
|
-
className="text-blue-600 hover:underline mt-2 inline-block"
|
|
46
|
-
>
|
|
47
|
-
Read more →
|
|
48
|
-
</a>
|
|
49
40
|
</article>
|
|
50
41
|
))}
|
|
51
42
|
</div>
|
|
52
43
|
);
|
|
53
|
-
}
|
|
44
|
+
}
|
|
@@ -13,16 +13,16 @@ export default function RootLayout({
|
|
|
13
13
|
children: React.ReactNode
|
|
14
14
|
}) {
|
|
15
15
|
return (
|
|
16
|
-
<div className="min-h-screen bg-white">
|
|
16
|
+
<div className="min-h-screen bg-white dark:bg-neutral-900">
|
|
17
17
|
<Header />
|
|
18
18
|
<div className="flex">
|
|
19
19
|
<Sidebar />
|
|
20
|
-
<main className="flex-1 px-8 py-
|
|
21
|
-
<article className="prose prose-
|
|
20
|
+
<main className="flex-1 px-8 py-8 max-w-3xl">
|
|
21
|
+
<article className="prose prose-neutral dark:prose-invert max-w-none">
|
|
22
22
|
{children}
|
|
23
23
|
</article>
|
|
24
24
|
</main>
|
|
25
25
|
</div>
|
|
26
26
|
</div>
|
|
27
27
|
);
|
|
28
|
-
}
|
|
28
|
+
}
|
|
@@ -6,44 +6,47 @@ export function Header() {
|
|
|
6
6
|
const [searchQuery, setSearchQuery] = useState("");
|
|
7
7
|
|
|
8
8
|
return (
|
|
9
|
-
<header className="
|
|
10
|
-
<div className="px-6
|
|
9
|
+
<header className="sticky top-0 z-50 bg-white/80 dark:bg-neutral-900/80 backdrop-blur-lg border-b border-neutral-200 dark:border-neutral-800">
|
|
10
|
+
<div className="px-6 h-14 flex items-center justify-between">
|
|
11
11
|
<div className="flex items-center gap-8">
|
|
12
|
-
<a href="/" className="text-
|
|
13
|
-
|
|
12
|
+
<a href="/" className="text-lg font-semibold text-neutral-900 dark:text-white">
|
|
13
|
+
Docs
|
|
14
14
|
</a>
|
|
15
15
|
<nav className="flex gap-6">
|
|
16
|
-
<a href="/docs" className="text-
|
|
16
|
+
<a href="/docs" className="text-sm text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors">
|
|
17
17
|
Docs
|
|
18
18
|
</a>
|
|
19
|
-
<a href="/api" className="text-
|
|
19
|
+
<a href="/docs/api" className="text-sm text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors">
|
|
20
20
|
API
|
|
21
21
|
</a>
|
|
22
|
-
<a href="/examples" className="text-
|
|
22
|
+
<a href="/examples" className="text-sm text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors">
|
|
23
23
|
Examples
|
|
24
24
|
</a>
|
|
25
25
|
</nav>
|
|
26
26
|
</div>
|
|
27
27
|
<div className="flex items-center gap-4">
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
<div className="relative">
|
|
29
|
+
<svg className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
|
30
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
|
|
31
|
+
</svg>
|
|
32
|
+
<input
|
|
33
|
+
type="search"
|
|
34
|
+
placeholder="Search..."
|
|
35
|
+
value={searchQuery}
|
|
36
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
37
|
+
className="w-48 pl-9 pr-4 py-2 bg-neutral-100 dark:bg-neutral-800 border-0 rounded-lg text-sm text-neutral-900 dark:text-white placeholder-neutral-400 focus:outline-none focus:ring-2 focus:ring-blue-500/30"
|
|
38
|
+
/>
|
|
39
|
+
</div>
|
|
39
40
|
<a
|
|
40
|
-
href="https://github.com
|
|
41
|
-
className="text-
|
|
41
|
+
href="https://github.com"
|
|
42
|
+
className="text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors"
|
|
42
43
|
>
|
|
43
|
-
|
|
44
|
+
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
|
45
|
+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
|
46
|
+
</svg>
|
|
44
47
|
</a>
|
|
45
48
|
</div>
|
|
46
49
|
</div>
|
|
47
50
|
</header>
|
|
48
51
|
);
|
|
49
|
-
}
|
|
52
|
+
}
|
|
@@ -37,22 +37,22 @@ export function Sidebar() {
|
|
|
37
37
|
}, []);
|
|
38
38
|
|
|
39
39
|
return (
|
|
40
|
-
<aside className="w-
|
|
41
|
-
<nav className="p-
|
|
40
|
+
<aside className="w-56 shrink-0 border-r border-neutral-200 dark:border-neutral-800 min-h-[calc(100vh-3.5rem)]">
|
|
41
|
+
<nav className="p-4 space-y-6 sticky top-14">
|
|
42
42
|
{navigation.map((section) => (
|
|
43
43
|
<div key={section.title}>
|
|
44
|
-
<h3 className="font-semibold text-
|
|
44
|
+
<h3 className="text-xs font-semibold text-neutral-500 dark:text-neutral-400 uppercase tracking-wider mb-2 px-3">
|
|
45
45
|
{section.title}
|
|
46
46
|
</h3>
|
|
47
|
-
<ul className="space-y-
|
|
47
|
+
<ul className="space-y-0.5">
|
|
48
48
|
{section.items.map((item) => (
|
|
49
49
|
<li key={item.href}>
|
|
50
50
|
<a
|
|
51
51
|
href={item.href}
|
|
52
|
-
className={`block px-3 py-1.5 text-sm rounded-
|
|
52
|
+
className={`block px-3 py-1.5 text-sm rounded-lg transition-colors ${
|
|
53
53
|
pathname === item.href
|
|
54
|
-
? "bg-blue-
|
|
55
|
-
: "text-
|
|
54
|
+
? "bg-blue-500/10 text-blue-500 font-medium"
|
|
55
|
+
: "text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800"
|
|
56
56
|
}`}
|
|
57
57
|
>
|
|
58
58
|
{item.title}
|
|
@@ -65,4 +65,4 @@ export function Sidebar() {
|
|
|
65
65
|
</nav>
|
|
66
66
|
</aside>
|
|
67
67
|
);
|
|
68
|
-
}
|
|
68
|
+
}
|
|
@@ -4,8 +4,10 @@ export default function RootLayout({
|
|
|
4
4
|
children: React.ReactNode;
|
|
5
5
|
}) {
|
|
6
6
|
return (
|
|
7
|
-
<div className="
|
|
8
|
-
|
|
7
|
+
<div className="min-h-screen bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-100">
|
|
8
|
+
<main className="max-w-2xl mx-auto px-6 py-16">
|
|
9
|
+
{children}
|
|
10
|
+
</main>
|
|
9
11
|
</div>
|
|
10
12
|
);
|
|
11
13
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
export default function HomePage() {
|
|
2
2
|
return (
|
|
3
|
-
<div
|
|
4
|
-
<h1 className="text-4xl font-bold mb-4">
|
|
3
|
+
<div>
|
|
4
|
+
<h1 className="text-4xl font-bold text-neutral-900 dark:text-white mb-4">
|
|
5
5
|
Welcome to Veryfront
|
|
6
6
|
</h1>
|
|
7
|
-
<p className="text-
|
|
8
|
-
Edit <code className="bg-
|
|
7
|
+
<p className="text-neutral-600 dark:text-neutral-400 mb-8">
|
|
8
|
+
Edit <code className="bg-neutral-100 dark:bg-neutral-800 px-1.5 py-0.5 rounded text-sm">app/page.tsx</code> to get started.
|
|
9
9
|
</p>
|
|
10
|
-
<div className="flex gap-
|
|
10
|
+
<div className="flex gap-3">
|
|
11
11
|
<a
|
|
12
12
|
href="/about"
|
|
13
|
-
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
|
|
13
|
+
className="px-4 py-2 bg-blue-500 text-white rounded-full text-sm font-medium hover:bg-blue-600 transition-colors"
|
|
14
14
|
>
|
|
15
15
|
About
|
|
16
16
|
</a>
|
|
17
17
|
<a
|
|
18
|
-
href="https://
|
|
19
|
-
className="px-4 py-2
|
|
18
|
+
href="https://veryfront.com/docs"
|
|
19
|
+
className="px-4 py-2 bg-neutral-100 dark:bg-neutral-800 text-neutral-900 dark:text-white rounded-full text-sm font-medium hover:bg-neutral-200 dark:hover:bg-neutral-700 transition-colors"
|
|
20
20
|
>
|
|
21
21
|
Documentation
|
|
22
22
|
</a>
|
package/package.json
CHANGED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { tool } from "veryfront/ai";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
|
|
4
|
-
export default tool({
|
|
5
|
-
description: "Get the current weather for a location",
|
|
6
|
-
inputSchema: z.object({
|
|
7
|
-
location: z.string().describe("The city and state, e.g. San Francisco, CA"),
|
|
8
|
-
}),
|
|
9
|
-
execute: ({ location }: { location: string }) => {
|
|
10
|
-
const mockWeather: Record<string, { temp: number; condition: string }> = {
|
|
11
|
-
"San Francisco, CA": { temp: 65, condition: "Foggy" },
|
|
12
|
-
"New York, NY": { temp: 75, condition: "Sunny" },
|
|
13
|
-
"London, UK": { temp: 60, condition: "Rainy" },
|
|
14
|
-
"Tokyo, Japan": { temp: 80, condition: "Humid" },
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const weather = mockWeather[location] || {
|
|
18
|
-
temp: 70,
|
|
19
|
-
condition: "Clear",
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
location,
|
|
24
|
-
temperature: weather.temp,
|
|
25
|
-
condition: weather.condition,
|
|
26
|
-
unit: "fahrenheit",
|
|
27
|
-
};
|
|
28
|
-
},
|
|
29
|
-
});
|