design: add dynamic design-style layout selector for saas, marketplace, and websites
This commit is contained in:
@@ -18,7 +18,7 @@ import {
|
||||
// Entrepreneur path — 4 steps. Each step is a focused question.
|
||||
|
||||
const ENTREP_TOTAL = 4;
|
||||
const ENTREP_STEP_NAMES = ["Type", "Idea", "Goal", "Look"];
|
||||
const ENTREP_STEP_NAMES = ["Type", "Idea", "Style", "Look"];
|
||||
|
||||
const IDEA_PROMPTS = [
|
||||
"A community for indie game devs to swap playtesters, with weekly demo nights",
|
||||
@@ -172,62 +172,88 @@ function EntrepType({ value, onChange }) {
|
||||
);
|
||||
}
|
||||
|
||||
const GOALS = [
|
||||
const SAAS_STYLES = [
|
||||
{
|
||||
id: "first_customer",
|
||||
icon: "🎯",
|
||||
label: "First real customer",
|
||||
desc: "Someone I don't know pays me. Even once.",
|
||||
id: "sidebar",
|
||||
label: "Vertical Sidebar",
|
||||
desc: "Left-side collapsible menu, data-dense. Ideal for CRM/dashboards.",
|
||||
},
|
||||
{
|
||||
id: "ten_users",
|
||||
icon: "👥",
|
||||
label: "Ten weekly users",
|
||||
desc: "A signal the thing actually does something useful.",
|
||||
id: "topbar",
|
||||
label: "Top Horizontal + ⌘K",
|
||||
desc: "Spacious top navigation with global command search bar.",
|
||||
},
|
||||
{
|
||||
id: "mrr_1k",
|
||||
icon: "📈",
|
||||
label: "$1k MRR",
|
||||
desc: "Enough to take it seriously.",
|
||||
},
|
||||
{
|
||||
id: "side_quit",
|
||||
icon: "🚪",
|
||||
label: "Replace my day job",
|
||||
desc: "The long road. Make this the main thing.",
|
||||
},
|
||||
{
|
||||
id: "audience",
|
||||
icon: "📣",
|
||||
label: "Build a tiny audience",
|
||||
desc: "200 emails, a community, something I can talk to.",
|
||||
},
|
||||
{
|
||||
id: "ship_it",
|
||||
icon: "🚀",
|
||||
label: "Just ship it",
|
||||
desc: "I want the thing to exist.",
|
||||
id: "rail",
|
||||
label: "Slim Icon Rail",
|
||||
desc: "Minimalist vertical narrow icon bar, maximizes workspace area.",
|
||||
},
|
||||
];
|
||||
|
||||
function EntrepGoal({ value, onChange }) {
|
||||
const MARKETPLACE_STYLES = [
|
||||
{
|
||||
id: "flux",
|
||||
label: "Dark Glass / Flux",
|
||||
desc: "Modern dark-glass panels with glowing fuchsia aurora backdrops.",
|
||||
},
|
||||
{
|
||||
id: "minimal",
|
||||
label: "Classic Minimal",
|
||||
desc: "Warm parchment neutrals, high-contrast typography and clean grids.",
|
||||
},
|
||||
];
|
||||
|
||||
const GENERAL_STYLES = [
|
||||
{
|
||||
id: "bento",
|
||||
label: "Dark Bento",
|
||||
desc: "Modern dark UI, bento-box card clusters.",
|
||||
},
|
||||
{
|
||||
id: "swiss",
|
||||
label: "Editorial Swiss",
|
||||
desc: "Type-led, gridded, lots of white space — clean and academic.",
|
||||
},
|
||||
{
|
||||
id: "brutalist",
|
||||
label: "Neo-Brutalist",
|
||||
desc: "Bold offsets, thick hand-drawn borders, highly tactile and organic.",
|
||||
},
|
||||
];
|
||||
|
||||
function EntrepStyle({ productType, value, onChange }) {
|
||||
// Dynamically tailor the styles array based on what they picked on Page 2
|
||||
const isSaas = productType === "saas";
|
||||
const isMarketplace = productType === "marketplace";
|
||||
|
||||
const styles = isSaas
|
||||
? SAAS_STYLES
|
||||
: isMarketplace
|
||||
? MARKETPLACE_STYLES
|
||||
: GENERAL_STYLES;
|
||||
|
||||
return (
|
||||
<>
|
||||
<WizardQ
|
||||
title="What does “working” look like?"
|
||||
sub="Helps Vibn decide what to build first — a landing page that converts, or a tool that retains."
|
||||
title="Choose a starting design style"
|
||||
sub={
|
||||
isSaas
|
||||
? "Select the navigation layout that fits your app's density."
|
||||
: isMarketplace
|
||||
? "Select the design aesthetic for your marketplace templates."
|
||||
: "Select the design layout for your custom pages."
|
||||
}
|
||||
/>
|
||||
<PresetGroup
|
||||
options={GOALS.map((g) => ({
|
||||
id: g.id,
|
||||
label: g.label,
|
||||
desc: g.desc,
|
||||
icon: <span style={{ fontSize: 14 }}>{g.icon}</span>,
|
||||
options={styles.map((s) => ({
|
||||
id: s.id,
|
||||
label: s.label,
|
||||
desc: s.desc,
|
||||
icon: undefined,
|
||||
}))}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
columns={2}
|
||||
columns={styles.length === 3 ? 1 : 2}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
@@ -387,9 +413,13 @@ export function EntrepreneurPath({
|
||||
canNext = (data.idea || "").trim().length >= 8;
|
||||
} else if (step === 2) {
|
||||
body = (
|
||||
<EntrepGoal value={data.goal} onChange={(v) => onUpdate({ goal: v })} />
|
||||
<EntrepStyle
|
||||
productType={data.productType}
|
||||
value={data.designStyle || ""}
|
||||
onChange={(v) => onUpdate({ designStyle: v })}
|
||||
/>
|
||||
);
|
||||
canNext = !!data.goal;
|
||||
canNext = !!data.designStyle;
|
||||
} else {
|
||||
body = (
|
||||
<EntrepVibe value={data.vibe} onChange={(v) => onUpdate({ vibe: v })} />
|
||||
|
||||
Reference in New Issue
Block a user