Inspiration prompts for home screen (#38)
This commit is contained in:
@@ -8,11 +8,12 @@ import { useLoadApps } from "@/hooks/useLoadApps";
|
||||
import { useSettings } from "@/hooks/useSettings";
|
||||
import { SetupBanner } from "@/components/SetupBanner";
|
||||
import { isPreviewOpenAtom } from "@/atoms/viewAtoms";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { useStreamChat } from "@/hooks/useStreamChat";
|
||||
import { HomeChatInput } from "@/components/chat/HomeChatInput";
|
||||
import { usePostHog } from "posthog-js/react";
|
||||
import { PrivacyBanner } from "@/components/TelemetryBanner";
|
||||
import { INSPIRATION_PROMPTS } from "@/prompts/inspiration_prompts";
|
||||
|
||||
export default function HomePage() {
|
||||
const [inputValue, setInputValue] = useAtom(homeChatInputValueAtom);
|
||||
@@ -28,6 +29,22 @@ export default function HomePage() {
|
||||
// Get the appId from search params
|
||||
const appId = search.appId ? Number(search.appId) : null;
|
||||
|
||||
// State for random prompts
|
||||
const [randomPrompts, setRandomPrompts] = useState<
|
||||
typeof INSPIRATION_PROMPTS
|
||||
>([]);
|
||||
|
||||
// Function to get random prompts
|
||||
const getRandomPrompts = useCallback(() => {
|
||||
const shuffled = [...INSPIRATION_PROMPTS].sort(() => 0.5 - Math.random());
|
||||
return shuffled.slice(0, 5);
|
||||
}, []);
|
||||
|
||||
// Initialize random prompts
|
||||
useEffect(() => {
|
||||
setRandomPrompts(getRandomPrompts());
|
||||
}, [getRandomPrompts]);
|
||||
|
||||
// Redirect to app details page if appId is present
|
||||
useEffect(() => {
|
||||
if (appId) {
|
||||
@@ -92,89 +109,59 @@ export default function HomePage() {
|
||||
<div className="w-full">
|
||||
<HomeChatInput onSubmit={handleSubmit} />
|
||||
|
||||
<div className="flex flex-wrap gap-4 mt-4">
|
||||
{[
|
||||
{
|
||||
icon: (
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"
|
||||
/>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
label: "TODO list app",
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1h2a1 1 0 001-1v-7m-6 0a1 1 0 00-1 1v3"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
label: "Landing Page",
|
||||
},
|
||||
{
|
||||
icon: (
|
||||
<svg
|
||||
className="w-5 h-5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
label: "Sign Up Form",
|
||||
},
|
||||
].map((item, index) => (
|
||||
<button
|
||||
type="button"
|
||||
key={index}
|
||||
onClick={() => setInputValue(`Build me a ${item.label}`)}
|
||||
className="flex items-center gap-3 px-4 py-2 rounded-xl border border-gray-200
|
||||
bg-white/50 backdrop-blur-sm
|
||||
transition-all duration-200
|
||||
hover:bg-white hover:shadow-md hover:border-gray-300
|
||||
active:scale-[0.98]
|
||||
dark:bg-gray-800/50 dark:border-gray-700
|
||||
dark:hover:bg-gray-800 dark:hover:border-gray-600"
|
||||
<div className="flex flex-col gap-4 mt-4">
|
||||
<div className="flex flex-wrap gap-4 justify-center">
|
||||
{randomPrompts.map((item, index) => (
|
||||
<button
|
||||
type="button"
|
||||
key={index}
|
||||
onClick={() => setInputValue(`Build me a ${item.label}`)}
|
||||
className="flex items-center gap-3 px-4 py-2 rounded-xl border border-gray-200
|
||||
bg-white/50 backdrop-blur-sm
|
||||
transition-all duration-200
|
||||
hover:bg-white hover:shadow-md hover:border-gray-300
|
||||
active:scale-[0.98]
|
||||
dark:bg-gray-800/50 dark:border-gray-700
|
||||
dark:hover:bg-gray-800 dark:hover:border-gray-600"
|
||||
>
|
||||
<span className="text-gray-700 dark:text-gray-300">
|
||||
{item.icon}
|
||||
</span>
|
||||
<span className="text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
{item.label}
|
||||
</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setRandomPrompts(getRandomPrompts())}
|
||||
className="self-center flex items-center gap-2 px-4 py-2 rounded-xl border border-gray-200
|
||||
bg-white/50 backdrop-blur-sm
|
||||
transition-all duration-200
|
||||
hover:bg-white hover:shadow-md hover:border-gray-300
|
||||
active:scale-[0.98]
|
||||
dark:bg-gray-800/50 dark:border-gray-700
|
||||
dark:hover:bg-gray-800 dark:hover:border-gray-600"
|
||||
>
|
||||
<svg
|
||||
className="w-5 h-5 text-gray-700 dark:text-gray-300"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<span className="text-gray-700 dark:text-gray-300">
|
||||
{item.icon}
|
||||
</span>
|
||||
<span className="text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
{item.label}
|
||||
</span>
|
||||
</button>
|
||||
))}
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
|
||||
/>
|
||||
</svg>
|
||||
<span className="text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
More ideas
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<PrivacyBanner />
|
||||
|
||||
Reference in New Issue
Block a user