diff --git a/src/components/ProjectSettingsDesigner.tsx b/src/components/ProjectSettingsDesigner.tsx index f9a4419..404bd78 100644 --- a/src/components/ProjectSettingsDesigner.tsx +++ b/src/components/ProjectSettingsDesigner.tsx @@ -1,17 +1,15 @@ -import { useState } from 'react' -import { NextJsConfig, NpmSettings, NpmPackage } from '@/types/project' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Button } from '@/components/ui/button' -import { Input } from '@/components/ui/input' -import { Label } from '@/components/ui/label' -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' -import { Switch } from '@/components/ui/switch' +import { NextJsConfig, NpmSettings } from '@/types/project' import { ScrollArea } from '@/components/ui/scroll-area' -import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' -import { Plus, Trash, Package, Cube, Code } from '@phosphor-icons/react' -import { Badge } from '@/components/ui/badge' -import { SeedDataManager } from '@/components/molecules' +import { Cube } from '@phosphor-icons/react' +import projectSettingsCopy from '@/data/project-settings.json' +import { NextJsConfigTab } from '@/components/project-settings/NextJsConfigTab' +import { PackagesTab } from '@/components/project-settings/PackagesTab' +import { ScriptsTab } from '@/components/project-settings/ScriptsTab' +import { DataTab } from '@/components/project-settings/DataTab' +import { PackageDialog } from '@/components/project-settings/PackageDialog' +import { ScriptDialog } from '@/components/project-settings/ScriptDialog' +import { useProjectSettingsActions } from '@/components/project-settings/useProjectSettingsActions' interface ProjectSettingsDesignerProps { nextjsConfig: NextJsConfig @@ -26,92 +24,27 @@ export function ProjectSettingsDesigner({ onNextjsConfigChange, onNpmSettingsChange, }: ProjectSettingsDesignerProps) { - const [packageDialogOpen, setPackageDialogOpen] = useState(false) - const [editingPackage, setEditingPackage] = useState(null) - const [scriptDialogOpen, setScriptDialogOpen] = useState(false) - const [scriptKey, setScriptKey] = useState('') - const [scriptValue, setScriptValue] = useState('') - const [editingScriptKey, setEditingScriptKey] = useState(null) - - const handleAddPackage = () => { - setEditingPackage({ - id: `package-${Date.now()}`, - name: '', - version: 'latest', - isDev: false, - }) - setPackageDialogOpen(true) - } - - const handleEditPackage = (pkg: NpmPackage) => { - setEditingPackage({ ...pkg }) - setPackageDialogOpen(true) - } - - const handleSavePackage = () => { - if (!editingPackage || !editingPackage.name) return - - onNpmSettingsChange((current) => { - const existingIndex = current.packages.findIndex((p) => p.id === editingPackage.id) - if (existingIndex >= 0) { - const updated = [...current.packages] - updated[existingIndex] = editingPackage - return { ...current, packages: updated } - } else { - return { ...current, packages: [...current.packages, editingPackage] } - } - }) - - setPackageDialogOpen(false) - setEditingPackage(null) - } - - const handleDeletePackage = (packageId: string) => { - onNpmSettingsChange((current) => ({ - ...current, - packages: current.packages.filter((p) => p.id !== packageId), - })) - } - - const handleAddScript = () => { - setScriptKey('') - setScriptValue('') - setEditingScriptKey(null) - setScriptDialogOpen(true) - } - - const handleEditScript = (key: string, value: string) => { - setScriptKey(key) - setScriptValue(value) - setEditingScriptKey(key) - setScriptDialogOpen(true) - } - - const handleSaveScript = () => { - if (!scriptKey || !scriptValue) return - - onNpmSettingsChange((current) => { - const scripts = { ...current.scripts } - if (editingScriptKey && editingScriptKey !== scriptKey) { - delete scripts[editingScriptKey] - } - scripts[scriptKey] = scriptValue - return { ...current, scripts } - }) - - setScriptDialogOpen(false) - setScriptKey('') - setScriptValue('') - setEditingScriptKey(null) - } - - const handleDeleteScript = (key: string) => { - onNpmSettingsChange((current) => { - const scripts = { ...current.scripts } - delete scripts[key] - return { ...current, scripts } - }) - } + const { + packageDialogOpen, + setPackageDialogOpen, + editingPackage, + setEditingPackage, + scriptDialogOpen, + setScriptDialogOpen, + scriptKey, + setScriptKey, + scriptValue, + setScriptValue, + editingScriptKey, + handleAddPackage, + handleEditPackage, + handleSavePackage, + handleDeletePackage, + handleAddScript, + handleEditScript, + handleSaveScript, + handleDeleteScript, + } = useProjectSettingsActions({ onNpmSettingsChange }) return (
@@ -121,9 +54,9 @@ export function ProjectSettingsDesigner({
-

Project Settings

+

{projectSettingsCopy.header.title}

- Configure Next.js and npm settings + {projectSettingsCopy.header.description}

@@ -132,488 +65,66 @@ export function ProjectSettingsDesigner({
- Next.js Config - NPM Packages - Scripts - Data + {projectSettingsCopy.tabs.nextjs} + {projectSettingsCopy.tabs.packages} + {projectSettingsCopy.tabs.scripts} + {projectSettingsCopy.tabs.data}
-
- - - Application Settings - Basic Next.js application configuration - - -
- - - onNextjsConfigChange((current) => ({ - ...current, - appName: e.target.value, - })) - } - placeholder="my-nextjs-app" - /> -
- -
- - - onNextjsConfigChange((current) => ({ - ...current, - importAlias: e.target.value, - })) - } - placeholder="@/*" - /> -

- Used for module imports (e.g., import {'{'} Button {'}'} from "@/components") -

-
-
-
- - - - Features - Enable or disable Next.js features - - -
-
- -

- Use TypeScript for type safety -

-
- - onNextjsConfigChange((current) => ({ - ...current, - typescript: checked, - })) - } - /> -
- -
-
- -

Code linting and formatting

-
- - onNextjsConfigChange((current) => ({ - ...current, - eslint: checked, - })) - } - /> -
- -
-
- -

Utility-first CSS framework

-
- - onNextjsConfigChange((current) => ({ - ...current, - tailwind: checked, - })) - } - /> -
- -
-
- -

- Organize code inside src/ folder -

-
- - onNextjsConfigChange((current) => ({ - ...current, - srcDirectory: checked, - })) - } - /> -
- -
-
- -

- Use the new App Router (vs Pages Router) -

-
- - onNextjsConfigChange((current) => ({ - ...current, - appRouter: checked, - })) - } - /> -
- -
-
- -

- Faster incremental bundler -

-
- - onNextjsConfigChange((current) => ({ - ...current, - turbopack: checked, - })) - } - /> -
-
-
-
+
-
-
-
-

NPM Packages

-

- Manage project dependencies -

-
- -
- -
- - -
- -
-
-

Dependencies

-
- {npmSettings.packages - .filter((pkg) => !pkg.isDev) - .map((pkg) => ( - - -
-
-
- - {pkg.name} - {pkg.version} -
- {pkg.description && ( -

- {pkg.description} -

- )} -
-
- - -
-
-
-
- ))} - {npmSettings.packages.filter((pkg) => !pkg.isDev).length === 0 && ( - -

No dependencies added yet

-
- )} -
-
- -
-

Dev Dependencies

-
- {npmSettings.packages - .filter((pkg) => pkg.isDev) - .map((pkg) => ( - - -
-
-
- - {pkg.name} - {pkg.version} - - dev - -
- {pkg.description && ( -

- {pkg.description} -

- )} -
-
- - -
-
-
-
- ))} - {npmSettings.packages.filter((pkg) => pkg.isDev).length === 0 && ( - -

No dev dependencies added yet

-
- )} -
-
-
-
+
-
-
-
-

NPM Scripts

-

- Define custom commands for your project -

-
- -
- -
- {Object.entries(npmSettings.scripts).map(([key, value]) => ( - - -
-
-
- - {key} -
- - {value} - -
-
- - -
-
-
-
- ))} - {Object.keys(npmSettings.scripts).length === 0 && ( - -

No scripts defined yet

-
- )} -
-
+
-
- -
+
- - - - - {editingPackage?.name ? 'Edit Package' : 'Add Package'} - - Configure npm package details - - {editingPackage && ( -
-
- - - setEditingPackage({ ...editingPackage, name: e.target.value }) - } - placeholder="e.g., react-query, axios" - /> -
-
- - - setEditingPackage({ ...editingPackage, version: e.target.value }) - } - placeholder="latest, ^1.0.0, ~2.3.4" - /> -
-
- - - setEditingPackage({ ...editingPackage, description: e.target.value }) - } - placeholder="What is this package for?" - /> -
-
- - - setEditingPackage({ ...editingPackage, isDev: checked }) - } - /> -
-
- )} - - - - -
-
+ - - - - {editingScriptKey ? 'Edit Script' : 'Add Script'} - Define a custom npm script command - -
-
- - setScriptKey(e.target.value)} - placeholder="e.g., dev, build, test" - /> -
-
- - setScriptValue(e.target.value)} - placeholder="e.g., next dev, tsc --noEmit" - /> -
-
- - - - -
-
+ ) } diff --git a/src/components/project-settings/DataTab.tsx b/src/components/project-settings/DataTab.tsx new file mode 100644 index 0000000..f490f05 --- /dev/null +++ b/src/components/project-settings/DataTab.tsx @@ -0,0 +1,9 @@ +import { SeedDataManager } from '@/components/molecules' + +export function DataTab() { + return ( +
+ +
+ ) +} diff --git a/src/components/project-settings/NextJsApplicationCard.tsx b/src/components/project-settings/NextJsApplicationCard.tsx new file mode 100644 index 0000000..ac97ba6 --- /dev/null +++ b/src/components/project-settings/NextJsApplicationCard.tsx @@ -0,0 +1,60 @@ +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import { NextJsConfig } from '@/types/project' +import projectSettingsCopy from '@/data/project-settings.json' + +interface NextJsApplicationCardProps { + nextjsConfig: NextJsConfig + onNextjsConfigChange: (config: NextJsConfig | ((current: NextJsConfig) => NextJsConfig)) => void +} + +export function NextJsApplicationCard({ + nextjsConfig, + onNextjsConfigChange, +}: NextJsApplicationCardProps) { + const { application } = projectSettingsCopy.nextjs + + return ( + + + {application.title} + {application.description} + + +
+ + + onNextjsConfigChange((current) => ({ + ...current, + appName: e.target.value, + })) + } + placeholder={application.fields.appName.placeholder} + /> +
+ +
+ + + onNextjsConfigChange((current) => ({ + ...current, + importAlias: e.target.value, + })) + } + placeholder={application.fields.importAlias.placeholder} + /> +

+ {application.fields.importAlias.helper} +

+
+
+
+ ) +} diff --git a/src/components/project-settings/NextJsConfigTab.tsx b/src/components/project-settings/NextJsConfigTab.tsx new file mode 100644 index 0000000..fab7665 --- /dev/null +++ b/src/components/project-settings/NextJsConfigTab.tsx @@ -0,0 +1,26 @@ +import { NextJsConfig } from '@/types/project' +import { NextJsApplicationCard } from '@/components/project-settings/NextJsApplicationCard' +import { NextJsFeaturesCard } from '@/components/project-settings/NextJsFeaturesCard' + +interface NextJsConfigTabProps { + nextjsConfig: NextJsConfig + onNextjsConfigChange: (config: NextJsConfig | ((current: NextJsConfig) => NextJsConfig)) => void +} + +export function NextJsConfigTab({ + nextjsConfig, + onNextjsConfigChange, +}: NextJsConfigTabProps) { + return ( +
+ + +
+ ) +} diff --git a/src/components/project-settings/NextJsFeaturesCard.tsx b/src/components/project-settings/NextJsFeaturesCard.tsx new file mode 100644 index 0000000..0a5eaa8 --- /dev/null +++ b/src/components/project-settings/NextJsFeaturesCard.tsx @@ -0,0 +1,139 @@ +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' +import { Label } from '@/components/ui/label' +import { Switch } from '@/components/ui/switch' +import { NextJsConfig } from '@/types/project' +import projectSettingsCopy from '@/data/project-settings.json' + +interface NextJsFeaturesCardProps { + nextjsConfig: NextJsConfig + onNextjsConfigChange: (config: NextJsConfig | ((current: NextJsConfig) => NextJsConfig)) => void +} + +export function NextJsFeaturesCard({ + nextjsConfig, + onNextjsConfigChange, +}: NextJsFeaturesCardProps) { + const { features } = projectSettingsCopy.nextjs + + return ( + + + {features.title} + {features.description} + + +
+
+ +

+ {features.items.typescript.description} +

+
+ + onNextjsConfigChange((current) => ({ + ...current, + typescript: checked, + })) + } + /> +
+ +
+
+ +

{features.items.eslint.description}

+
+ + onNextjsConfigChange((current) => ({ + ...current, + eslint: checked, + })) + } + /> +
+ +
+
+ +

+ {features.items.tailwind.description} +

+
+ + onNextjsConfigChange((current) => ({ + ...current, + tailwind: checked, + })) + } + /> +
+ +
+
+ +

+ {features.items.srcDirectory.description} +

+
+ + onNextjsConfigChange((current) => ({ + ...current, + srcDirectory: checked, + })) + } + /> +
+ +
+
+ +

+ {features.items.appRouter.description} +

+
+ + onNextjsConfigChange((current) => ({ + ...current, + appRouter: checked, + })) + } + /> +
+ +
+
+ +

+ {features.items.turbopack.description} +

+
+ + onNextjsConfigChange((current) => ({ + ...current, + turbopack: checked, + })) + } + /> +
+
+
+ ) +} diff --git a/src/components/project-settings/PackageDialog.tsx b/src/components/project-settings/PackageDialog.tsx new file mode 100644 index 0000000..9c88fd2 --- /dev/null +++ b/src/components/project-settings/PackageDialog.tsx @@ -0,0 +1,90 @@ +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog' +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import { Switch } from '@/components/ui/switch' +import { NpmPackage } from '@/types/project' +import projectSettingsCopy from '@/data/project-settings.json' + +interface PackageDialogProps { + open: boolean + onOpenChange: (open: boolean) => void + editingPackage: NpmPackage | null + setEditingPackage: (pkg: NpmPackage | null) => void + onSave: () => void +} + +export function PackageDialog({ + open, + onOpenChange, + editingPackage, + setEditingPackage, + onSave, +}: PackageDialogProps) { + const copy = projectSettingsCopy.packages.dialog + const isEditing = Boolean(editingPackage?.name) + + return ( + + + + {isEditing ? copy.title.edit : copy.title.add} + {copy.description} + + {editingPackage && ( +
+
+ + + setEditingPackage({ ...editingPackage, name: e.target.value }) + } + placeholder={copy.fields.name.placeholder} + /> +
+
+ + + setEditingPackage({ ...editingPackage, version: e.target.value }) + } + placeholder={copy.fields.version.placeholder} + /> +
+
+ + + setEditingPackage({ ...editingPackage, description: e.target.value }) + } + placeholder={copy.fields.description.placeholder} + /> +
+
+ + + setEditingPackage({ ...editingPackage, isDev: checked }) + } + /> +
+
+ )} + + + + +
+
+ ) +} diff --git a/src/components/project-settings/PackageListSection.tsx b/src/components/project-settings/PackageListSection.tsx new file mode 100644 index 0000000..75a07f7 --- /dev/null +++ b/src/components/project-settings/PackageListSection.tsx @@ -0,0 +1,74 @@ +import { Badge } from '@/components/ui/badge' +import { Button } from '@/components/ui/button' +import { Card, CardContent } from '@/components/ui/card' +import { NpmPackage } from '@/types/project' +import { Package, Trash } from '@phosphor-icons/react' + +interface PackageListSectionProps { + title: string + emptyCopy: string + iconClassName: string + showDevBadge?: boolean + packages: NpmPackage[] + onEditPackage: (pkg: NpmPackage) => void + onDeletePackage: (packageId: string) => void +} + +export function PackageListSection({ + title, + emptyCopy, + iconClassName, + showDevBadge = false, + packages, + onEditPackage, + onDeletePackage, +}: PackageListSectionProps) { + return ( +
+

{title}

+
+ {packages.map((pkg) => ( + + +
+
+
+ + {pkg.name} + {pkg.version} + {showDevBadge && ( + + dev + + )} +
+ {pkg.description && ( +

{pkg.description}

+ )} +
+
+ + +
+
+
+
+ ))} + {packages.length === 0 && ( + +

{emptyCopy}

+
+ )} +
+
+ ) +} diff --git a/src/components/project-settings/PackagesTab.tsx b/src/components/project-settings/PackagesTab.tsx new file mode 100644 index 0000000..9d78b51 --- /dev/null +++ b/src/components/project-settings/PackagesTab.tsx @@ -0,0 +1,84 @@ +import { NpmPackage, NpmSettings } from '@/types/project' +import { Button } from '@/components/ui/button' +import { Label } from '@/components/ui/label' +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' +import projectSettingsCopy from '@/data/project-settings.json' +import { Plus } from '@phosphor-icons/react' +import { PackageListSection } from '@/components/project-settings/PackageListSection' + +interface PackagesTabProps { + npmSettings: NpmSettings + onNpmSettingsChange: (settings: NpmSettings | ((current: NpmSettings) => NpmSettings)) => void + onAddPackage: () => void + onEditPackage: (pkg: NpmPackage) => void + onDeletePackage: (packageId: string) => void +} + +export function PackagesTab({ + npmSettings, + onNpmSettingsChange, + onAddPackage, + onEditPackage, + onDeletePackage, +}: PackagesTabProps) { + const copy = projectSettingsCopy.packages + const dependencies = npmSettings.packages.filter((pkg) => !pkg.isDev) + const devDependencies = npmSettings.packages.filter((pkg) => pkg.isDev) + + return ( +
+
+
+

{copy.title}

+

{copy.description}

+
+ +
+ +
+ + +
+ +
+ + +
+
+ ) +} diff --git a/src/components/project-settings/ScriptDialog.tsx b/src/components/project-settings/ScriptDialog.tsx new file mode 100644 index 0000000..a91d36f --- /dev/null +++ b/src/components/project-settings/ScriptDialog.tsx @@ -0,0 +1,66 @@ +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog' +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import projectSettingsCopy from '@/data/project-settings.json' + +interface ScriptDialogProps { + open: boolean + onOpenChange: (open: boolean) => void + scriptKey: string + scriptValue: string + setScriptKey: (value: string) => void + setScriptValue: (value: string) => void + editingScriptKey: string | null + onSave: () => void +} + +export function ScriptDialog({ + open, + onOpenChange, + scriptKey, + scriptValue, + setScriptKey, + setScriptValue, + editingScriptKey, + onSave, +}: ScriptDialogProps) { + const copy = projectSettingsCopy.scripts.dialog + + return ( + + + + {editingScriptKey ? copy.title.edit : copy.title.add} + {copy.description} + +
+
+ + setScriptKey(e.target.value)} + placeholder={copy.fields.name.placeholder} + /> +
+
+ + setScriptValue(e.target.value)} + placeholder={copy.fields.command.placeholder} + /> +
+
+ + + + +
+
+ ) +} diff --git a/src/components/project-settings/ScriptsTab.tsx b/src/components/project-settings/ScriptsTab.tsx new file mode 100644 index 0000000..02405aa --- /dev/null +++ b/src/components/project-settings/ScriptsTab.tsx @@ -0,0 +1,73 @@ +import { Button } from '@/components/ui/button' +import { Card, CardContent } from '@/components/ui/card' +import { NpmSettings } from '@/types/project' +import projectSettingsCopy from '@/data/project-settings.json' +import { Code, Plus, Trash } from '@phosphor-icons/react' + +interface ScriptsTabProps { + npmSettings: NpmSettings + onAddScript: () => void + onEditScript: (key: string, value: string) => void + onDeleteScript: (key: string) => void +} + +export function ScriptsTab({ + npmSettings, + onAddScript, + onEditScript, + onDeleteScript, +}: ScriptsTabProps) { + const copy = projectSettingsCopy.scripts + const scripts = Object.entries(npmSettings.scripts) + + return ( +
+
+
+

{copy.title}

+

{copy.description}

+
+ +
+ +
+ {scripts.map(([key, value]) => ( + + +
+
+
+ + {key} +
+ {value} +
+
+ + +
+
+
+
+ ))} + {scripts.length === 0 && ( + +

{copy.empty}

+
+ )} +
+
+ ) +} diff --git a/src/components/project-settings/useProjectSettingsActions.ts b/src/components/project-settings/useProjectSettingsActions.ts new file mode 100644 index 0000000..de65c8d --- /dev/null +++ b/src/components/project-settings/useProjectSettingsActions.ts @@ -0,0 +1,119 @@ +import { useState } from 'react' +import { NpmPackage, NpmSettings } from '@/types/project' + +interface UseProjectSettingsActionsProps { + onNpmSettingsChange: (settings: NpmSettings | ((current: NpmSettings) => NpmSettings)) => void +} + +export function useProjectSettingsActions({ + onNpmSettingsChange, +}: UseProjectSettingsActionsProps) { + const [packageDialogOpen, setPackageDialogOpen] = useState(false) + const [editingPackage, setEditingPackage] = useState(null) + const [scriptDialogOpen, setScriptDialogOpen] = useState(false) + const [scriptKey, setScriptKey] = useState('') + const [scriptValue, setScriptValue] = useState('') + const [editingScriptKey, setEditingScriptKey] = useState(null) + + const handleAddPackage = () => { + setEditingPackage({ + id: `package-${Date.now()}`, + name: '', + version: 'latest', + isDev: false, + }) + setPackageDialogOpen(true) + } + + const handleEditPackage = (pkg: NpmPackage) => { + setEditingPackage({ ...pkg }) + setPackageDialogOpen(true) + } + + const handleSavePackage = () => { + if (!editingPackage || !editingPackage.name) return + + onNpmSettingsChange((current) => { + const existingIndex = current.packages.findIndex((p) => p.id === editingPackage.id) + if (existingIndex >= 0) { + const updated = [...current.packages] + updated[existingIndex] = editingPackage + return { ...current, packages: updated } + } + return { ...current, packages: [...current.packages, editingPackage] } + }) + + setPackageDialogOpen(false) + setEditingPackage(null) + } + + const handleDeletePackage = (packageId: string) => { + onNpmSettingsChange((current) => ({ + ...current, + packages: current.packages.filter((p) => p.id !== packageId), + })) + } + + const handleAddScript = () => { + setScriptKey('') + setScriptValue('') + setEditingScriptKey(null) + setScriptDialogOpen(true) + } + + const handleEditScript = (key: string, value: string) => { + setScriptKey(key) + setScriptValue(value) + setEditingScriptKey(key) + setScriptDialogOpen(true) + } + + const handleSaveScript = () => { + if (!scriptKey || !scriptValue) return + + onNpmSettingsChange((current) => { + const scripts = { ...current.scripts } + if (editingScriptKey && editingScriptKey !== scriptKey) { + delete scripts[editingScriptKey] + } + scripts[scriptKey] = scriptValue + return { ...current, scripts } + }) + + setScriptDialogOpen(false) + setScriptKey('') + setScriptValue('') + setEditingScriptKey(null) + } + + const handleDeleteScript = (key: string) => { + onNpmSettingsChange((current) => { + const scripts = { ...current.scripts } + delete scripts[key] + return { ...current, scripts } + }) + } + + return { + packageDialogOpen, + setPackageDialogOpen, + editingPackage, + setEditingPackage, + scriptDialogOpen, + setScriptDialogOpen, + scriptKey, + setScriptKey, + scriptValue, + setScriptValue, + editingScriptKey, + setEditingScriptKey, + handleAddPackage, + handleEditPackage, + handleSavePackage, + handleDeletePackage, + handleAddScript, + handleEditScript, + handleSaveScript, + handleDeleteScript, + } +} diff --git a/src/data/project-settings.json b/src/data/project-settings.json new file mode 100644 index 0000000..c68aa0c --- /dev/null +++ b/src/data/project-settings.json @@ -0,0 +1,120 @@ +{ + "header": { + "title": "Project Settings", + "description": "Configure Next.js and npm settings" + }, + "tabs": { + "nextjs": "Next.js Config", + "packages": "NPM Packages", + "scripts": "Scripts", + "data": "Data" + }, + "nextjs": { + "application": { + "title": "Application Settings", + "description": "Basic Next.js application configuration", + "fields": { + "appName": { + "label": "Application Name", + "placeholder": "my-nextjs-app" + }, + "importAlias": { + "label": "Import Alias", + "placeholder": "@/*", + "helper": "Used for module imports (e.g., import { Button } from \"@/components\")" + } + } + }, + "features": { + "title": "Features", + "description": "Enable or disable Next.js features", + "items": { + "typescript": { + "label": "TypeScript", + "description": "Use TypeScript for type safety" + }, + "eslint": { + "label": "ESLint", + "description": "Code linting and formatting" + }, + "tailwind": { + "label": "Tailwind CSS", + "description": "Utility-first CSS framework" + }, + "srcDirectory": { + "label": "Use src/ Directory", + "description": "Organize code inside src/ folder" + }, + "appRouter": { + "label": "App Router", + "description": "Use the new App Router (vs Pages Router)" + }, + "turbopack": { + "label": "Turbopack (Beta)", + "description": "Faster incremental bundler" + } + } + } + }, + "packages": { + "title": "NPM Packages", + "description": "Manage project dependencies", + "packageManager": { + "label": "Package Manager" + }, + "dependencies": { + "title": "Dependencies", + "empty": "No dependencies added yet" + }, + "devDependencies": { + "title": "Dev Dependencies", + "empty": "No dev dependencies added yet" + }, + "dialog": { + "title": { + "add": "Add Package", + "edit": "Edit Package" + }, + "description": "Configure npm package details", + "fields": { + "name": { + "label": "Package Name", + "placeholder": "e.g., react-query, axios" + }, + "version": { + "label": "Version", + "placeholder": "latest, ^1.0.0, ~2.3.4" + }, + "description": { + "label": "Description (Optional)", + "placeholder": "What is this package for?" + }, + "devDependency": { + "label": "Development Dependency" + } + } + } + }, + "scripts": { + "title": "NPM Scripts", + "description": "Define custom commands for your project", + "empty": "No scripts defined yet", + "dialog": { + "title": { + "add": "Add Script", + "edit": "Edit Script" + }, + "description": "Define a custom npm script command", + "fields": { + "name": { + "label": "Script Name", + "placeholder": "e.g., dev, build, test" + }, + "command": { + "label": "Command", + "placeholder": "e.g., next dev, tsc --noEmit" + } + } + } + } +}