Spaces:
Running
Running
File size: 3,164 Bytes
702763e e4741e5 702763e 3c7c2dc 702763e bab2147 702763e bab2147 702763e e4741e5 702763e bab2147 e4741e5 702763e e4741e5 702763e 704ade6 702763e bab2147 702763e e4741e5 702763e e4741e5 bab2147 702763e bab2147 702763e 56b5482 702763e e4741e5 702763e bab2147 702763e bab2147 702763e bab2147 e4741e5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
"use client";
import { useState } from "react";
import Image from "next/image";
import classNames from "classnames";
import satori from "satori";
import { roast } from "@/app/actions/roast";
import { share, ShareProps } from "@/app/actions/share";
import { Form, FormProps } from "@/components/form";
import { CopyToClipboard } from "@/components/copy";
import { Quote } from "@/components/quote";
import Logo from "@/assets/logo.svg";
export default function Home() {
const [data, setData] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const [loadingShare, setLoadingShare] = useState(false);
const [hfUser, setHfUser] = useState<string | undefined>(undefined);
const [quote, setQuote] = useState<string | undefined>(undefined);
const handleRoast = async (form: FormProps) => {
setError("");
setData("");
setLoading(true);
const res: {
error?: string;
data?: any;
} = await roast(form);
if (res.error) {
setError(res.error);
} else {
setQuote(undefined);
setHfUser(form.username);
setData(res?.data);
}
setLoading(false);
};
const handleShare = async (form: ShareProps) => {
setLoadingShare(true);
const res = await share({ hf_user: form.hf_user, text: form.text });
if (res?.data) {
setQuote(res.data.id);
}
setLoadingShare(false);
};
return (
<>
<div className="max-w-2xl w-full border border-gray-200 bg-white rounded-3xl p-8 grid gap-8 shadow-xl shadow-black/5">
<header className="flex items-start max-lg:gap-1 lg:items-center justify-between max-lg:flex-col border-b border-zinc-200 pb-5">
<Image
src={Logo}
alt="logo hugging face"
width={100}
height={100}
className="object-contain w-36 lg:w-44"
/>
<div>
<p className="text-sm text-zinc-500">
Roast your favorite Hugging Face user! 👹
</p>
</div>
</header>
{error && (
<div className="text-sm text-red-600 bg-red-500/10 border-[1px] border-red-500/15 px-3.5 py-2.5 rounded-xl">
<p className="font-semibold text-sm">Oops!</p>
{error}
</div>
)}
<Form loading={loading} onSubmit={handleRoast} />
</div>
{data && (
<Quote data={data}>
{quote ? (
<CopyToClipboard id={quote} />
) : (
<button
className={classNames(
"bg-black rounded-full mt-4 px-4 py-2.5 text-sm font-medium text-white hover:bg-zinc-800 disabled:bg-zinc-300 disabled:text-zinc-500 disabled:cursor-not-allowed",
{
"animate-pulse": loadingShare,
}
)}
disabled={loadingShare}
onClick={() =>
hfUser && handleShare({ hf_user: hfUser, text: data })
}
>
{loadingShare ? "Creating a quote..." : "Share my roast!"}
</button>
)}
</Quote>
)}
</>
);
}
|