update stack builder design

This commit is contained in:
Aman Varshney
2025-05-12 20:31:05 +05:30
parent cd7d9f7f30
commit 49f4330f96
2 changed files with 143 additions and 157 deletions

View File

@@ -858,9 +858,9 @@ const StackArchitect = () => {
const [showPresets, setShowPresets] = useState(false); const [showPresets, setShowPresets] = useState(false);
const [showHelp, setShowHelp] = useState(false); const [showHelp, setShowHelp] = useState(false);
const [lastSavedStack, setLastSavedStack] = useState<StackState | null>(null); const [lastSavedStack, setLastSavedStack] = useState<StackState | null>(null);
const [activeCategory, setActiveCategory] = useState<string | null>( // const [activeCategory, setActiveCategory] = useState<string | null>(
CATEGORY_ORDER[0], // CATEGORY_ORDER[0],
); // );
const [, setLastChanges] = useState< const [, setLastChanges] = useState<
Array<{ category: string; message: string }> Array<{ category: string; message: string }>
>([]); >([]);
@@ -915,7 +915,6 @@ const StackArchitect = () => {
setStack(randomStack as StackState); setStack(randomStack as StackState);
setShowHelp(false); setShowHelp(false);
setShowPresets(false); setShowPresets(false);
setActiveCategory(CATEGORY_ORDER[0]);
contentRef.current?.scrollTo(0, 0); contentRef.current?.scrollTo(0, 0);
toast.success("Random stack generated!"); toast.success("Random stack generated!");
}; };
@@ -1480,7 +1479,6 @@ const StackArchitect = () => {
setStack(DEFAULT_STACK); setStack(DEFAULT_STACK);
setShowHelp(false); setShowHelp(false);
setShowPresets(false); setShowPresets(false);
setActiveCategory(CATEGORY_ORDER[0]);
contentRef.current?.scrollTo(0, 0); contentRef.current?.scrollTo(0, 0);
}; };
@@ -1495,7 +1493,6 @@ const StackArchitect = () => {
setStack(lastSavedStack); setStack(lastSavedStack);
setShowHelp(false); setShowHelp(false);
setShowPresets(false); setShowPresets(false);
setActiveCategory(CATEGORY_ORDER[0]);
contentRef.current?.scrollTo(0, 0); contentRef.current?.scrollTo(0, 0);
toast.success("Saved configuration loaded"); toast.success("Saved configuration loaded");
} }
@@ -1509,28 +1506,16 @@ const StackArchitect = () => {
setStack(preset.stack); setStack(preset.stack);
setShowPresets(false); setShowPresets(false);
setShowHelp(false); setShowHelp(false);
setActiveCategory(CATEGORY_ORDER[0]);
contentRef.current?.scrollTo(0, 0); contentRef.current?.scrollTo(0, 0);
toast.success(`Applied preset: ${preset.name}`); toast.success(`Applied preset: ${preset.name}`);
} }
}; };
const handleSidebarClick = (category: string) => {
setActiveCategory(category);
const element = sectionRefs.current[category];
if (element) {
element.scrollIntoView({
behavior: "smooth",
block: "start",
});
}
};
return ( return (
<TooltipProvider> <TooltipProvider>
<div <div
className={cn( className={cn(
"flex h-screen flex-col overflow-hidden border-border bg-background text-foreground", "flex h-svh flex-col overflow-hidden border-border bg-background text-foreground",
)} )}
> >
<div <div
@@ -1644,8 +1629,9 @@ const StackArchitect = () => {
</div> </div>
)} )}
<div className="flex-shrink-0 bg-background p-3 pb-0 font-mono sm:p-4 sm:pb-0"> <div className="grid grid-cols-1 overflow-hidden sm:grid-cols-[auto_1fr]">
<div className="mb-3 flex flex-col justify-between gap-y-3 sm:flex-row sm:items-start"> <div className="flex h-full max-w-full flex-col justify-between border-border border-r p-4 sm:max-w-3xs md:max-w-xs lg:max-w-sm">
<div className="flex flex-col space-y-4">
<label className="flex flex-col"> <label className="flex flex-col">
<span className="mb-1 text-muted-foreground text-xs"> <span className="mb-1 text-muted-foreground text-xs">
Project Name: Project Name:
@@ -1658,7 +1644,7 @@ const StackArchitect = () => {
setStack({ projectName: newValue }); setStack({ projectName: newValue });
}} }}
className={cn( className={cn(
"w-full rounded border bg-background px-2 py-1 font-mono text-sm focus:outline-none sm:w-auto", "w-full rounded border bg-background px-2 py-1 font-mono text-sm focus:outline-none",
projectNameError projectNameError
? "border-destructive bg-destructive/10 text-destructive-foreground" ? "border-destructive bg-destructive/10 text-destructive-foreground"
: "border-border focus:border-primary", : "border-border focus:border-primary",
@@ -1721,20 +1707,19 @@ const StackArchitect = () => {
Share Share
</button> </button>
</div> </div>
</div> <div className="relative rounded border border-border bg-background p-2">
<div className="flex">
<div className="relative mb-4 overflow-hidden rounded border border-border bg-background p-2 pr-16 sm:pr-20">
<div className="flex overflow-x-auto">
<span className="mr-2 select-none text-chart-4">$</span> <span className="mr-2 select-none text-chart-4">$</span>
<code className="no-scrollbar inline-flex items-center overflow-x-auto whitespace-pre break-words text-muted-foreground text-xs sm:text-sm"> <code className="block break-all text-muted-foreground text-xs sm:text-sm">
{command} {command}
</code> </code>
</div> </div>
<div className="mt-2 flex justify-end">
<button <button
type="button" type="button"
onClick={copyToClipboard} onClick={copyToClipboard}
className={cn( className={cn(
"-translate-y-1/2 absolute top-1/2 right-1 flex items-center gap-1 rounded px-2 py-1 text-xs transition-colors", "flex items-center gap-1 rounded px-2 py-1 text-xs transition-colors",
copied copied
? "bg-muted text-chart-4" ? "bg-muted text-chart-4"
: "text-muted-foreground hover:bg-muted hover:text-foreground", : "text-muted-foreground hover:bg-muted hover:text-foreground",
@@ -1754,41 +1739,43 @@ const StackArchitect = () => {
)} )}
</button> </button>
</div> </div>
</div>
<div className="mb-4"> <div>
<h3 className="mb-2 font-medium text-foreground text-sm">
Selected Stack
</h3>
<div className="flex flex-wrap gap-1.5">{selectedBadges}</div> <div className="flex flex-wrap gap-1.5">{selectedBadges}</div>
</div> </div>
</div> </div>
<div className="mt-auto border-border border-t pt-4">
<div className="flex flex-grow overflow-hidden"> <h3 className="mb-2 font-medium text-foreground text-sm">
<nav className="hidden w-48 flex-shrink-0 overflow-y-auto border-border border-r p-2 md:flex"> Quick Presets
<ul className="space-y-1"> </h3>
{CATEGORY_ORDER.map((category) => ( <div className="grid grid-cols-2 gap-2">
<li key={category}> {PRESET_TEMPLATES.map((preset) => (
<button <button
type="button" type="button"
onClick={() => handleSidebarClick(category)} key={preset.id}
className={cn( onClick={() => applyPreset(preset.id)}
"flex w-full items-center justify-between rounded px-2 py-1.5 text-left font-mono text-xs transition-colors", className="rounded border border-border bg-background p-2 text-left transition-colors hover:bg-muted"
activeCategory === category title={preset.description}
? "bg-primary/10 text-primary"
: "text-muted-foreground hover:bg-muted/50",
)}
> >
<span>{getCategoryDisplayName(category)}</span> <div className="font-medium text-foreground text-sm">
{compatibilityAnalysis.notes[category]?.hasIssue && ( {preset.name}
<span title="Compatibility issue affects this section"> </div>
<InfoIcon className="h-3 w-3 flex-shrink-0 text-chart-5" />{" "} <div className="text-muted-foreground text-xs">
</span> {preset.description}
)} </div>
</button> </button>
</li>
))} ))}
</ul> </div>
</nav> </div>
</div>
<ScrollArea ref={contentRef} className="flex-1 scroll-smooth"> <ScrollArea
<main className="flex-grow p-4"> ref={contentRef}
className="overflow-hidden scroll-smooth"
>
<main className="p-4">
{CATEGORY_ORDER.map((categoryKey) => { {CATEGORY_ORDER.map((categoryKey) => {
const categoryOptions = const categoryOptions =
TECH_OPTIONS[categoryKey as keyof typeof TECH_OPTIONS] || []; TECH_OPTIONS[categoryKey as keyof typeof TECH_OPTIONS] || [];
@@ -1814,8 +1801,7 @@ const StackArchitect = () => {
<h2 className="font-semibold text-base text-foreground"> <h2 className="font-semibold text-base text-foreground">
{categoryDisplayName} {categoryDisplayName}
</h2> </h2>
{compatibilityAnalysis.notes[categoryKey]?.notes.length > {compatibilityAnalysis.notes[categoryKey]?.hasIssue && (
0 && (
<Tooltip delayDuration={100}> <Tooltip delayDuration={100}>
<TooltipTrigger asChild> <TooltipTrigger asChild>
<InfoIcon className="ml-2 h-4 w-4 flex-shrink-0 cursor-help text-muted-foreground" /> <InfoIcon className="ml-2 h-4 w-4 flex-shrink-0 cursor-help text-muted-foreground" />
@@ -1833,7 +1819,7 @@ const StackArchitect = () => {
)} )}
</div> </div>
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"> <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 2xl:grid-cols-4">
{filteredOptions.map((tech) => { {filteredOptions.map((tech) => {
let isSelected = false; let isSelected = false;
const category = categoryKey as keyof StackState; const category = categoryKey as keyof StackState;

View File

@@ -14,7 +14,7 @@
}, },
"apps/cli": { "apps/cli": {
"name": "create-better-t-stack", "name": "create-better-t-stack",
"version": "2.9.6", "version": "2.9.9",
"bin": { "bin": {
"create-better-t-stack": "dist/index.js", "create-better-t-stack": "dist/index.js",
}, },