Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
2db4aa3
feat: implement usage tracking API and display real-time platform sta…
Arjun544 Jun 5, 2026
df76c1c
Merge branch 'main' of https://github.com/Arjun544/flutter_init
Arjun544 Jun 13, 2026
2466911
Merge branch 'main' of https://github.com/Arjun544/flutter_init
Arjun544 Jun 13, 2026
eb30a5e
feat: add CLI
Arjun544 Jun 15, 2026
75a56d3
feat: implement animate-ui library and landing page components with m…
Arjun544 Jun 15, 2026
4c15564
feat: add landing page components including interactive navbar and no…
Arjun544 Jun 15, 2026
8b0c0c1
feat: enhance landing page statistics section with improved card stru…
Arjun544 Jun 16, 2026
7c776df
feat: implement FlutterInit CLI scaffolding tool and landing page com…
Arjun544 Jun 20, 2026
92b628a
chore: add border-beam, lucide-react, and motion dependencies to bun.…
Arjun544 Jun 20, 2026
9a9c494
feat: implement CLI core structure, project generator, and native con…
Arjun544 Jun 20, 2026
2e7a110
chore: exclude cli directory from TypeScript compilation
Arjun544 Jun 20, 2026
c6ee2ae
feat: add AvatarGroup and AvatarGroupTooltip components with motion a…
Arjun544 Jun 20, 2026
9427735
feat: implement landing page components including hero, feature showc…
Arjun544 Jun 20, 2026
2d25b35
feat: components cleanup
Arjun544 Jun 20, 2026
3946b62
feat: implement blog infrastructure, animate-ui primitives, and archi…
Arjun544 Jun 20, 2026
8b06f7b
bug: fixed FlutterInit CLI
Arjun544 Jun 20, 2026
8e08b2b
feat: implement blog infrastructure, including post routing, filterin…
Arjun544 Jun 20, 2026
5c1f200
feat: implement wizard shell UI and add NPM version badge to README
Arjun544 Jun 20, 2026
f2dfe2b
Merge branch 'main' into add_cli
Arjun544 Jun 20, 2026
578bf25
feat: add canonical URL to blog metadata for SEO optimization
Arjun544 Aug 10, 2026
734154c
Merge branch 'add_cli' of https://github.com/Arjun544/flutter_init in…
Arjun544 Aug 10, 2026
9f62d38
Added live code editor
Arjun544 Aug 10, 2026
49d6059
Added more blogs
Arjun544 Aug 10, 2026
6f8ecc2
Merge branch 'main' into add_cli
Arjun544 Aug 10, 2026
d75e627
Remove blog layout, page, and related components to streamline the bl…
Arjun544 Aug 10, 2026
3fef1c8
Merge branch 'main' into add_cli
Arjun544 Aug 10, 2026
8ea1434
Update README and related files to reflect the change from "Blog" to …
Arjun544 Aug 10, 2026
f85560a
Merge branch 'add_cli' of https://github.com/Arjun544/flutter_init in…
Arjun544 Aug 10, 2026
f6c7e53
Refactor WizardShell component: update button shadow style and clean …
Arjun544 Aug 10, 2026
02907d1
Fixed issues
Arjun544 Aug 10, 2026
32ccfad
Merge branch 'main' into add_cli
Arjun544 Aug 10, 2026
164d552
Refactor CodeEditorWorkspace and WizardShell components: streamline i…
Arjun544 Aug 11, 2026
3599fc3
Merge branch 'add_cli' of https://github.com/Arjun544/flutter_init in…
Arjun544 Aug 11, 2026
2344224
Merge branch 'main' into add_cli
Arjun544 Aug 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
706 changes: 83 additions & 623 deletions app/components/wizard/CodeEditorWorkspace.tsx

Large diffs are not rendered by default.

34 changes: 26 additions & 8 deletions app/components/wizard/WizardShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,6 @@ export function WizardShell() {
}
}

const progress = React.useMemo(
() => Math.round(((stepIndex + 1) / stepOrder.length) * 100),
[stepIndex]
)

const handleNext = async () => {
if (stepIndex === stepOrder.length - 1) {
await handleGenerate()
Expand Down Expand Up @@ -195,7 +190,7 @@ export function WizardShell() {
variant="outline"
asChild
disabled={!isValid || isGenerating}
className="h-10 px-4 border-border/40 bg-background/50 shadow-xs cursor-pointer"
className="hidden lg:inline-flex h-10 px-4 border-border/40 bg-background/50 shadow-xs cursor-pointer"
>
<Link
href={isValid ? "/create/code" : "#"}
Expand All @@ -205,8 +200,7 @@ export function WizardShell() {
className={cn((!isValid || isGenerating) && "pointer-events-none opacity-50")}
>
<HugeiconsIcon icon={SourceCodeIcon} className="size-4 mr-1.5" />
<span className="hidden sm:inline">Preview code</span>
<span className="sm:hidden">Code</span>
Preview code
</Link>
</Button>
<Button
Expand Down Expand Up @@ -252,6 +246,30 @@ export function WizardShell() {
</main>
</div>

{/* Mobile floating preview — keeps header uncluttered on small screens */}
<Button
asChild
disabled={!isValid || isGenerating}
className={cn(
"lg:hidden fixed z-40 bottom-6 right-4 h-12 gap-2 rounded-xl px-5",
"bg-primary text-primary-foreground shadow-lg",
"hover:bg-primary/90 active:scale-[0.98] transition-transform",
(!isValid || isGenerating) && "opacity-50"
)}
>
<Link
href={isValid ? "/create/code" : "#"}
target="_blank"
rel="noopener noreferrer"
aria-label="Preview code"
aria-disabled={!isValid || isGenerating}
className={cn((!isValid || isGenerating) && "pointer-events-none")}
>
<HugeiconsIcon icon={SourceCodeIcon} className="size-4" />
Preview
</Link>
</Button>

<PackageInfoPanel />
</SidebarInset>
</SidebarProvider>
Expand Down
46 changes: 46 additions & 0 deletions app/components/wizard/code-editor/EditorBreadcrumb.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"use client"

import * as React from "react"

import { CopyButton } from "@/components/animate-ui/components/buttons/copy"
import { cn } from "@/lib/utils"

export function EditorBreadcrumb({
path,
code,
canCopy,
}: {
path: string
code: string
canCopy: boolean
}) {
return (
<div className="flex h-7 shrink-0 items-center gap-1 bg-background px-2 text-[11px] text-muted-foreground sm:h-6 sm:px-3 sm:text-[12px]">
<div className="flex min-w-0 flex-1 items-center gap-1 overflow-x-auto overscroll-x-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
{path.split("/").map((segment, index, parts) => (
<React.Fragment key={`${segment}-${index}`}>
{index > 0 && <span className="shrink-0 opacity-40">/</span>}
<span
className={cn(
"shrink-0",
index === parts.length - 1 && "text-foreground"
)}
>
{segment}
</span>
</React.Fragment>
))}
</div>
{canCopy ? (
<CopyButton
content={code}
size="xs"
variant="ghost"
aria-label="Copy file contents"
title="Copy file"
className="ml-auto size-6 shrink-0 text-muted-foreground hover:bg-muted hover:text-foreground sm:size-5"
/>
) : null}
</div>
)
}
77 changes: 77 additions & 0 deletions app/components/wizard/code-editor/EditorColumn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"use client"

import type { MouseEvent } from "react"

import { EditorBreadcrumb } from "@/app/components/wizard/code-editor/EditorBreadcrumb"
import { EditorPane } from "@/app/components/wizard/code-editor/EditorPane"
import { EditorTabs } from "@/app/components/wizard/code-editor/EditorTabs"

export function EditorColumn({
paths,
activePath,
pinnedPaths,
loading,
error,
code,
theme,
canPreview,
isMobile,
onSelectTab,
onCloseTab,
onCloseAllTabs,
onCloseOtherTabs,
onMoveTabToRight,
onTogglePinTab,
onBrowseFiles,
}: {
paths: string[]
activePath: string | null
pinnedPaths: string[]
loading: boolean
error: string | null
code: string
theme: string
canPreview: boolean
isMobile: boolean
onSelectTab: (path: string) => void
onCloseTab: (path: string, event?: MouseEvent) => void
onCloseAllTabs: () => void
onCloseOtherTabs: (path: string) => void
onMoveTabToRight: (path: string) => void
onTogglePinTab: (path: string) => void
onBrowseFiles: () => void
}) {
return (
<div className="flex h-full min-h-0 min-w-0 flex-1 flex-col">
<EditorTabs
paths={paths}
activePath={activePath}
pinnedPaths={pinnedPaths}
loading={loading}
onSelect={onSelectTab}
onClose={onCloseTab}
onCloseAll={onCloseAllTabs}
onCloseOthers={onCloseOtherTabs}
onMoveToRight={onMoveTabToRight}
onTogglePin={onTogglePinTab}
/>
{activePath ? (
<EditorBreadcrumb
path={activePath}
code={code}
canCopy={canPreview}
/>
) : null}
<EditorPane
loading={loading}
error={error}
activePath={activePath}
code={code}
theme={theme}
canPreview={canPreview}
isMobile={isMobile}
onBrowseFiles={onBrowseFiles}
/>
</div>
)
}
85 changes: 85 additions & 0 deletions app/components/wizard/code-editor/EditorPane.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"use client"

import { File01Icon, SidebarLeftIcon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"

import { HighlightedPane } from "@/app/components/wizard/code-editor/HighlightedPane"
import { Button } from "@/components/ui/button"
import {
Empty,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/components/ui/empty"

export function EditorPane({
loading,
error,
activePath,
code,
theme,
canPreview,
isMobile,
onBrowseFiles,
}: {
loading: boolean
error: string | null
activePath: string | null
code: string
theme: string
canPreview: boolean
isMobile: boolean
onBrowseFiles: () => void
}) {
return (
<div className="min-h-0 min-w-0 flex-1 bg-background">
{loading ? (
<div className="flex h-full flex-col gap-2 p-4" aria-busy="true">
<div className="h-3 w-2/3 animate-pulse rounded bg-muted" />
<div className="h-3 w-1/2 animate-pulse rounded bg-muted" />
<div className="h-3 w-3/4 animate-pulse rounded bg-muted" />
</div>
) : error ? (
<div className="flex h-full items-center justify-center p-6 text-center text-sm text-destructive">
{error}
</div>
) : !activePath ? (
<div className="flex h-full flex-col items-center justify-center gap-3 p-6 text-center text-sm text-muted-foreground">
<HugeiconsIcon icon={File01Icon} className="size-8 opacity-40" />
<p>
{isMobile
? "Open the explorer to pick a file."
: "Open a file from the explorer to start."}
</p>
{isMobile ? (
<Button
type="button"
variant="outline"
size="sm"
className="gap-1.5"
onClick={onBrowseFiles}
>
<HugeiconsIcon icon={SidebarLeftIcon} className="size-3.5" />
Browse files
</Button>
) : null}
</div>
) : !canPreview ? (
<Empty className="h-full border-0">
<EmptyHeader>
<EmptyMedia variant="icon">
<HugeiconsIcon icon={File01Icon} />
</EmptyMedia>
<EmptyTitle>No preview available</EmptyTitle>
<EmptyDescription>
This file type can&apos;t be previewed in the editor.
</EmptyDescription>
</EmptyHeader>
</Empty>
) : (
<HighlightedPane code={code} filePath={activePath} theme={theme} />
)}
</div>
)
}
Loading
Loading