Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
samselikoff committed Nov 12, 2024
1 parent a136147 commit 0007889
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 34 deletions.
43 changes: 29 additions & 14 deletions app/api/generateLogo/route.ts → app/api/generate-logo/route.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import Together from 'together-ai';
import { z } from 'zod';
import dedent from "dedent";
import Together from "together-ai";
import { z } from "zod";
// import { Ratelimit } from "@upstash/ratelimit";
// import { Redis } from "@upstash/redis";
import { headers } from 'next/headers';
// import { headers } from "next/headers";

// let ratelimit: Ratelimit | undefined;

Expand All @@ -22,11 +23,11 @@ export async function POST(req: Request) {
const data = z
.object({
companyName: z.string(),
selectedLayout: z.string(),
selectedLogoStyle: z.string(),
selectedPrimaryColor: z.string(),
selectedBackgroundColor: z.string(),
additionalInfo: z.string(),
selectedLayout: z.enum(["Solo", "Side", "Stack"]),
// selectedLogoStyle: z.string(),
// selectedPrimaryColor: z.string(),
// selectedBackgroundColor: z.string(),
// additionalInfo: z.string(),
})
.parse(json);

Expand Down Expand Up @@ -60,38 +61,52 @@ export async function POST(req: Request) {
// }
// }

const prompt = `Design a professional, unique, and memorable logo that effectively represents the brand's identity and values. The logo should be versatile for use across various mediums and sizes, maintaining clarity and impact in both digital and print formats.
const prompt = dedent`Design a professional, unique, and memorable logo for a company that effectively represents the brand's identity and values. The logo should be versatile for use across various mediums and sizes, maintaining clarity and impact in both digital and print formats.
Here are the details:
Here are the company details:
Company name: ${data.companyName}
${
data.selectedLayout === "Solo"
? `Focus solely on creating a minimalist icon or symbol without any accompanying text whatsoever. COMPANY NAME NOT INCLUDED.`
: ""
}
${
data.selectedLayout === "Side"
? `Have the company name placed to the right of logo you generate. Ensure the text and icon are well-aligned for visual balance.`
: ""
}
`;

console.log(prompt);

let response;
try {
response = await client.images.create({
prompt,
model: 'black-forest-labs/FLUX.1.1-pro',
model: "black-forest-labs/FLUX.1.1-pro",
width: 512,
height: 512,
steps: 3,
// @ts-expect-error - this is not typed in the API
response_format: 'base64',
response_format: "base64",
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
return Response.json(
{ error: e.toString() },
{
status: 500,
}
},
);
}

return Response.json(response.data[0]);
}

export const runtime = 'edge';
export const runtime = "edge";

// function getIPAddress() {
// const FALLBACK_IP_ADDRESS = '0.0.0.0';
Expand Down
55 changes: 35 additions & 20 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { ChevronDown, Info } from "lucide-react";
import Image from "next/image";
import { useEffect, useRef, useState } from "react";
import { FormEvent, useEffect, useRef, useState } from "react";
import {
Tooltip,
TooltipContent,
Expand All @@ -16,7 +16,9 @@ import Footer from "./components/footer";
export default function Page() {
const [apiKey, setApiKey] = useState("");
const [companyName, setCompanyName] = useState("");
const [selectedLayout, setSelectedLayout] = useState<string | null>(null);
const [selectedLayout, setSelectedLayout] = useState<
"Solo" | "Side" | "Stack"
>("Solo");
const [selectedLogoStyle, setSelectedLogoStyle] = useState<string | null>(
null,
);
Expand All @@ -36,6 +38,8 @@ export default function Page() {
const primaryDropdownRef = useRef<HTMLDivElement>(null); // Added ref for primary dropdown
const backgroundDropdownRef = useRef<HTMLDivElement>(null); // Added ref for background dropdown

const [b64Image, setb64Image] = useState("");

useEffect(() => {
function handleClickOutside(event: MouseEvent) {
// Added click outside handler
Expand Down Expand Up @@ -77,7 +81,7 @@ export default function Page() {
{ name: "Solo", icon: "/solo.svg" },
{ name: "Side", icon: "/side.svg" },
{ name: "Stack", icon: "/stack.svg" },
];
] as const;

const logoStyles = [
{ name: "Flashy", icon: "/flashy.svg" },
Expand All @@ -91,7 +95,8 @@ export default function Page() {
// setShowAdditionalOptions((prev) => !prev);
// };

const handleGenerateLogo = async () => {
async function handleGenerateLogo(e: FormEvent<HTMLFormElement>) {
e.preventDefault();
setIsLoading(true); // Set loading state to true
// Simulate logo generation logic
// await new Promise((resolve) => setTimeout(resolve, 2000)); // Simulate async operation
Expand All @@ -111,13 +116,12 @@ export default function Page() {
});

const json = await res.json();
console.log(json);

setIsLoading(false); // Reset loading state
};
setb64Image(`data:image/png;base64,${json.b64_json}`);

const handleToggleLayout = (layoutName: string) => {
setSelectedLayout((prev) => (prev === layoutName ? null : layoutName));
};
setIsLoading(false); // Reset loading state
}

const handleToggleLogoStyle = (styleName: string) => {
setSelectedLogoStyle((prev) => (prev === styleName ? null : styleName));
Expand All @@ -142,7 +146,10 @@ export default function Page() {
<Header className="block md:hidden" />{" "}
{/* Show header on small screens */}
<div className="flex w-full flex-col md:flex-row">
<div className="sidebar flex h-full w-full flex-col bg-[#2C2C2C] font-jura text-[#F3F3F3] md:w-auto">
<form
onSubmit={handleGenerateLogo}
className="sidebar flex h-full w-full flex-col bg-[#2C2C2C] font-jura text-[#F3F3F3] md:w-auto"
>
<div className={`flex-grow overflow-y-auto`}>
<div className="px-8 pb-0 pt-4 md:px-6 md:pt-6">
{/* API Key Section */}
Expand Down Expand Up @@ -184,6 +191,7 @@ export default function Page() {
placeholder="Amazon"
aria-label="Company Name"
tabIndex={0}
required
/>
</div>
{/* Layout Section */}
Expand All @@ -204,12 +212,9 @@ export default function Page() {
? "border-2 border-[#F3F3F3]"
: ""
}`}
onClick={() => handleToggleLayout(layout.name)}
onClick={() => setSelectedLayout(layout.name)}
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "Enter")
handleToggleLayout(layout.name);
}}
type="button"
aria-checked={selectedLayout === layout.name}
role="radio"
>
Expand Down Expand Up @@ -451,9 +456,7 @@ export default function Page() {
<button
className="flex w-full items-center justify-center rounded bg-[#F3F3F3] py-[12.5px] text-base font-bold text-[#2C2C2C]"
aria-label="Generate Logo"
tabIndex={0}
onClick={handleGenerateLogo}
onKeyDown={(e) => e.key === "Enter" && handleGenerateLogo()}
type="submit"
disabled={isLoading} // Disable button while loading
>
{isLoading ? ( // Conditional rendering for loading state
Expand All @@ -475,13 +478,25 @@ export default function Page() {
</div> */}
</div>
</div>
</div>
</form>

<div className="flex w-full flex-col">
<Header className="hidden md:block" />{" "}
{/* Show header on larger screens */}
<div className="flex flex-grow items-center justify-center overflow-hidden">
<LogoPlaceholder />
{b64Image ? (
<Image
// placeholder="blur"
// blurDataURL={imagePlaceholder.blurDataURL}
width={512}
height={512}
src={b64Image}
alt=""
// className={`${isFetching ? "animate-pulse" : ""} max-w-full rounded-lg object-cover shadow-sm shadow-black`}
/>
) : (
<LogoPlaceholder />
)}
</div>
<Footer />
</div>
Expand Down
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"dependencies": {
"@radix-ui/react-tooltip": "^1.1.3",
"clsx": "^2.1.1",
"dedent": "^1.5.3",
"lucide-react": "^0.453.0",
"next": "14.2.15",
"react": "^18",
Expand Down

0 comments on commit 0007889

Please sign in to comment.