Skip to content

Commit

Permalink
add payment
Browse files Browse the repository at this point in the history
  • Loading branch information
idoubi committed Apr 14, 2024
1 parent 7bb6fe8 commit 5961d08
Show file tree
Hide file tree
Showing 48 changed files with 1,876 additions and 262 deletions.
291 changes: 274 additions & 17 deletions app/[locale]/(default)/_components/generator/describe.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,170 @@
"use client";

import { Dispatch, SetStateAction, useState } from "react";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { useEffect, useState } from "react";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import Link from "next/link";
import { Switch } from "@/components/ui/switch";
import { Textarea } from "@/components/ui/textarea";
import { toast } from "sonner";
import { useAppContext } from "@/contexts/app";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation";

export default function () {
const t = useTranslations("create.form");
const styles = [
{
label: "rock",
value: "rock",
},
{
label: "electronic",
value: "electronic",
},
{
label: "pop",
value: "pop",
},
{
label: "jazz",
value: "jazz",
},
{
label: "classical",
value: "classical",
},
{
label: "hip hop",
value: "hip hop",
},
{
label: "pop rock",
value: "pop rock",
},
{
label: "indie rock",
value: "indie rock",
},
{
label: "alternative rock",
value: "alternative rock",
},
{
label: "folk",
value: "folk",
},
{
label: "punk",
value: "punk",
},
{
label: "blues",
value: "blues",
},
{
label: "experimental",
value: "experimental",
},
{
label: "ambient",
value: "ambient",
},
{
label: "synth-pop",
value: "synth-pop",
},
{
label: "hard rock",
value: "hard rock",
},
{
label: "downtempo",
value: "downtempo",
},
{
label: "heavy metal",
value: "heavy metal",
},
{
label: "house",
value: "house",
},
{
label: "electro",
value: "electro",
},
{
label: "soul",
value: "soul",
},
{
label: "country",
value: "country",
},
{
label: "folk rock",
value: "folk rock",
},
{
label: "melodic",
value: "melodic",
},
{
label: "latin",
value: "latin",
},
];

const router = useRouter();
const [description, setDescription] = useState("");
const [tags, setTags] = useState<string[]>([]);
const [mode, setMode] = useState("quick");
const [title, setTitle] = useState("");
const [lyrics, setLyrics] = useState("");
const [isNoLyrics, setIsNoLyrics] = useState(false);
const [loading, setLoading] = useState(false);
const {
songTaskStep: step,
setSongTaskStep: setStep,
setSongTask,
userCredits,
setUserCredits,
} = useAppContext();

const fetchUserCredits = async function () {
try {
const resp = await fetch("/api/get-user-credits", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
const { code, message, data } = await resp.json();
console.log("user credits", data);
if (data) {
setUserCredits(data);
}
} catch (e) {
console.log("get user credits failed:", e);
}
};

const fetchGenLyrics = async function (description: string) {
try {
const params = {
description,
tags: tags.join(","),
is_no_lyrics: isNoLyrics,
lyrics: lyrics,
title: title,
mode: mode,
};
console.log("params", params);

setLoading(true);
const resp = await fetch("/api/gen-song-lyrics", {
const resp = await fetch("/api/gen-song", {
method: "POST",
headers: {
"Content-Type": "application/json",
Expand All @@ -41,9 +179,12 @@ export default function () {
return;
}

console.log("gen song lyrics:", data);
fetchUserCredits();

console.log("gen song result:", data);
setSongTask(data || {});
setStep(2);

router.push("/creations");
} catch (e) {
setLoading(false);

Expand All @@ -53,24 +194,132 @@ export default function () {
};

const handleSubmit = async function () {
if (!description) {
toast.error("please input song description");
if (mode === "custom") {
if (!title) {
toast.error("please input song title");
return;
}
if (!isNoLyrics && !lyrics) {
toast.error("please input song lyrics");
return;
}
if (tags.length === 0) {
toast.error("please choose music style");
return;
}
if (tags.length > 5) {
toast.error("music style no more than 5 tags");
return;
}
} else {
if (!description) {
toast.error("please input song description");
return;
}
}

if (!userCredits || userCredits.left_credits < 1) {
toast.error("credits not enough");
return;
}

fetchGenLyrics(description);
};

useEffect(() => {
console.log("tags updated", tags);
}, [tags]);

return (
<div>
<Tabs value={mode} onValueChange={(v) => setMode(v)} className="max-w-3xl">
<TabsList className="grid w-full grid-cols-2 bg-base-200">
<TabsTrigger value="quick">Quick Mode</TabsTrigger>
<TabsTrigger value="custom">Custom Mode</TabsTrigger>
</TabsList>
<TabsContent value="quick">
<div>
<div className="mt-4">
<p className="text-sm text-base-content">Song Description</p>
<Textarea
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder={`a song about driving on the road`}
className="mt-2 bg-base-200 border-base-300"
/>
</div>
</div>
</TabsContent>
<TabsContent value="custom">
<div className="mt-4">
<p className="text-sm text-base-content">Song Title</p>
<Input
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder={`Five Hundred Miles`}
className="mt-4 bg-base-200 border-base-300"
/>
</div>

{!isNoLyrics && (
<div className="mt-4">
<p className="text-sm text-base-content">Lyrics</p>
<Textarea
value={lyrics}
onChange={(e) => setLyrics(e.target.value)}
placeholder={`Your custom lyrics`}
className="mt-2 bg-base-200 border-base-300"
rows={2}
/>
</div>
)}
</TabsContent>

<div className="mt-4">
<p className="text-sm text-base-content">{t("description")}</p>
<Textarea
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder={t("description_placeholder")}
className="mt-2"
<p className="text-sm text-base-content">Style of Music</p>
<p className="flex items-center gap-x-2 flex-wrap py-4">
{styles.map((v: any, idx: number) => {
const tag: string = v["value"];
if (!tag) {
return;
}

return (
<span
className={`bg-base-300 text-sm px-2 py-0 my-1 text-nowrap rounded-full cursor-pointer ${
tags.includes(tag) ? "bg-primary" : ""
}`}
aria-disabled={tags.includes(tag)}
key={idx}
onClick={() => {
setTags((tags: string[]) => {
if (tags.includes(tag)) {
const pos = tags.indexOf(tag);
if (pos !== -1) {
tags.splice(tags.indexOf(tag), 1);
}
} else {
tags.push(tag);
}
console.log("tags", tags);

return [...tags];
});
}}
>
{v["label"]}
</span>
);
})}
</p>
</div>

<div className="flex items-center space-x-2 mt-4">
<Switch
checked={isNoLyrics}
onCheckedChange={(v) => setIsNoLyrics(v)}
className="bg-base-200"
/>
<Label htmlFor="airplane-mode">No Lyrics</Label>
</div>

<div className="mt-4">
Expand All @@ -79,9 +328,17 @@ export default function () {
disabled={loading}
onClick={handleSubmit}
>
{t("genlyrics")}
Create Song
</Button>
</div>
</div>

{userCredits && userCredits.left_credits < 1 && (
<div className="mt-4">
<Link href="/pricing" className="text-primary underline text-sm">
credits not enough, please recharge
</Link>
</div>
)}
</Tabs>
);
}
Loading

0 comments on commit 5961d08

Please sign in to comment.