create-credbuild-app 0.1.0

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 ADDED
@@ -0,0 +1,52 @@
1
+ # create-credbuild-app
2
+
3
+ Create a new [CredBuild](https://crediblemark.com) project with a single command.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ npx create-credbuild-app my-website
9
+ cd my-website
10
+ npm run dev
11
+ ```
12
+
13
+ Then open [http://localhost:3000/edit](http://localhost:3000/edit) to access the visual editor.
14
+
15
+ ## What's included
16
+
17
+ - ⚡ **Next.js 16** — Latest framework with App Router
18
+ - 🎨 **40+ Premium Blocks** — Hero sections, pricing, testimonials, galleries, and more
19
+ - 🖼️ **Visual Drag & Drop Editor** — Build pages without code
20
+ - 📱 **Responsive** — Every block works on all screen sizes
21
+ - 🎯 **SEO Optimized** — Semantic HTML and meta tags built-in
22
+ - 🔧 **Fully Customizable** — Fine-tune colors, spacing, and typography
23
+
24
+ ## Project Structure
25
+
26
+ ```
27
+ my-website/
28
+ ├── src/
29
+ │ ├── app/
30
+ │ │ ├── page.tsx # Landing page
31
+ │ │ ├── layout.tsx # Root layout
32
+ │ │ ├── globals.css # Global styles
33
+ │ │ ├── credbuild/ # Editor route
34
+ │ │ └── api/ # API routes
35
+ │ └── proxy.ts # Media proxy
36
+ ├── credbuild.config.tsx # Block configuration
37
+ ├── next.config.ts # Next.js config
38
+ └── package.json
39
+ ```
40
+
41
+ ## Commands
42
+
43
+ | Command | Description |
44
+ |---------|-------------|
45
+ | `npm run dev` | Start development server |
46
+ | `npm run build` | Build for production |
47
+ | `npm start` | Start production server |
48
+
49
+ ## Learn More
50
+
51
+ - [CredBuild Documentation](https://crediblemark.com/docs)
52
+ - [Next.js Documentation](https://nextjs.org/docs)
package/bin/index.mjs ADDED
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execSync } from "node:child_process";
4
+ import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
+ import { basename, join, resolve, dirname } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+
10
+ // ── Colors (no dependencies) ────────────────────────────────────────
11
+ const bold = (t) => `\x1b[1m${t}\x1b[22m`;
12
+ const cyan = (t) => `\x1b[36m${t}\x1b[39m`;
13
+ const green = (t) => `\x1b[32m${t}\x1b[39m`;
14
+ const yellow = (t) => `\x1b[33m${t}\x1b[39m`;
15
+ const dim = (t) => `\x1b[2m${t}\x1b[22m`;
16
+ const red = (t) => `\x1b[31m${t}\x1b[39m`;
17
+
18
+ // ── Banner ──────────────────────────────────────────────────────────
19
+ function banner() {
20
+ console.log();
21
+ console.log(bold(cyan(" ╔═══════════════════════════════════════╗")));
22
+ console.log(bold(cyan(" ║ ║")));
23
+ console.log(bold(cyan(" ║") + " ⚡ " + yellow("create-credbuild-app") + " " + cyan("║")));
24
+ console.log(bold(cyan(" ║") + " Visual Website Builder Scaffold " + cyan("║")));
25
+ console.log(bold(cyan(" ║ ║")));
26
+ console.log(bold(cyan(" ╚═══════════════════════════════════════╝")));
27
+ console.log();
28
+ }
29
+
30
+ // ── Detect package manager ──────────────────────────────────────────
31
+ function detectPM() {
32
+ const ua = process.env.npm_config_user_agent || "";
33
+ if (ua.startsWith("bun")) return "bun";
34
+ if (ua.startsWith("pnpm")) return "pnpm";
35
+ if (ua.startsWith("yarn")) return "yarn";
36
+ return "npm";
37
+ }
38
+
39
+ // ── Main ────────────────────────────────────────────────────────────
40
+ function main() {
41
+ banner();
42
+
43
+ const args = process.argv.slice(2);
44
+ const projectName = args[0];
45
+
46
+ if (!projectName || projectName.startsWith("-")) {
47
+ console.log(` ${red("Error:")} Please specify the project name:`);
48
+ console.log();
49
+ console.log(` ${cyan("npx create-credbuild-app")} ${green("<project-name>")}`);
50
+ console.log();
51
+ console.log(" Example:");
52
+ console.log(` ${cyan("npx create-credbuild-app")} ${green("my-website")}`);
53
+ console.log();
54
+ process.exit(1);
55
+ }
56
+
57
+ const targetDir = resolve(process.cwd(), projectName);
58
+
59
+ // Check if directory already exists
60
+ if (existsSync(targetDir)) {
61
+ console.log(` ${red("Error:")} Directory ${bold(projectName)} already exists.`);
62
+ console.log(` Please choose a different name or remove the existing directory.`);
63
+ console.log();
64
+ process.exit(1);
65
+ }
66
+
67
+ const templateDir = join(__dirname, "..", "template");
68
+
69
+ // 1. Copy template
70
+ console.log(` ${cyan("●")} Creating project in ${bold(projectName)}...`);
71
+ mkdirSync(targetDir, { recursive: true });
72
+ cpSync(templateDir, targetDir, { recursive: true });
73
+
74
+ // 2. Update package.json with project name
75
+ const pkgPath = join(targetDir, "package.json");
76
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
77
+ pkg.name = basename(projectName);
78
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
79
+ console.log(` ${green("✓")} Template copied`);
80
+
81
+ // 3. Create .gitignore (can't be included in npm package as "template/.gitignore")
82
+ const gitignoreContent = `# dependencies
83
+ node_modules/
84
+ .pnp
85
+ .pnp.js
86
+
87
+ # testing
88
+ coverage/
89
+
90
+ # next.js
91
+ .next/
92
+ out/
93
+
94
+ # production
95
+ build/
96
+ dist/
97
+
98
+ # misc
99
+ .DS_Store
100
+ *.pem
101
+
102
+ # debug
103
+ npm-debug.log*
104
+ yarn-debug.log*
105
+ yarn-error.log*
106
+ .pnpm-debug.log*
107
+
108
+ # env
109
+ .env*.local
110
+
111
+ # typescript
112
+ *.tsbuildinfo
113
+ next-env.d.ts
114
+ `;
115
+ writeFileSync(join(targetDir, ".gitignore"), gitignoreContent);
116
+
117
+ // 4. Install dependencies
118
+ const pm = detectPM();
119
+ console.log(` ${cyan("●")} Installing dependencies with ${bold(pm)}...`);
120
+ console.log();
121
+
122
+ try {
123
+ execSync(`${pm} install`, {
124
+ cwd: targetDir,
125
+ stdio: "inherit",
126
+ });
127
+ } catch {
128
+ console.log();
129
+ console.log(` ${yellow("⚠")} Install failed. You can install manually:`);
130
+ console.log(` cd ${projectName} && ${pm} install`);
131
+ console.log();
132
+ }
133
+
134
+ // 5. Done!
135
+ console.log();
136
+ console.log(` ${green("✓")} ${bold("Project created successfully!")}`);
137
+ console.log();
138
+ console.log(" Get started:");
139
+ console.log();
140
+ console.log(` ${cyan("cd")} ${projectName}`);
141
+ console.log(` ${cyan(`${pm === "npm" ? "npm run" : pm} dev`)}`);
142
+ console.log();
143
+ console.log(` Then open ${bold(cyan("http://localhost:3000/edit"))} in your browser.`);
144
+ console.log();
145
+ }
146
+
147
+ main();
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "create-credbuild-app",
3
+ "version": "0.1.0",
4
+ "description": "Create a new CredBuild project with a single command",
5
+ "license": "MIT",
6
+ "bin": {
7
+ "create-credbuild-app": "./bin/index.mjs"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "template"
12
+ ],
13
+ "keywords": [
14
+ "credbuild",
15
+ "website-builder",
16
+ "nextjs",
17
+ "drag-and-drop",
18
+ "visual-editor"
19
+ ]
20
+ }
@@ -0,0 +1,7 @@
1
+ "use client";
2
+
3
+ import { buildUiPreset } from "@crediblemark/build-ui";
4
+
5
+ const config = buildUiPreset;
6
+
7
+ export default config;
@@ -0,0 +1,18 @@
1
+ import { defineConfig, globalIgnores } from "eslint/config";
2
+ import nextVitals from "eslint-config-next/core-web-vitals";
3
+ import nextTs from "eslint-config-next/typescript";
4
+
5
+ const eslintConfig = defineConfig([
6
+ ...nextVitals,
7
+ ...nextTs,
8
+ // Override default ignores of eslint-config-next.
9
+ globalIgnores([
10
+ // Default ignores of eslint-config-next:
11
+ ".next/**",
12
+ "out/**",
13
+ "build/**",
14
+ "next-env.d.ts",
15
+ ]),
16
+ ]);
17
+
18
+ export default eslintConfig;
@@ -0,0 +1,6 @@
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+ import "./.next/dev/types/routes.d.ts";
4
+
5
+ // NOTE: This file should not be edited
6
+ // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
@@ -0,0 +1,28 @@
1
+ // @ts-ignore
2
+ import type { NextConfig } from "next";
3
+
4
+ const nextConfig: NextConfig = {
5
+ transpilePackages: ['@crediblemark/build', '@crediblemark/build-ui'],
6
+ serverExternalPackages: ['isomorphic-dompurify', 'jsdom', 'parse5'],
7
+ images: {
8
+ unoptimized: true,
9
+ },
10
+ webpack: (config: any, { isServer, webpack }: { isServer: boolean; webpack: any }) => {
11
+ if (!isServer) {
12
+ config.plugins.push(
13
+ new webpack.NormalModuleReplacementPlugin(
14
+ /^isomorphic-dompurify$/,
15
+ 'dompurify'
16
+ )
17
+ );
18
+ config.resolve.fallback = {
19
+ ...config.resolve.fallback,
20
+ "parse5": false,
21
+ "jsdom": false,
22
+ };
23
+ }
24
+ return config;
25
+ }
26
+ };
27
+
28
+ export default nextConfig;
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "my-credbuild-app",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev --webpack",
7
+ "build": "next build --webpack",
8
+ "start": "next start",
9
+ "lint": "eslint"
10
+ },
11
+ "dependencies": {
12
+ "@crediblemark/build": "^0.25.5",
13
+ "@crediblemark/build-ui": "^0.25.7",
14
+ "@tiptap/starter-kit": "^3.23.4",
15
+ "next": "^16.2.6",
16
+ "react": "^19.2.4",
17
+ "react-dom": "^19.2.4"
18
+ },
19
+ "devDependencies": {
20
+ "@tailwindcss/postcss": "^4",
21
+ "@types/node": "^20",
22
+ "@types/react": "^19",
23
+ "@types/react-dom": "^19",
24
+ "eslint": "^9",
25
+ "eslint-config-next": "^16.2.6",
26
+ "tailwindcss": "^4",
27
+ "typescript": "^5"
28
+ }
29
+ }
@@ -0,0 +1,7 @@
1
+ const config = {
2
+ plugins: {
3
+ "@tailwindcss/postcss": {},
4
+ },
5
+ };
6
+
7
+ export default config;
@@ -0,0 +1 @@
1
+ <svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
@@ -0,0 +1,17 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { writeFile } from 'fs/promises';
3
+ import { join } from 'path';
4
+
5
+ export async function POST(req: Request) {
6
+ try {
7
+ const data = await req.json();
8
+ const DB_PATH = join(process.cwd(), 'database.json');
9
+
10
+ // Save the published data to a local JSON file to simulate a database
11
+ await writeFile(DB_PATH, JSON.stringify(data, null, 2));
12
+
13
+ return NextResponse.json({ success: true });
14
+ } catch (error) {
15
+ return NextResponse.json({ error: "Failed to save" }, { status: 500 });
16
+ }
17
+ }
@@ -0,0 +1,23 @@
1
+ import { NextResponse } from 'next/server';
2
+
3
+ export async function GET(request: Request) {
4
+ const { searchParams } = new URL(request.url);
5
+ const url = searchParams.get('url');
6
+
7
+ if (!url) {
8
+ return new NextResponse('Missing url parameter', { status: 400 });
9
+ }
10
+
11
+ try {
12
+ const response = await fetch(url);
13
+ const buffer = await response.arrayBuffer();
14
+ return new NextResponse(buffer, {
15
+ headers: {
16
+ 'Content-Type': response.headers.get('content-type') || 'image/jpeg',
17
+ 'Cache-Control': 'public, max-age=31536000, immutable',
18
+ },
19
+ });
20
+ } catch (error) {
21
+ return new NextResponse('Error fetching image', { status: 500 });
22
+ }
23
+ }
@@ -0,0 +1,52 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { writeFile, mkdir } from 'fs/promises';
3
+ import { join } from 'path';
4
+
5
+ // In-memory store for development simulation
6
+ // In production, you would fetch this from a database
7
+ let mediaStore: any[] = [];
8
+
9
+ export async function GET() {
10
+ return NextResponse.json({ data: mediaStore });
11
+ }
12
+
13
+ export async function POST(request: Request) {
14
+ try {
15
+ const formData = await request.formData();
16
+ const file = formData.get('file') as File;
17
+
18
+ if (!file) {
19
+ return NextResponse.json({ error: "No file uploaded" }, { status: 400 });
20
+ }
21
+
22
+ const bytes = await file.arrayBuffer();
23
+ const buffer = Buffer.from(bytes);
24
+
25
+ // Save locally to simulate S3/Cloudflare R2 bucket behavior
26
+ const uploadDir = join(process.cwd(), 'public', 'uploads');
27
+ await mkdir(uploadDir, { recursive: true });
28
+
29
+ const filename = `${Date.now()}-${file.name.replace(/[^a-zA-Z0-9.-]/g, '_')}`;
30
+ const path = join(uploadDir, filename);
31
+ await writeFile(path, buffer);
32
+
33
+ // Generate the public URL that acts like a cloud storage URL
34
+ const url = `/uploads/${filename}`;
35
+
36
+ const mediaItem = {
37
+ id: Date.now().toString(),
38
+ filename: file.name,
39
+ url,
40
+ mimeType: file.type,
41
+ size: file.size,
42
+ };
43
+
44
+ // Save to our dummy database
45
+ mediaStore = [mediaItem, ...mediaStore];
46
+
47
+ return NextResponse.json(mediaItem);
48
+ } catch (e) {
49
+ console.error("Upload error:", e);
50
+ return NextResponse.json({ error: "Upload failed" }, { status: 500 });
51
+ }
52
+ }
@@ -0,0 +1,33 @@
1
+ "use client";
2
+
3
+ import { CredBuild } from "@crediblemark/build";
4
+ import config from "../../../../credbuild.config";
5
+
6
+ export function EditorClient({ path, data }: { path: string[], data: any }) {
7
+ return (
8
+ <CredBuild
9
+ config={config as any}
10
+ data={data}
11
+ headerPath={path.length > 0 ? path.join("/") : "/"}
12
+ iframe={{ enabled: false }}
13
+ onPublish={async (newData: any) => {
14
+ try {
15
+ const res = await fetch('/api/credbuild', {
16
+ method: 'POST',
17
+ body: JSON.stringify(newData),
18
+ });
19
+ if (res.ok) {
20
+ alert("Berhasil disimpan!");
21
+ } else {
22
+ alert("Gagal menyimpan!");
23
+ }
24
+ } catch (e) {
25
+ alert("Terjadi kesalahan jaringan!");
26
+ }
27
+ }}
28
+ onChange={(newData: any) => {
29
+ console.log("Editor Data Changed:", newData);
30
+ }}
31
+ />
32
+ );
33
+ }
@@ -0,0 +1,22 @@
1
+ import { EditorClient } from "./EditorClient";
2
+ import { readFile } from "fs/promises";
3
+ import { join } from "path";
4
+
5
+ export default async function EditorPage({ params }: { params: Promise<{ path?: string[] }> }) {
6
+ const { path } = await params;
7
+
8
+ let data = {};
9
+ try {
10
+ const DB_PATH = join(process.cwd(), "database.json");
11
+ const file = await readFile(DB_PATH, "utf-8");
12
+ data = JSON.parse(file);
13
+ } catch (e) {
14
+ // ignore, start fresh
15
+ }
16
+
17
+ return (
18
+ <div style={{ height: "100vh", display: "flex", flexDirection: "column" }}>
19
+ <EditorClient path={path || []} data={data} />
20
+ </div>
21
+ );
22
+ }
Binary file
@@ -0,0 +1,31 @@
1
+ /* Layer 2: Theming (colors, variables, font) */
2
+ @import "@crediblemark/build/dist/index.css";
3
+ /* Layer 3: Compact sizing (padding, height, font-size) */
4
+ @import "@crediblemark/build-ui/sidebar-neat.css";
5
+ /* Tailwind */
6
+ @import "tailwindcss";
7
+
8
+ :root {
9
+ --background: #ffffff;
10
+ --foreground: #171717;
11
+ }
12
+
13
+ @theme inline {
14
+ --color-background: var(--background);
15
+ --color-foreground: var(--foreground);
16
+ --font-sans: var(--font-geist-sans);
17
+ --font-mono: var(--font-geist-mono);
18
+ }
19
+
20
+ @media (prefers-color-scheme: dark) {
21
+ :root {
22
+ --background: #0a0a0a;
23
+ --foreground: #ededed;
24
+ }
25
+ }
26
+
27
+ body {
28
+ background: var(--background);
29
+ color: var(--foreground);
30
+ font-family: Arial, Helvetica, sans-serif;
31
+ }
@@ -0,0 +1,34 @@
1
+ import type { Metadata } from "next";
2
+ import { Geist, Geist_Mono } from "next/font/google";
3
+ import "./globals.css";
4
+
5
+ const geistSans = Geist({
6
+ variable: "--font-geist-sans",
7
+ subsets: ["latin"],
8
+ });
9
+
10
+ const geistMono = Geist_Mono({
11
+ variable: "--font-geist-mono",
12
+ subsets: ["latin"],
13
+ });
14
+
15
+ export const metadata: Metadata = {
16
+ title: "CredBuild — Visual Website Builder",
17
+ description:
18
+ "Build stunning websites visually with drag-and-drop blocks. No coding required.",
19
+ };
20
+
21
+ export default function RootLayout({
22
+ children,
23
+ }: Readonly<{
24
+ children: React.ReactNode;
25
+ }>) {
26
+ return (
27
+ <html
28
+ lang="en"
29
+ className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
30
+ >
31
+ <body className="min-h-full flex flex-col">{children}</body>
32
+ </html>
33
+ );
34
+ }
@@ -0,0 +1,355 @@
1
+ import Link from "next/link";
2
+
3
+ export default function Home() {
4
+ return (
5
+ <div className="flex flex-col min-h-screen bg-[#0a0a0a] text-white overflow-hidden">
6
+ {/* Ambient glow effects */}
7
+ <div
8
+ className="pointer-events-none fixed inset-0"
9
+ aria-hidden="true"
10
+ >
11
+ <div className="absolute top-[-20%] left-[10%] w-[500px] h-[500px] rounded-full bg-amber-500/[0.07] blur-[120px]" />
12
+ <div className="absolute bottom-[-10%] right-[15%] w-[400px] h-[400px] rounded-full bg-violet-500/[0.05] blur-[100px]" />
13
+ </div>
14
+
15
+ {/* Header */}
16
+ <header className="relative z-10 flex items-center justify-between px-6 py-5 md:px-12">
17
+ <div className="flex items-center gap-2">
18
+ <div className="w-8 h-8 rounded-lg bg-gradient-to-br from-amber-400 to-orange-500 flex items-center justify-center font-bold text-sm text-black">
19
+ CB
20
+ </div>
21
+ <span className="text-lg font-semibold tracking-tight">
22
+ CredBuild
23
+ </span>
24
+ </div>
25
+ <nav className="hidden md:flex items-center gap-8 text-sm text-zinc-400">
26
+ <a href="#features" className="hover:text-white transition-colors">
27
+ Features
28
+ </a>
29
+ <a href="#blocks" className="hover:text-white transition-colors">
30
+ Blocks
31
+ </a>
32
+ <a href="#pricing" className="hover:text-white transition-colors">
33
+ Pricing
34
+ </a>
35
+ </nav>
36
+ <Link
37
+ href="/edit"
38
+ className="px-5 py-2 text-sm font-medium rounded-lg bg-white/10 border border-white/10 hover:bg-white/15 transition-all backdrop-blur-sm"
39
+ >
40
+ Open Editor
41
+ </Link>
42
+ </header>
43
+
44
+ {/* Hero */}
45
+ <main className="relative z-10 flex-1 flex flex-col items-center justify-center text-center px-6 py-20 md:py-32">
46
+ <div className="inline-flex items-center gap-2 px-4 py-1.5 mb-8 rounded-full border border-amber-500/20 bg-amber-500/5 text-amber-400 text-xs font-medium tracking-wide uppercase">
47
+ <span className="w-1.5 h-1.5 rounded-full bg-amber-400 animate-pulse" />
48
+ Visual Website Builder
49
+ </div>
50
+
51
+ <h1 className="max-w-3xl text-4xl md:text-6xl lg:text-7xl font-bold tracking-tight leading-[1.1]">
52
+ Build websites{" "}
53
+ <span className="bg-gradient-to-r from-amber-300 via-orange-400 to-amber-500 bg-clip-text text-transparent">
54
+ visually
55
+ </span>
56
+ <br />
57
+ with drag & drop
58
+ </h1>
59
+
60
+ <p className="mt-6 max-w-xl text-lg text-zinc-400 leading-relaxed">
61
+ Powerful block-based editor with 40+ premium components.
62
+ Design stunning pages without writing a single line of code.
63
+ </p>
64
+
65
+ <div className="flex flex-col sm:flex-row items-center gap-4 mt-10">
66
+ <Link
67
+ href="/edit"
68
+ className="group relative px-8 py-3.5 rounded-xl bg-gradient-to-r from-amber-500 to-orange-500 text-black font-semibold text-sm tracking-wide hover:shadow-[0_0_30px_rgba(245,158,11,0.3)] transition-all duration-300"
69
+ >
70
+ Start Building
71
+ <span className="ml-2 inline-block group-hover:translate-x-1 transition-transform">
72
+
73
+ </span>
74
+ </Link>
75
+ <a
76
+ href="#features"
77
+ className="px-8 py-3.5 rounded-xl border border-white/10 text-sm font-medium text-zinc-300 hover:text-white hover:border-white/20 transition-all"
78
+ >
79
+ Learn More
80
+ </a>
81
+ </div>
82
+
83
+ {/* Editor preview mockup */}
84
+ <div className="relative mt-20 w-full max-w-4xl">
85
+ <div className="absolute inset-0 bg-gradient-to-t from-[#0a0a0a] via-transparent to-transparent z-10 pointer-events-none" />
86
+ <div className="rounded-xl border border-white/10 bg-white/[0.03] backdrop-blur-sm overflow-hidden shadow-2xl shadow-black/50">
87
+ {/* Mockup toolbar */}
88
+ <div className="flex items-center gap-2 px-4 py-3 border-b border-white/10 bg-white/[0.02]">
89
+ <div className="flex gap-1.5">
90
+ <div className="w-3 h-3 rounded-full bg-red-500/60" />
91
+ <div className="w-3 h-3 rounded-full bg-yellow-500/60" />
92
+ <div className="w-3 h-3 rounded-full bg-green-500/60" />
93
+ </div>
94
+ <div className="flex-1 flex justify-center">
95
+ <div className="px-4 py-1 rounded-md bg-white/5 text-xs text-zinc-500 font-mono">
96
+ localhost:3000/edit
97
+ </div>
98
+ </div>
99
+ </div>
100
+ {/* Mockup content */}
101
+ <div className="flex h-64 md:h-80">
102
+ {/* Left sidebar */}
103
+ <div className="w-48 border-r border-white/10 bg-white/[0.02] p-3 hidden sm:block">
104
+ <div className="text-[10px] font-semibold text-zinc-500 uppercase tracking-wider mb-3">
105
+ Blocks
106
+ </div>
107
+ {[
108
+ "Hero Section",
109
+ "Feature Grid",
110
+ "Testimonials",
111
+ "Pricing Table",
112
+ "Contact Form",
113
+ "FAQ Accordion",
114
+ ].map((block) => (
115
+ <div
116
+ key={block}
117
+ className="px-2.5 py-1.5 mb-1 rounded text-xs text-zinc-400 bg-white/[0.03] border border-white/5 hover:border-amber-500/20 transition-colors"
118
+ >
119
+ {block}
120
+ </div>
121
+ ))}
122
+ </div>
123
+ {/* Canvas */}
124
+ <div className="flex-1 p-6 flex items-center justify-center">
125
+ <div className="text-center">
126
+ <div className="w-16 h-16 mx-auto mb-4 rounded-xl bg-gradient-to-br from-amber-500/20 to-orange-500/20 border border-amber-500/10 flex items-center justify-center">
127
+ <svg
128
+ width="24"
129
+ height="24"
130
+ viewBox="0 0 24 24"
131
+ fill="none"
132
+ stroke="currentColor"
133
+ strokeWidth="1.5"
134
+ className="text-amber-400"
135
+ >
136
+ <rect x="3" y="3" width="7" height="7" rx="1" />
137
+ <rect x="14" y="3" width="7" height="7" rx="1" />
138
+ <rect x="3" y="14" width="7" height="7" rx="1" />
139
+ <rect x="14" y="14" width="7" height="7" rx="1" />
140
+ </svg>
141
+ </div>
142
+ <p className="text-sm text-zinc-500">
143
+ Drag blocks here to start building
144
+ </p>
145
+ </div>
146
+ </div>
147
+ {/* Right sidebar */}
148
+ <div className="w-48 border-l border-white/10 bg-white/[0.02] p-3 hidden md:block">
149
+ <div className="text-[10px] font-semibold text-zinc-500 uppercase tracking-wider mb-3">
150
+ Properties
151
+ </div>
152
+ {["Title", "Subtitle", "Background", "Padding"].map(
153
+ (prop) => (
154
+ <div key={prop} className="mb-2">
155
+ <div className="text-[9px] text-zinc-600 mb-1">
156
+ {prop}
157
+ </div>
158
+ <div className="h-6 rounded bg-white/[0.04] border border-white/5" />
159
+ </div>
160
+ )
161
+ )}
162
+ </div>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ </main>
167
+
168
+ {/* Features */}
169
+ <section id="features" className="relative z-10 px-6 py-24 md:px-12">
170
+ <div className="max-w-5xl mx-auto">
171
+ <h2 className="text-3xl md:text-4xl font-bold text-center mb-4">
172
+ Everything you need
173
+ </h2>
174
+ <p className="text-zinc-400 text-center mb-16 max-w-lg mx-auto">
175
+ A complete toolkit for building professional websites at speed.
176
+ </p>
177
+
178
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
179
+ {[
180
+ {
181
+ icon: "⚡",
182
+ title: "40+ Premium Blocks",
183
+ desc: "Hero sections, pricing tables, testimonials, galleries, and more — all customizable.",
184
+ },
185
+ {
186
+ icon: "🎨",
187
+ title: "Visual Editor",
188
+ desc: "Intuitive drag-and-drop interface. See changes in real-time as you build.",
189
+ },
190
+ {
191
+ icon: "📱",
192
+ title: "Responsive Design",
193
+ desc: "Every block looks great on desktop, tablet, and mobile out of the box.",
194
+ },
195
+ {
196
+ icon: "🔧",
197
+ title: "Full Customization",
198
+ desc: "Fine-tune every property — colors, spacing, typography, and animations.",
199
+ },
200
+ {
201
+ icon: "🚀",
202
+ title: "Production Ready",
203
+ desc: "Export clean, optimized code. Built on Next.js for blazing fast performance.",
204
+ },
205
+ {
206
+ icon: "🎯",
207
+ title: "SEO Optimized",
208
+ desc: "Semantic HTML, meta tags, and structured data built into every component.",
209
+ },
210
+ ].map((feature) => (
211
+ <div
212
+ key={feature.title}
213
+ className="group p-6 rounded-xl border border-white/5 bg-white/[0.02] hover:border-amber-500/20 hover:bg-amber-500/[0.02] transition-all duration-300"
214
+ >
215
+ <div className="text-2xl mb-4">{feature.icon}</div>
216
+ <h3 className="font-semibold mb-2">{feature.title}</h3>
217
+ <p className="text-sm text-zinc-500 leading-relaxed">
218
+ {feature.desc}
219
+ </p>
220
+ </div>
221
+ ))}
222
+ </div>
223
+ </div>
224
+ </section>
225
+
226
+ {/* Get Started / Installation */}
227
+ <section className="relative z-10 px-6 py-24 md:px-12">
228
+ <div className="max-w-3xl mx-auto">
229
+ <h2 className="text-3xl md:text-4xl font-bold text-center mb-4">
230
+ Get started in seconds
231
+ </h2>
232
+ <p className="text-zinc-400 text-center mb-12 max-w-lg mx-auto">
233
+ Install the packages and start building right away.
234
+ </p>
235
+
236
+ <div className="space-y-4">
237
+ {/* Step 1 */}
238
+ <div className="rounded-xl border border-white/10 bg-white/[0.02] overflow-hidden">
239
+ <div className="flex items-center gap-3 px-5 py-3 border-b border-white/5">
240
+ <div className="w-6 h-6 rounded-full bg-amber-500/10 border border-amber-500/20 flex items-center justify-center text-xs font-bold text-amber-400">
241
+ 1
242
+ </div>
243
+ <span className="text-sm font-medium text-zinc-300">
244
+ Install packages
245
+ </span>
246
+ </div>
247
+ <div className="p-5 space-y-3">
248
+ <div className="group relative rounded-lg bg-black/60 border border-white/5 px-4 py-3 font-mono text-sm text-zinc-300">
249
+ <span className="text-amber-400">$</span>{" "}
250
+ npm i @crediblemark/build
251
+ </div>
252
+ <div className="group relative rounded-lg bg-black/60 border border-white/5 px-4 py-3 font-mono text-sm text-zinc-300">
253
+ <span className="text-amber-400">$</span>{" "}
254
+ npm i @crediblemark/build-ui
255
+ </div>
256
+ </div>
257
+ </div>
258
+
259
+ {/* Step 2 */}
260
+ <div className="rounded-xl border border-white/10 bg-white/[0.02] overflow-hidden">
261
+ <div className="flex items-center gap-3 px-5 py-3 border-b border-white/5">
262
+ <div className="w-6 h-6 rounded-full bg-amber-500/10 border border-amber-500/20 flex items-center justify-center text-xs font-bold text-amber-400">
263
+ 2
264
+ </div>
265
+ <span className="text-sm font-medium text-zinc-300">
266
+ Import and configure
267
+ </span>
268
+ </div>
269
+ <div className="p-5">
270
+ <div className="rounded-lg bg-black/60 border border-white/5 px-4 py-3 font-mono text-sm text-zinc-300 whitespace-pre leading-relaxed">
271
+ <span className="text-violet-400">import</span>
272
+ {" { "}
273
+ <span className="text-amber-300">buildUiPreset</span>
274
+ {" } "}
275
+ <span className="text-violet-400">from</span>{" "}
276
+ <span className="text-green-400">
277
+ &quot;@crediblemark/build-ui&quot;
278
+ </span>
279
+ ;{"\n"}
280
+ <span className="text-violet-400">import</span>{" "}
281
+ <span className="text-green-400">
282
+ &quot;@crediblemark/build/dist/index.css&quot;
283
+ </span>
284
+ ;{"\n"}
285
+ <span className="text-violet-400">import</span>{" "}
286
+ <span className="text-green-400">
287
+ &quot;@crediblemark/build-ui/sidebar-neat.css&quot;
288
+ </span>
289
+ ;
290
+ </div>
291
+ </div>
292
+ </div>
293
+
294
+ {/* Step 3 */}
295
+ <div className="rounded-xl border border-white/10 bg-white/[0.02] overflow-hidden">
296
+ <div className="flex items-center gap-3 px-5 py-3 border-b border-white/5">
297
+ <div className="w-6 h-6 rounded-full bg-amber-500/10 border border-amber-500/20 flex items-center justify-center text-xs font-bold text-amber-400">
298
+ 3
299
+ </div>
300
+ <span className="text-sm font-medium text-zinc-300">
301
+ Start building
302
+ </span>
303
+ </div>
304
+ <div className="p-5">
305
+ <div className="rounded-lg bg-black/60 border border-white/5 px-4 py-3 font-mono text-sm text-zinc-300">
306
+ <span className="text-amber-400">$</span> npm run dev
307
+ </div>
308
+ <p className="mt-3 text-xs text-zinc-500">
309
+ Open{" "}
310
+ <code className="px-1.5 py-0.5 rounded bg-white/5 text-amber-400 font-mono">
311
+ localhost:3000/edit
312
+ </code>{" "}
313
+ to access the visual editor.
314
+ </p>
315
+ </div>
316
+ </div>
317
+ </div>
318
+ </div>
319
+ </section>
320
+
321
+ {/* CTA */}
322
+ <section className="relative z-10 px-6 py-24 md:px-12">
323
+ <div className="max-w-2xl mx-auto text-center">
324
+ <h2 className="text-3xl md:text-4xl font-bold mb-4">
325
+ Ready to build?
326
+ </h2>
327
+ <p className="text-zinc-400 mb-8">
328
+ Jump straight into the editor and start creating your website.
329
+ </p>
330
+ <Link
331
+ href="/edit"
332
+ className="inline-flex items-center gap-2 px-8 py-4 rounded-xl bg-gradient-to-r from-amber-500 to-orange-500 text-black font-semibold tracking-wide hover:shadow-[0_0_40px_rgba(245,158,11,0.3)] transition-all duration-300"
333
+ >
334
+ Open Editor →
335
+ </Link>
336
+ </div>
337
+ </section>
338
+
339
+ {/* Footer */}
340
+ <footer className="relative z-10 border-t border-white/5 px-6 py-8 md:px-12">
341
+ <div className="max-w-5xl mx-auto flex flex-col md:flex-row items-center justify-between gap-4">
342
+ <div className="flex items-center gap-2 text-sm text-zinc-500">
343
+ <div className="w-5 h-5 rounded bg-gradient-to-br from-amber-400 to-orange-500 flex items-center justify-center font-bold text-[8px] text-black">
344
+ CB
345
+ </div>
346
+ CredBuild © {new Date().getFullYear()}
347
+ </div>
348
+ <p className="text-xs text-zinc-600">
349
+ Built with Next.js • Powered by CredBuild Engine
350
+ </p>
351
+ </div>
352
+ </footer>
353
+ </div>
354
+ );
355
+ }
@@ -0,0 +1,16 @@
1
+ import { NextResponse } from "next/server";
2
+ import type { NextRequest } from "next/server";
3
+
4
+ export function proxy(request: NextRequest) {
5
+ const url = request.nextUrl.clone();
6
+
7
+ if (url.pathname.endsWith("/edit")) {
8
+ const pathWithoutEdit = url.pathname.replace(/\/edit$/, "");
9
+ url.pathname = `/credbuild${pathWithoutEdit || "/"}`;
10
+ return NextResponse.rewrite(url);
11
+ }
12
+ }
13
+
14
+ export const config = {
15
+ matcher: '/:path*',
16
+ };
@@ -0,0 +1,34 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "react-jsx",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./src/*"]
23
+ }
24
+ },
25
+ "include": [
26
+ "next-env.d.ts",
27
+ "**/*.ts",
28
+ "**/*.tsx",
29
+ ".next/types/**/*.ts",
30
+ ".next/dev/types/**/*.ts",
31
+ "**/*.mts"
32
+ ],
33
+ "exclude": ["node_modules"]
34
+ }