Skip to content

Commit

Permalink
feat: [SC-25978] ✨ Created Randomize mini-app for namegraph.dev
Browse files Browse the repository at this point in the history
  • Loading branch information
FrancoAguzzi committed Dec 23, 2024
1 parent 501b1ae commit a2098b1
Show file tree
Hide file tree
Showing 6 changed files with 287 additions and 19 deletions.
19 changes: 15 additions & 4 deletions apps/namegraph.dev/app/ideate/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "@namehash/namegraph-sdk/utils";
import { WritersBlockPills } from "@/components/mini-apps/ideate/writers-block-pills";
import { Catalog } from "@/components/mini-apps/ideate/catalog";
import { Button } from "@/components/ui/button";

export default function IdeatePage() {
const [suggestions, setSuggestions] = useState<WritersBlockSuggestion[]>([]);
Expand All @@ -35,10 +36,20 @@ export default function IdeatePage() {
<div className="flex flex-col lg:flex-row gap-8">
<div className="flex-1">
<div className="max-w-3xl mx-auto px-4 py-12 text-center">
<WritersBlockPills
suggestions={suggestions}
onIdeate={() => ideate(collectionsToConsider)}
/>
<h1 className="text-2xl font-semibold mb-4">
Check out what&apos;s hot
</h1>
<p className="text-gray-500 mb-8">
Check out some suggestions from the community.
<br /> Edit the catalog in the right to constraint the results
sampled.
</p>
<WritersBlockPills suggestions={suggestions} />
<div className="mt-4">
<Button onClick={() => ideate(collectionsToConsider)}>
Ideate
</Button>
</div>
</div>
</div>
<div className="w-full lg:w-[600px]">
Expand Down
6 changes: 6 additions & 0 deletions apps/namegraph.dev/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ export default function HomePage() {
Explore collections
</Link>
</li>
<li className="flex space-x-1">
<p>➡️</p>
<Link href="/randomize" className="hover:underline">
Randomize
</Link>
</li>
</ul>
</div>
</div>
Expand Down
246 changes: 246 additions & 0 deletions apps/namegraph.dev/app/randomize/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
"use client";

import { useState, useEffect } from "react";
import { Button } from "@namehash/namekit-react";
import {
getCollectionsForQuery,
sampleNamesByCollectionId,
scrambleNamesByCollectionId,
} from "@/lib/utils";
import { DebounceInput } from "react-debounce-input";
import {
NameGraphFetchTopCollectionMembersResponse,
NameGraphGroupedByCategoryResponse,
NameGraphSuggestion,
} from "@namehash/namegraph-sdk/utils";
import { TruncatedText } from "@namehash/namekit-react/client";

export default function RandomizePage() {
const [suggestions, setSuggestions] = useState<
NameGraphGroupedByCategoryResponse | undefined
>(undefined);

const [sampledSuggestions, setSampledSuggestions] = useState<
NameGraphSuggestion[] | undefined
>(undefined);

const [scrambledSuggestions, setScrambledSuggestions] = useState<
NameGraphSuggestion[] | undefined
>(undefined);

const suggest = () => {
setError(false);
setSelectedCollection(undefined);
setSampledSuggestions(undefined);
setScrambledSuggestions(undefined);

let query = debouncedValue;
if (debouncedValue.includes(".")) {
query = debouncedValue.split(".")[0];
}

setSuggestions(undefined);
getCollectionsForQuery(query)
.then((res) => setSuggestions(res))
.catch(() => setError(true));
};

const sample = () => {
setError(false);

if (!selectedCollection?.collection_id) {
setError(true);
throw new Error("Selected collection has no collection ID");
}

setSampledSuggestions(undefined);
sampleNamesByCollectionId(selectedCollection.collection_id)
.then((res) => setSampledSuggestions(res))
.catch(() => setError(true));
};

const scramble = () => {
setError(false);

if (!selectedCollection?.collection_id) {
setError(true);
throw new Error("Selected collection has no collection ID");
}

setScrambledSuggestions(undefined);
scrambleNamesByCollectionId(selectedCollection.collection_id)
.then((res) => setScrambledSuggestions(res))
.catch(() => setError(true));
};

const [debouncedValue, setDebouncedValue] = useState("");
const [error, setError] = useState(false);

useEffect(() => {
if (debouncedValue) {
suggest();
} else {
setSuggestions(undefined);
setError(false);
}
}, [debouncedValue]);

const [selectedCollection, setSelectedCollection] = useState<
NameGraphFetchTopCollectionMembersResponse | undefined
>(undefined);

useEffect(() => {
setSampledSuggestions(undefined);
setScrambledSuggestions(undefined);
}, [selectedCollection]);

return (
<div className="container mx-auto py-8 flex flex-col items-center">
<h1 className="text-xl font-semibold mt-4 mb-8 text-center">
🌪️ Query something to start the brainstorm 🧠
</h1>
<DebounceInput
id="query"
type="text"
name="query"
autoComplete="off"
debounceTimeout={300}
onChange={(e) => setDebouncedValue(e.target.value)}
className="w-[80%] bg-gray-100 border border-gray-300 rounded-md p-3 px-4"
/>

{error ? (
<p className="underline text-red-400 text-xs mx-auto text-center pt-6">
Please try again shortly, we had a network error while executing your
request.
</p>
) : suggestions?.categories.length ? (
<>
{debouncedValue && (
<div className="mt-8">
<h3 className="text-xl font-semibold mt-4 mb-8 text-center">
🕸️ Select the collection you want to focus on 🔀
</h3>
<div className="flex flex-wrap gap-2 items-center max-w-3xl justify-center">
{suggestions?.categories
? suggestions?.categories.map((category) => {
return (
<>
{category.collection_id ? (
<Button
variant={
selectedCollection?.name === category.name
? "primary"
: "ghost"
}
key={category.name}
onClick={() => setSelectedCollection(category)}
>
{category.name}
</Button>
) : null}
</>
);
})
: null}
</div>
</div>
)}
{selectedCollection && (
<div className="w-full flex flex-col lg:flex-row gap-8 mt-16">
<div className="lg:w-1/3 max-w-3xl mx-auto px-4 text-center min-w-[180px] flex flex-col items-center">
<h1 className="text-center text-xl font-semibold mb-4">
🎰 Generated names 🎰
</h1>
{suggestions?.categories.length && (
<div className="flex flex-col items-center">
<div className="flex flex-wrap gap-2 justify-center">
<div className="w-full mt-8 mb-12">
<div className="flex flex-col space-y-3 flex-wrap gap-2 justify-center">
{suggestions.categories
.find(
(collection) =>
collection.name === selectedCollection.name,
)
?.suggestions.map((suggestion, i) => (
<TruncatedText
maxDisplayWidth={180}
key={i}
text={suggestion.name}
/>
))}
</div>
</div>
</div>
</div>
)}
</div>
<div className="flex-1">
<div className="lg:w-1/3 max-w-3xl mx-auto px-4 text-center min-w-[180px] flex flex-col items-center">
<h1 className="text-center text-xl font-semibold mb-4 w-max">
🃏 Sampled names 🃏
</h1>
{selectedCollection ? (
<Button
variant="secondary"
className="mt-8"
onClick={sample}
>
Sample
</Button>
) : null}
<div className="flex flex-col items-center">
<div className="flex flex-wrap gap-2 justify-center">
<div className="w-full mt-8 mb-12">
<div className="flex flex-col space-y-3 flex-wrap gap-2 justify-center">
{sampledSuggestions?.map((suggestion, i) => (
<TruncatedText
maxDisplayWidth={180}
key={i}
text={suggestion.name}
/>
))}
</div>
</div>
</div>
</div>
</div>
</div>
<div className="flex-1">
<div className="lg:w-1/3 max-w-3xl mx-auto px-4 text-center min-w-[180px] flex flex-col items-center">
<h1 className="text-center text-xl font-semibold mb-4 w-max">
🥣 Scramble names 🥣
</h1>
{selectedCollection ? (
<Button
variant="secondary"
className="mt-8"
onClick={scramble}
>
Scramble
</Button>
) : null}
<div className="flex flex-col items-center">
<div className="flex flex-wrap gap-2 justify-center">
<div className="w-full mt-8 mb-12">
<div className="flex flex-col space-y-3 flex-wrap gap-2 justify-center">
{scrambledSuggestions?.map((suggestion, i) => (
<TruncatedText
maxDisplayWidth={180}
key={i}
text={suggestion.name}
/>
))}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)}
</>
) : null}
</div>
);
}
2 changes: 1 addition & 1 deletion apps/namegraph.dev/components/mini-apps/ideate/catalog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function Catalog({ onJsonChange }: CatalogProps) {
value={jsonText}
ref={catalogTextarea}
onChange={handleJsonChange}
className="w-full h-full min-h-[500px] font-mono text-sm"
className="w-full h-full min-h-[450px] font-mono text-sm"
/>
{hasJSONFormatError ? (
<p className="underline text-red-400 text-xs mx-auto text-center pt-6">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
import { Button } from "../../ui/button";
import { WritersBlockSuggestion } from "@namehash/namegraph-sdk/utils";
import { WritersBlockPill } from "./writers-block-pill";

interface WritersBlockPillsProps {
suggestions: WritersBlockSuggestion[];
onIdeate: () => void;
}

export function WritersBlockPills({
suggestions,
onIdeate,
}: WritersBlockPillsProps) {
export function WritersBlockPills({ suggestions }: WritersBlockPillsProps) {
return (
<>
<h1 className="text-2xl font-semibold mb-4">Check out what&apos;s hot</h1>
<p className="text-gray-500 mb-8">
Check out some suggestions from the community.
<br /> Edit the catalog in the right to constraint the results sampled.
</p>
{suggestions.length ? (
<div className="flex flex-col space-y-3">
<div className="flex flex-wrap gap-2 justify-center">
{suggestions.map((suggestion, idx) => (
<WritersBlockPill key={idx} suggestion={suggestion} />
))}
</div>
<div>
<Button onClick={onIdeate}>Ideate</Button>
</div>
</div>
) : null}
</>
Expand Down
18 changes: 18 additions & 0 deletions apps/namegraph.dev/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,21 @@ export const getCollectionsForQuery = async (

return nameGeneratorSuggestions;
};

export const sampleNamesByCollectionId = async (
collectionId: string,
): Promise<NameGraphSuggestion[]> => {
const nameGeneratorSuggestions =
await NameGraphClient.sampleCollectionMembers(collectionId);

return nameGeneratorSuggestions;
};

export const scrambleNamesByCollectionId = async (
collectionId: string,
): Promise<NameGraphSuggestion[]> => {
const nameGeneratorSuggestions =
await NameGraphClient.scrambleCollectionTokens(collectionId);

return nameGeneratorSuggestions;
};

0 comments on commit a2098b1

Please sign in to comment.