Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
.next/
.DS_Store
.env*
16 changes: 0 additions & 16 deletions Idea.tsx

This file was deleted.

12 changes: 0 additions & 12 deletions ShareButtons.tsx

This file was deleted.

64 changes: 0 additions & 64 deletions aigiftgen_v101 2/README.md

This file was deleted.

63 changes: 0 additions & 63 deletions aigiftgen_v101 2/app/page.tsx

This file was deleted.

16 changes: 0 additions & 16 deletions aigiftgen_v101 2/components/Idea.tsx

This file was deleted.

12 changes: 0 additions & 12 deletions aigiftgen_v101 2/components/ShareButtons.tsx

This file was deleted.

5 changes: 0 additions & 5 deletions aigiftgen_v101 2/next-env.d.ts

This file was deleted.

4 changes: 0 additions & 4 deletions aigiftgen_v101 2/next.config.js

This file was deleted.

29 changes: 0 additions & 29 deletions aigiftgen_v101 2/package.json

This file was deleted.

6 changes: 0 additions & 6 deletions aigiftgen_v101 2/postcss.config.js

This file was deleted.

Empty file removed aigiftgen_v101 2/public/og.png
Empty file.
13 changes: 0 additions & 13 deletions aigiftgen_v101 2/tailwind.config.ts

This file was deleted.

36 changes: 0 additions & 36 deletions aigiftgen_v101 2/tsconfig.json

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
87 changes: 87 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
'use client';

import { useState } from "react";

import Idea from "@/components/Idea";

export default function Home() {
const [who, setWho] = useState("my brother who loves hiking and bad puns");
const [ideas, setIdeas] = useState<string[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const affiliateTag = process.env.NEXT_PUBLIC_AFFILIATE_TAG || "yourtag-21";

async function generate() {
setLoading(true);
setError(null);

try {
const res = await fetch("/api/gifts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ who }),
});

if (!res.ok) {
throw new Error("Failed to fetch gift ideas");
}

const data = await res.json();
setIdeas(data.ideas || []);
} catch (err: any) {
setError(err.message);
} finally {
setLoading(false);
}
}

return (
<main className="max-w-2xl mx-auto p-6">
<header className="mt-12 mb-8 text-center">
<h1 className="text-4xl font-bold">🎅 AI Gift Generator</h1>
<p className="small mt-2">
Tell AI Santa who you&apos;re shopping for. Get 3–5 witty, spot‑on gift
ideas.
</p>
</header>

<div className="card p-5">
<label className="small">Who is the gift for?</label>
<input
className="input mt-2"
value={who}
onChange={(event) => setWho(event.target.value)}
placeholder="e.g., my dad who grills in winter and collects jazz vinyl"
/>
<div className="flex gap-2 mt-4">
<button
className="btn btn-primary"
onClick={generate}
disabled={loading}
>
{loading ? "Summoning AI Santa…" : "Generate ideas"}
</button>
<a href="/clone" className="btn btn-ghost">
Clone this site → earn too
</a>
</div>
</div>

{error && <div className="card p-4 mt-4 text-red-300">Error: {error}</div>}

<section className="mt-6">
{ideas.map((idea, index) => (
<Idea key={index} idea={idea} affiliateTag={affiliateTag} />
))}
</section>

<footer className="mt-10 text-center small">
Built by AI ·
<a className="link" href="https://aigiftgen.co.uk" target="_blank">
aigiftgen.co.uk
</a>
· Not affiliated with Amazon.
</footer>
</main>
);
}
Loading