@deneb-ui/cli 2.0.22 → 2.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -114
- package/bin/index.js +37 -12
- package/package.json +20 -5
- package/src/arc/__fixtures__/next-app-basic/package.json +10 -0
- package/src/arc/__fixtures__/next-app-basic/src/app/globals.css +3 -0
- package/src/arc/__fixtures__/next-app-basic/src/app/layout.tsx +9 -0
- package/src/arc/__fixtures__/next-app-basic/src/app/page.tsx +11 -0
- package/src/arc/__fixtures__/next-app-basic/src/components/Header.tsx +13 -0
- package/src/arc/__fixtures__/next-app-basic/src/components/Hero.tsx +12 -0
- package/src/arc/__fixtures__/next-app-basic/src/components/PromoBanner.tsx +10 -0
- package/src/arc/__fixtures__/next-app-basic/tsconfig.json +12 -0
- package/src/arc/__fixtures__/next-app-storefront/components.json +14 -0
- package/src/arc/__fixtures__/next-app-storefront/package.json +22 -0
- package/src/arc/__fixtures__/next-app-storefront/src/app/about/page.tsx +13 -0
- package/src/arc/__fixtures__/next-app-storefront/src/app/globals.css +5 -0
- package/src/arc/__fixtures__/next-app-storefront/src/app/layout.tsx +19 -0
- package/src/arc/__fixtures__/next-app-storefront/src/app/page.tsx +13 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/Features.tsx +31 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/Hero.tsx +45 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/ProductGrid.tsx +49 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/SiteFooter.tsx +22 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/SiteHeader.tsx +21 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/ui/button.tsx +36 -0
- package/src/arc/__fixtures__/next-app-storefront/tsconfig.json +15 -0
- package/src/arc/__fixtures__/next-pages-basic/package.json +10 -0
- package/src/arc/__fixtures__/next-pages-basic/pages/_app.jsx +5 -0
- package/src/arc/__fixtures__/next-pages-basic/pages/contact.jsx +9 -0
- package/src/arc/__fixtures__/next-pages-basic/pages/index.jsx +11 -0
- package/src/arc/__fixtures__/next-pages-basic/styles/globals.css +9 -0
- package/src/arc/__tests__/arc.test.cjs +458 -0
- package/src/arc/adapters.cjs +184 -0
- package/src/arc/ast.cjs +323 -0
- package/src/arc/field-paths.cjs +165 -0
- package/src/arc/fivora-contract.cjs +521 -0
- package/src/arc/fs-utils.cjs +170 -0
- package/src/arc/index.cjs +628 -0
- package/src/arc/learning.cjs +185 -0
- package/src/arc/manifest.cjs +421 -0
- package/src/arc/next-config.cjs +279 -0
- package/src/arc/planner.cjs +227 -0
- package/src/arc/printer.cjs +153 -0
- package/src/arc/recipes-v2.cjs +49 -0
- package/src/arc/scanner.cjs +613 -0
- package/src/arc/semantic.cjs +651 -0
- package/src/arc/transformer.cjs +646 -0
- package/src/arc/validator.cjs +173 -0
- package/src/arc/version.cjs +22 -0
package/README.md
CHANGED
|
@@ -1,138 +1,86 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
>
|
|
6
|
-
|
|
7
|
-
>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
npm install -D @deneb-ui/cli
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Or install globally:
|
|
27
|
-
```bash
|
|
28
|
-
npm install -g @deneb-ui/cli
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
The CLI command is available as `deneb` (with alias `denebui`).
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://deneb.fivora.site">
|
|
3
|
+
<img src="https://img.shields.io/badge/DENEB_CLI-Storefront_Authoring_Toolkit-6366F1?style=for-the-badge&labelColor=0f172a" alt="DENEB CLI" />
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/@deneb-ui/cli"><img src="https://img.shields.io/npm/v/@deneb-ui/cli.svg?style=flat-square&color=6366F1" alt="npm version" /></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/@deneb-ui/cli"><img src="https://img.shields.io/npm/dm/@deneb-ui/cli.svg?style=flat-square&color=6366F1" alt="npm downloads" /></a>
|
|
10
|
+
<img src="https://img.shields.io/badge/Node-%3E%3D18-339933?style=flat-square&logo=node.js&logoColor=white" alt="Node.js" />
|
|
11
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-emerald?style=flat-square" alt="MIT License" /></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<strong>Scaffold, convert, validate, and ship Fivora-ready storefront templates.</strong>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="https://deneb.fivora.site/docs/cli"><strong>CLI Reference</strong></a> ·
|
|
20
|
+
<a href="https://deneb.fivora.site/docs/installation"><strong>Installation</strong></a> ·
|
|
21
|
+
<a href="https://github.com/deneb-ui/core"><strong>GitHub</strong></a>
|
|
22
|
+
</p>
|
|
32
23
|
|
|
33
24
|
---
|
|
34
25
|
|
|
35
|
-
##
|
|
36
|
-
|
|
37
|
-
### 1. `deneb add <component>` (Component Registry)
|
|
38
|
-
Add production-ready DENEB UI components into `src/components/ui/`:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
# List available components:
|
|
42
|
-
npx @deneb-ui/cli add list
|
|
43
|
-
|
|
44
|
-
# Add specific components:
|
|
45
|
-
npx @deneb-ui/cli add product-card
|
|
46
|
-
npx @deneb-ui/cli add contact-actions
|
|
47
|
-
npx @deneb-ui/cli add location-card
|
|
48
|
-
npx @deneb-ui/cli add whatsapp-button
|
|
49
|
-
npx @deneb-ui/cli add dialog
|
|
50
|
-
npx @deneb-ui/cli add all
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### 1. `deneb init` (Initialize Existing Project)
|
|
54
|
-
Converts and configures any **ongoing Next.js project** for the Fivora platform:
|
|
55
|
-
- Generates `fivora-template.json` (Version 2 contract with strict visual editing)
|
|
56
|
-
- Creates `src/data/site-data.json` with merchant defaults
|
|
57
|
-
- Injects npm scripts (`lab`, `validate`, `zip`, `validate-and-zip`, `update:deneb`)
|
|
58
|
-
- Installs `@deneb-ui/ui` and `@deneb-ui/cli`
|
|
26
|
+
## Quick start
|
|
59
27
|
|
|
60
28
|
```bash
|
|
29
|
+
# Convert an existing Next.js app (Deneb ARC — default engine)
|
|
61
30
|
npx @deneb-ui/cli init
|
|
62
|
-
# Or: deneb init
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### 2. `deneb update` (Update Packages & DENEB Components)
|
|
66
|
-
Keeps your project up to date by updating both npm packages and installed DENEB components:
|
|
67
|
-
- Updates `@deneb-ui/ui` and `@deneb-ui/cli` to the latest releases
|
|
68
|
-
- Automatically scans `src/components/ui/` and synchronizes existing DENEB UI components with the latest definitions
|
|
69
31
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
# Or: deneb update
|
|
73
|
-
```
|
|
32
|
+
# Preview the transformation plan without writing files
|
|
33
|
+
npx @deneb-ui/cli init --explain
|
|
74
34
|
|
|
75
|
-
|
|
76
|
-
|
|
35
|
+
# Validate Fivora contract compliance
|
|
36
|
+
npx @deneb-ui/cli validate .
|
|
77
37
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# Or: deneb validate .
|
|
81
|
-
# Or validate and immediately bundle on success:
|
|
82
|
-
deneb validate --zip
|
|
38
|
+
# Package a clean upload ZIP
|
|
39
|
+
npx @deneb-ui/cli validate --zip
|
|
83
40
|
```
|
|
84
41
|
|
|
85
|
-
|
|
86
|
-
Creates a clean, upload-ready `fivora-template.zip` excluding unnecessary directories and secret files (`node_modules`, `.next`, `.git`, `.env*`, `.cache`, `.turbo`, logs):
|
|
42
|
+
Install as a dev dependency:
|
|
87
43
|
|
|
88
44
|
```bash
|
|
89
|
-
npm
|
|
90
|
-
#
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### 5. `deneb validate-and-zip` (One-Step Preflight Check & Clean ZIP)
|
|
94
|
-
The safest, recommended command for releasing templates. Runs full preflight validation; if and only if all platform checks pass 100%, it bundles a clean `fivora-template.zip`:
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
npm run validate-and-zip
|
|
98
|
-
# Or: deneb validate-and-zip .
|
|
99
|
-
# Or: deneb validate and zip
|
|
45
|
+
npm install -D @deneb-ui/cli
|
|
46
|
+
# Command: deneb
|
|
100
47
|
```
|
|
101
48
|
|
|
102
|
-
|
|
103
|
-
Add or update production-ready DENEB UI components into `src/components/ui/`:
|
|
49
|
+
---
|
|
104
50
|
|
|
105
|
-
|
|
106
|
-
# List available components:
|
|
107
|
-
npx @deneb-ui/cli add list
|
|
108
|
-
|
|
109
|
-
# Add specific components:
|
|
110
|
-
npx @deneb-ui/cli add product-card
|
|
111
|
-
npx @deneb-ui/cli add contact-actions
|
|
112
|
-
npx @deneb-ui/cli add location-card
|
|
113
|
-
npx @deneb-ui/cli add whatsapp-button
|
|
114
|
-
npx @deneb-ui/cli add dialog
|
|
115
|
-
npx @deneb-ui/cli add all
|
|
116
|
-
```
|
|
51
|
+
## Commands
|
|
117
52
|
|
|
118
|
-
|
|
119
|
-
|
|
53
|
+
| Command | Description |
|
|
54
|
+
| :--- | :--- |
|
|
55
|
+
| `deneb init` | Run **Deneb ARC** — AST conversion of React/Next.js apps into Fivora-editable templates |
|
|
56
|
+
| `deneb init --legacy` | Use the legacy regex converter instead of ARC |
|
|
57
|
+
| `deneb init --dry-run` | Simulate conversion; print field paths without writing |
|
|
58
|
+
| `deneb init --explain` | Show transformation plan with confidence scores |
|
|
59
|
+
| `deneb validate` | Preflight manifest + visual editing contract checks |
|
|
60
|
+
| `deneb zip` | Create upload-ready `fivora-template.zip` |
|
|
61
|
+
| `deneb doctor` | Environment, dependency, and export diagnostics |
|
|
62
|
+
| `deneb add <component>` | Copy DENEB UI components into your project |
|
|
63
|
+
| `deneb lab` | Launch local visual editing preview lab |
|
|
64
|
+
| `deneb update` | Update `@deneb-ui/*` packages and synced components |
|
|
65
|
+
|
|
66
|
+
Full reference: [deneb.fivora.site/docs/cli](https://deneb.fivora.site/docs/cli)
|
|
120
67
|
|
|
121
|
-
|
|
122
|
-
npx @deneb-ui/cli create my-store
|
|
123
|
-
```
|
|
68
|
+
---
|
|
124
69
|
|
|
125
|
-
|
|
126
|
-
Launches the interactive visual editing test lab simulating Fivora editor messages:
|
|
70
|
+
## What `deneb init` does (ARC)
|
|
127
71
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
72
|
+
1. **Scans** your Next.js project — routes, dependencies, reachable pages
|
|
73
|
+
2. **Analyzes** JSX for editable text, images, URLs, collections, CTAs
|
|
74
|
+
3. **Transforms** source via AST — injects preview markers and `site-data` bindings
|
|
75
|
+
4. **Generates** `fivora-template.json` + `site-data.json` with strict self-validation
|
|
76
|
+
5. **Backs up** changed files to `.deneb-backup-*` for safe rollback
|
|
132
77
|
|
|
133
78
|
---
|
|
134
79
|
|
|
135
|
-
##
|
|
80
|
+
## Authors
|
|
81
|
+
|
|
82
|
+
Created and maintained by **[Chamika Gayashan](https://github.com/chamikathereal)** and **[Induranga Kawishwara](https://github.com/Induranga-kawishwara)**.
|
|
136
83
|
|
|
137
|
-
|
|
138
|
-
|
|
84
|
+
<p align="center">
|
|
85
|
+
<sub>MIT © DENEB UI</sub>
|
|
86
|
+
</p>
|
package/bin/index.js
CHANGED
|
@@ -602,8 +602,8 @@ function initProject(targetInput, options = {}) {
|
|
|
602
602
|
const pkgPath = path.join(targetDir, 'package.json');
|
|
603
603
|
|
|
604
604
|
console.log('\n' + createBox([
|
|
605
|
-
'\x1b[1m\x1b[37mDENEB
|
|
606
|
-
'\x1b[
|
|
605
|
+
'\x1b[1m\x1b[37mDENEB ARC\x1b[0m',
|
|
606
|
+
'\x1b[90mAdaptive Refactoring Compiler for Fivora-editable UI\x1b[0m',
|
|
607
607
|
'\x1b[90mPowered by DENEB-UI Collaborate with FIVORA\x1b[0m'
|
|
608
608
|
], 58) + '\n');
|
|
609
609
|
|
|
@@ -637,20 +637,27 @@ function initProject(targetInput, options = {}) {
|
|
|
637
637
|
// 1. Scan / Detect Pages
|
|
638
638
|
const detectedPages = detectPages(targetDir);
|
|
639
639
|
|
|
640
|
-
// 2.
|
|
641
|
-
// Automatically detects CSS/UI frameworks (shadcn/ui, HeroUI, Tailwind CSS),
|
|
642
|
-
// creates safe backup, instruments Root Layout with SiteDataProvider,
|
|
643
|
-
// extracts hardcoded text/images/buttons/placeholders,
|
|
644
|
-
// injects data-preview-field-path markers, harmonizes UI components,
|
|
645
|
-
// and builds synchronized site-data.json & fivora-template.json.
|
|
640
|
+
// 2. Deneb ARC (default) or legacy regex converter (--legacy)
|
|
646
641
|
let conversionRes = null;
|
|
647
642
|
try {
|
|
648
|
-
|
|
649
|
-
|
|
643
|
+
if (options.legacy) {
|
|
644
|
+
const { runUniversalTemplateConversion } = require('../src/tools/template-converter.cjs');
|
|
645
|
+
conversionRes = runUniversalTemplateConversion(targetDir, projectName, detectedPages, options);
|
|
646
|
+
} else {
|
|
647
|
+
const { runDenebArc } = require('../src/arc/index.cjs');
|
|
648
|
+
conversionRes = runDenebArc(targetDir, projectName, {
|
|
649
|
+
...options,
|
|
650
|
+
detectedPages,
|
|
651
|
+
});
|
|
652
|
+
}
|
|
650
653
|
} catch (err) {
|
|
651
654
|
console.error(`\x1b[33m⚠ Note:\x1b[0m Automated conversion encountered an issue: ${err.message}. Falling back to default generation.`);
|
|
652
655
|
}
|
|
653
656
|
|
|
657
|
+
if (options.dryRun) {
|
|
658
|
+
return conversionRes;
|
|
659
|
+
}
|
|
660
|
+
|
|
654
661
|
// 3. Fallback: Generate fivora-template.json if not yet present
|
|
655
662
|
const manifestPath = path.join(targetDir, 'fivora-template.json');
|
|
656
663
|
if (!fs.existsSync(manifestPath)) {
|
|
@@ -999,17 +1006,31 @@ if (command === 'validate' && (commandArgs[0] === 'and' || commandArgs[0] === '&
|
|
|
999
1006
|
if (command === 'init') {
|
|
1000
1007
|
let targetInput = '.';
|
|
1001
1008
|
let recipeName = null;
|
|
1009
|
+
let dryRun = false;
|
|
1010
|
+
let explain = false;
|
|
1011
|
+
let legacy = false;
|
|
1012
|
+
let telemetry = 'off';
|
|
1002
1013
|
for (let i = 0; i < commandArgs.length; i++) {
|
|
1003
1014
|
const arg = commandArgs[i];
|
|
1004
1015
|
if (arg === '--recipe' || arg === '-r') {
|
|
1005
1016
|
recipeName = commandArgs[++i];
|
|
1006
1017
|
} else if (arg.startsWith('--recipe=')) {
|
|
1007
1018
|
recipeName = arg.split('=')[1];
|
|
1019
|
+
} else if (arg === '--dry-run' || arg === '--dryrun') {
|
|
1020
|
+
dryRun = true;
|
|
1021
|
+
} else if (arg === '--explain') {
|
|
1022
|
+
explain = true;
|
|
1023
|
+
} else if (arg === '--legacy') {
|
|
1024
|
+
legacy = true;
|
|
1025
|
+
} else if (arg === '--telemetry' && commandArgs[i + 1]) {
|
|
1026
|
+
telemetry = commandArgs[++i];
|
|
1027
|
+
} else if (arg.startsWith('--telemetry=')) {
|
|
1028
|
+
telemetry = arg.split('=')[1] || 'off';
|
|
1008
1029
|
} else if (!arg.startsWith('-')) {
|
|
1009
1030
|
targetInput = arg;
|
|
1010
1031
|
}
|
|
1011
1032
|
}
|
|
1012
|
-
initProject(targetInput, { recipeName });
|
|
1033
|
+
initProject(targetInput, { recipeName, dryRun, explain, legacy, telemetry });
|
|
1013
1034
|
} else if (command === 'create') {
|
|
1014
1035
|
createTemplate(commandArgs[0]);
|
|
1015
1036
|
} else if (command === 'add') {
|
|
@@ -1072,7 +1093,8 @@ if (command === 'init') {
|
|
|
1072
1093
|
DENEB UI Framework — Powered by DENEB-UI Collaborate with FIVORA
|
|
1073
1094
|
|
|
1074
1095
|
Core Commands:
|
|
1075
|
-
init
|
|
1096
|
+
init Deneb ARC: convert an existing React/Next.js app into a Fivora-editable storefront
|
|
1097
|
+
flags: --dry-run --explain --recipe <name> --legacy --telemetry off|anonymous|enhanced
|
|
1076
1098
|
doctor Run comprehensive environment, manifest, visual editing AST & asset diagnostic checks (flags: --fix, --json)
|
|
1077
1099
|
save-recipe Learn and save calibrated fixes & schemas into reusable recipe bank (e.g. deneb save-recipe . shoes-store)
|
|
1078
1100
|
learn Alias for save-recipe
|
|
@@ -1093,9 +1115,12 @@ Examples:
|
|
|
1093
1115
|
deneb doctor --fix
|
|
1094
1116
|
deneb doctor --json
|
|
1095
1117
|
deneb init
|
|
1118
|
+
deneb init --dry-run
|
|
1119
|
+
deneb init --explain
|
|
1096
1120
|
deneb init --recipe fashion
|
|
1097
1121
|
deneb init --recipe electronics
|
|
1098
1122
|
deneb init --recipe cosmetics
|
|
1123
|
+
deneb init --legacy
|
|
1099
1124
|
deneb update
|
|
1100
1125
|
deneb validate .
|
|
1101
1126
|
deneb validate --zip
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deneb-ui/cli",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "Official
|
|
3
|
+
"version": "2.0.23",
|
|
4
|
+
"description": "Official DENEB CLI — scaffold, convert, validate, and package Fivora-ready storefront templates.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"deneb": "bin/index.js",
|
|
7
7
|
"denebui": "bin/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"url": "git+https://github.com/deneb-ui/core.git",
|
|
16
16
|
"directory": "cli/deneb-cli"
|
|
17
17
|
},
|
|
18
|
-
"homepage": "https://
|
|
18
|
+
"homepage": "https://deneb.fivora.site/docs/cli",
|
|
19
19
|
"bugs": {
|
|
20
20
|
"url": "https://github.com/deneb-ui/core/issues"
|
|
21
21
|
},
|
|
@@ -24,16 +24,31 @@
|
|
|
24
24
|
"src",
|
|
25
25
|
"README.md"
|
|
26
26
|
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"test": "node --test src/arc/__tests__/arc.test.cjs"
|
|
29
|
+
},
|
|
27
30
|
"keywords": [
|
|
28
31
|
"deneb",
|
|
29
32
|
"deneb-ui",
|
|
30
33
|
"cli",
|
|
34
|
+
"fivora",
|
|
35
|
+
"nextjs",
|
|
36
|
+
"template",
|
|
31
37
|
"validator",
|
|
32
|
-
"packager"
|
|
38
|
+
"packager",
|
|
39
|
+
"visual-editing",
|
|
40
|
+
"storefront",
|
|
41
|
+
"scaffold"
|
|
33
42
|
],
|
|
34
43
|
"author": "Chamika Gayashan & Induranga Kawishwara",
|
|
44
|
+
"contributors": [
|
|
45
|
+
"Chamika Gayashan <https://github.com/chamikathereal>",
|
|
46
|
+
"Induranga Kawishwara <https://github.com/Induranga-kawishwara>"
|
|
47
|
+
],
|
|
35
48
|
"license": "MIT",
|
|
36
49
|
"dependencies": {
|
|
37
|
-
"
|
|
50
|
+
"@babel/parser": "^7.28.0",
|
|
51
|
+
"adm-zip": "^0.6.0",
|
|
52
|
+
"recast": "^0.23.11"
|
|
38
53
|
}
|
|
39
54
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function Hero() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="hero">
|
|
4
|
+
<h1>Summer Collection</h1>
|
|
5
|
+
<p>Discover lightweight performance apparel for every season.</p>
|
|
6
|
+
<a href="https://wa.me/94771234567" className="btn cta">
|
|
7
|
+
Start a Conversation
|
|
8
|
+
</a>
|
|
9
|
+
<img src="/hero.jpg" alt="Summer Collection" />
|
|
10
|
+
</section>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "new-york",
|
|
4
|
+
"tailwind": {
|
|
5
|
+
"config": "",
|
|
6
|
+
"css": "src/app/globals.css",
|
|
7
|
+
"baseColor": "slate",
|
|
8
|
+
"cssVariables": true
|
|
9
|
+
},
|
|
10
|
+
"aliases": {
|
|
11
|
+
"components": "@/components",
|
|
12
|
+
"ui": "@/components/ui"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "acme-storefront",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "next dev",
|
|
7
|
+
"build": "next build"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"next": "15.1.0",
|
|
11
|
+
"react": "19.0.0",
|
|
12
|
+
"react-dom": "19.0.0",
|
|
13
|
+
"lucide-react": "^0.460.0",
|
|
14
|
+
"framer-motion": "^11.11.0",
|
|
15
|
+
"class-variance-authority": "^0.7.0",
|
|
16
|
+
"@radix-ui/react-slot": "^1.1.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"tailwindcss": "^4.0.0",
|
|
20
|
+
"typescript": "^5.6.0"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default function AboutPage() {
|
|
2
|
+
return (
|
|
3
|
+
<main className="mx-auto max-w-3xl px-6 py-24">
|
|
4
|
+
<h1 className="text-4xl font-semibold tracking-tight">Our Story</h1>
|
|
5
|
+
<p className="mt-6 text-lg leading-relaxed text-slate-600">
|
|
6
|
+
Acme was founded in a garage in 2014 with a single goal: build tools that outlast trends.
|
|
7
|
+
</p>
|
|
8
|
+
<div className="mt-10 text-sm text-slate-500">
|
|
9
|
+
Every product is assembled by hand in small batches.
|
|
10
|
+
</div>
|
|
11
|
+
</main>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { SiteHeader } from '@/components/SiteHeader';
|
|
3
|
+
import { SiteFooter } from '@/components/SiteFooter';
|
|
4
|
+
|
|
5
|
+
export const metadata = {
|
|
6
|
+
title: 'Acme Storefront',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
10
|
+
return (
|
|
11
|
+
<html lang="en">
|
|
12
|
+
<body className="min-h-screen bg-white text-slate-900 antialiased">
|
|
13
|
+
<SiteHeader />
|
|
14
|
+
{children}
|
|
15
|
+
<SiteFooter />
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Hero } from '@/components/Hero';
|
|
2
|
+
import { ProductGrid } from '@/components/ProductGrid';
|
|
3
|
+
import { Features } from '@/components/Features';
|
|
4
|
+
|
|
5
|
+
export default function HomePage() {
|
|
6
|
+
return (
|
|
7
|
+
<main className="flex flex-col gap-24 pb-24">
|
|
8
|
+
<Hero />
|
|
9
|
+
<ProductGrid />
|
|
10
|
+
<Features />
|
|
11
|
+
</main>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { motion } from 'framer-motion';
|
|
4
|
+
import { Truck, ShieldCheck, Recycle } from 'lucide-react';
|
|
5
|
+
|
|
6
|
+
const features = [
|
|
7
|
+
{ icon: Truck, title: 'Free carbon-neutral shipping', body: 'On every order above $80.' },
|
|
8
|
+
{ icon: ShieldCheck, title: 'Five year warranty', body: 'Repairs handled in-house, forever.' },
|
|
9
|
+
{ icon: Recycle, title: 'Circular by design', body: 'Send it back and we rebuild it.' },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
export function Features() {
|
|
13
|
+
return (
|
|
14
|
+
<section className="bg-slate-50 px-6 py-20">
|
|
15
|
+
<div className="mx-auto grid max-w-5xl gap-10 md:grid-cols-3">
|
|
16
|
+
{features.map((feature) => (
|
|
17
|
+
<motion.div
|
|
18
|
+
key={feature.title}
|
|
19
|
+
initial={{ opacity: 0, y: 12 }}
|
|
20
|
+
whileInView={{ opacity: 1, y: 0 }}
|
|
21
|
+
className="flex flex-col gap-3"
|
|
22
|
+
>
|
|
23
|
+
<feature.icon className="size-6 text-slate-900" aria-hidden="true" />
|
|
24
|
+
<h3 className="text-base font-semibold">{feature.title}</h3>
|
|
25
|
+
<p className="text-sm text-slate-600">{feature.body}</p>
|
|
26
|
+
</motion.div>
|
|
27
|
+
))}
|
|
28
|
+
</div>
|
|
29
|
+
</section>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import Image from 'next/image';
|
|
2
|
+
import Link from 'next/link';
|
|
3
|
+
import { ArrowRight } from 'lucide-react';
|
|
4
|
+
import { Button } from '@/components/ui/button';
|
|
5
|
+
|
|
6
|
+
export function Hero() {
|
|
7
|
+
const badge = 'New Season 2026';
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<section className="relative grid gap-12 px-6 pt-20 md:grid-cols-2 md:items-center">
|
|
11
|
+
<div className="flex flex-col gap-6">
|
|
12
|
+
<span className="w-fit rounded-full bg-slate-100 px-3 py-1 text-xs uppercase tracking-widest">
|
|
13
|
+
{badge}
|
|
14
|
+
</span>
|
|
15
|
+
<h1 className="text-5xl font-semibold leading-tight tracking-tight">
|
|
16
|
+
Engineered for modern living
|
|
17
|
+
</h1>
|
|
18
|
+
<p className="max-w-md text-lg text-slate-600">
|
|
19
|
+
Discover a minimalist collection crafted from premium materials that age beautifully.
|
|
20
|
+
</p>
|
|
21
|
+
<div className="flex items-center gap-4">
|
|
22
|
+
<Button asChild>
|
|
23
|
+
<Link href="/products">
|
|
24
|
+
Shop the collection
|
|
25
|
+
<ArrowRight className="ml-2 size-4" aria-hidden="true" />
|
|
26
|
+
</Link>
|
|
27
|
+
</Button>
|
|
28
|
+
<a
|
|
29
|
+
href="https://wa.me/15550192834"
|
|
30
|
+
className="text-sm font-medium underline underline-offset-4"
|
|
31
|
+
>
|
|
32
|
+
Chat with a stylist
|
|
33
|
+
</a>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<Image
|
|
37
|
+
src="/hero-lounge.webp"
|
|
38
|
+
alt="Lounge chair in a sunlit room"
|
|
39
|
+
width={720}
|
|
40
|
+
height={540}
|
|
41
|
+
className="rounded-3xl object-cover shadow-2xl"
|
|
42
|
+
/>
|
|
43
|
+
</section>
|
|
44
|
+
);
|
|
45
|
+
}
|