Skip to content

Commit 8e76bd8

Browse files
committed
add heros section
1 parent 25b1d96 commit 8e76bd8

213 files changed

Lines changed: 20301 additions & 9049 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,11 @@ Use Wayfinder to generate TypeScript functions for Laravel routes. Import from `
212212

213213
- IMPORTANT: Activate `inertia-react-development` when working with Inertia React client-side patterns.
214214

215+
=== tailwindcss/shadcn rules ===
216+
217+
# TailwindCSS & Shadcn Colors
218+
219+
- NEVER use hardcoded theme colors like `bg-zinc-50`, `dark:bg-black`, `bg-emerald-50/50`, `dark:bg-zinc-950`, `text-emerald-700`, `dark:text-emerald-400`.
220+
- ALWAYS use semantic Shadcn variables and color tokens defined in `resources/css/app.css` (e.g., `bg-background`, `text-foreground`, `bg-card`, `text-card-foreground`, `bg-muted`, `text-muted-foreground`, `bg-primary`, `text-primary-foreground`, `bg-secondary`, `text-secondary-foreground`, `border-border`, `bg-destructive`, etc.). This ensures layout consistency and automatic compatibility in both light and dark modes.
221+
215222
</laravel-boost-guidelines>

GEMINI.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,11 @@ Use Wayfinder to generate TypeScript functions for Laravel routes. Import from `
212212

213213
- IMPORTANT: Activate `inertia-react-development` when working with Inertia React client-side patterns.
214214

215+
=== tailwindcss/shadcn rules ===
216+
217+
# TailwindCSS & Shadcn Colors
218+
219+
- NEVER use hardcoded theme colors like `bg-zinc-50`, `dark:bg-black`, `bg-emerald-50/50`, `dark:bg-zinc-950`, `text-emerald-700`, `dark:text-emerald-400`.
220+
- ALWAYS use semantic Shadcn variables and color tokens defined in `resources/css/app.css` (e.g., `bg-background`, `text-foreground`, `bg-card`, `text-card-foreground`, `bg-muted`, `text-muted-foreground`, `bg-primary`, `text-primary-foreground`, `bg-secondary`, `text-secondary-foreground`, `border-border`, `bg-destructive`, etc.). This ensures layout consistency and automatic compatibility in both light and dark modes.
221+
215222
</laravel-boost-guidelines>

app/Actions/Registry/StoreRegistryAction.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ class StoreRegistryAction
88
{
99
public function handle(array $data): Registry
1010
{
11-
return Registry::create($data);
11+
if (! isset($data['user_id']) && auth()->check()) {
12+
$data['user_id'] = auth()->id();
13+
}
14+
15+
$registry = new Registry;
16+
$registry->forceFill($data);
17+
$registry->save();
18+
19+
return $registry;
1220
}
1321
}

app/Console/Commands/RegistryBuildCommand.php

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,40 @@ public function handle(): int
6363
if (isset($pathParts[1]) && $pathParts[1] === 'ui') {
6464
$itemType = 'registry:ui';
6565
$category = $pathParts[2] ?? 'components';
66+
} elseif (isset($pathParts[1]) && $pathParts[1] === 'blocks') {
67+
$itemType = 'registry:block';
68+
$category = $pathParts[2] ?? 'blocks';
6669
} else {
6770
$itemType = 'registry:block';
68-
$category = 'blocks';
71+
$category = $pathParts[1] ?? 'blocks';
6972
}
7073
}
7174

72-
$name = ($itemType === 'registry:block') ? ($pathParts[1] ?? $filename) : $filename;
75+
// Normalise and group category names
76+
$categoryMap = [
77+
'hero-section' => 'hero-sections',
78+
'pricing-section' => 'pricing',
79+
'cards-stats' => 'stats',
80+
'booking-form' => 'forms',
81+
'rental-listings' => 'properties',
82+
'property-detail' => 'properties',
83+
'reviews-slider' => 'reviews',
84+
'buttons-gallery' => 'galleries',
85+
'canvas-gallery' => 'galleries',
86+
'inputs-gallery' => 'galleries',
87+
'music-player' => 'media',
88+
'threejs' => 'canvas',
89+
];
90+
$category = str_starts_with($category, 'hero-') ? 'hero-sections' : ($categoryMap[$category] ?? $category);
91+
92+
$name = $filename;
93+
if ($itemType === 'registry:block') {
94+
if (isset($pathParts[1]) && $pathParts[1] === 'blocks') {
95+
$name = $pathParts[2] ?? $filename;
96+
} else {
97+
$name = $pathParts[1] ?? $filename;
98+
}
99+
}
73100

74101
if (isset($registryItems[$name])) {
75102
$registryItems[$name]['files'][] = [
@@ -181,9 +208,78 @@ public function handle(): int
181208
}
182209
unset($item);
183210

211+
$descriptions = [
212+
'analytics-dashboard' => 'A comprehensive, premium analytics dashboard showing statistics, performance metrics, and graphs.',
213+
'booking-form' => 'A clean and responsive booking card form layout for properties or services.',
214+
'buttons-gallery' => 'A showcase of various button designs including magnetic, particles, and shining effect variants.',
215+
'canvas-gallery' => 'A beautiful presentation displaying interactive HTML Canvas art and experiments.',
216+
'cards-stats' => 'A collection of metric statistics cards with trends, indicator badges, and compact styling.',
217+
'feature-grid' => 'A clean grid layout to present core features of a product with icons and card hover states.',
218+
'hero-section' => 'A stunning and modern landing page hero section with typography and call to actions.',
219+
'inputs-gallery' => 'An interactive display showcasing specialized text, phone, currency, slug, and rating input components.',
220+
'music-player' => 'An immersive, premium client-side music player layout with playlist and visual controls.',
221+
'pricing-section' => 'A modern tiered pricing section with hover scale states, tags, and toggles.',
222+
'property-detail' => 'A clean and rich property details display page containing descriptions, photos, and reviews.',
223+
'rental-listings' => 'A responsive layout showing real estate property rental cards with search filters.',
224+
'reviews-slider' => 'A premium, smooth testimonial reviews slider with star ratings and user profiles.',
225+
'gsap-marquee' => 'A high-performance GSAP-powered horizontal scrolling marquee component.',
226+
'marquee' => 'A lightweight CSS-based horizontal text/elements scrolling marquee.',
227+
'text-animator' => 'An elegant text animator rendering typography with premium transitions.',
228+
'button-magnetic' => 'A premium magnetic button pull effect that snaps to the cursor position on hover.',
229+
'button-particles' => 'A vibrant button trigger releasing interactive confetti/particle explosions on click.',
230+
'button-shine' => 'A sleek button design showcasing a subtle glowing reflective shine transition.',
231+
'pixel-canvas' => 'An interactive background canvas that draws pixel highlights under the mouse cursor.',
232+
'back-light' => 'A modern card wrapper creating a glowing, color-matching backlight shadow behind components.',
233+
'glow-conic' => 'A beautiful border animation powered by a rotating conic color gradient.',
234+
'glow-radial' => 'An interactive background overlay that reflects cursor positioning with radial gradients. Requires GlowStack wrapping to function.',
235+
'glow-stack' => 'A coordinated hover effect sharing cursor coordinates across a card stack.',
236+
'input-currency' => 'A smart text input formatting numeric entries into localized currency notation as you type.',
237+
'input-number' => 'A numeric spinner input containing up/down stepper buttons and range constraints.',
238+
'input-phone' => 'A formatted text input enforcing phone masks and raw numeric outputs.',
239+
'input-slug' => 'A reactive field transforming raw keystrokes into clean URL-safe slug strings.',
240+
'multi-select' => 'A dropdown selector allowing search, selection, and creation of multiple tags.',
241+
'progress-circle' => 'A clean SVG circular progress meter displaying animated percentage levels.',
242+
'interactive-rating' => 'A star-based rating component supporting interactive hover feedback and selections.',
243+
'animated-tabs' => 'A tab selection bar showcasing smooth fluid sliding indicator animations.',
244+
'waves-three' => 'A responsive WebGL 3D waves animation powered by Three.js.',
245+
'use-dark-mode' => 'A React hook detecting and toggling light/dark system color schemes.',
246+
'use-headroom' => 'A React scroll hook enabling/disabling visibility of nav headers based on scroll direction.',
247+
'use-hover' => 'A ref-bound React hover hook managing mouse entrance and exit event states.',
248+
'use-pixel-canvas' => 'A helper hook handling pixel drawing mathematics for the Pixel Canvas component.',
249+
'audio-context' => 'A browser Web Audio API manager providing playback nodes for the music player.',
250+
'glow-geometry' => 'A helper library managing mouse coordinate tracking for glow wrappers.',
251+
'pixel-canvas-helper' => 'A mathematical helper module driving pixel animations for the Pixel Canvas.',
252+
'heading' => 'A structured typographic heading component supporting levels 1 to 6.',
253+
'paragraph' => 'A versatile paragraph text component supporting default, lead, and muted layout variants.',
254+
'badge-indicator' => 'A clean and customizable badge indicator component with optional Lucide icon support.',
255+
'heading-block' => 'A composite title heading block containing category badge, main title, and description.',
256+
'input-number-stepper' => 'A numeric entry component with side-by-side plus and minus adjustment buttons.',
257+
'button-special' => 'A collection of unique styled buttons with pulsing, glowing, drawing, or gradient border effects.',
258+
'hero-gradient' => 'A mesh gradient hero banner utilizing HeadingBlock typography and custom neon buttons.',
259+
'hero-split' => 'A split two-column hero section with an interactive PixelCanvas visual panel and CTA options.',
260+
'hero-minimal-centered' => 'A clean centered hero banner with simple typography and special draw and pulse CTA buttons.',
261+
'hero-phone-mockup' => 'A split hero layout showcasing app copy alongside a high-fidelity glowing smartphone dashboard mockup.',
262+
'hero-features-grid' => 'A centered hero banner paired with a three-column micro-grid of cards displaying key app features.',
263+
'hero-video-dialog' => 'A centered hero section featuring a simulated dashboard mockup with an interactive play state.',
264+
'hero-particles' => 'A high-impact centered hero set against an animated backdrop of floating ambient light particles.',
265+
'hero-conic-glow' => 'A dark theme hero section displaying a centerpiece panel framed by a rotating conic border gradient.',
266+
'hero-waitlist' => 'An interactive private beta submission form featuring custom number steppers and subscription feedback.',
267+
'hero-trusted-by' => 'A centered landing page hero banner with an integrated client brand logo cloud for social proof.',
268+
'hero-tabs-showcase' => 'A structured full-stack hero layout with tabbed navigation displaying frontend, backend, and migration code snippets.',
269+
'hero-waves' => 'An immersive black-themed hero banner using a WebGL 3D waves canvas backdrop behind high-end typography.',
270+
'phone-mockup' => 'A high-fidelity CSS-only smartphone mock frame that acts as a container for mobile previews.',
271+
'code-window' => 'An interactive code editor window mockup with custom file tags and active indicators.',
272+
'browser-mockup' => 'A clean browser mockup container frame with close/minimize chrome controls and viewport slot.',
273+
'particles-backdrop' => 'A pure CSS background animation engine rendering drifting ambient particle glows.',
274+
'logo-cloud' => 'A horizontal social proof logo grid displaying client/partner brands.',
275+
'glowing-card' => 'An interactive card container that tracks mouse hover coordinates to trace a glowing radial spotlight.',
276+
'hero-glowing-cards' => 'A centered hero banner utilizing three mouse-tracing GlowingCard components to show features.',
277+
];
278+
184279
$databaseRecords = [];
185280
foreach ($registryItems as $name => $item) {
186281
try {
282+
$item['description'] = $descriptions[$name] ?? 'A beautiful component for your application.';
187283
$parsed = Registry::fromRegistry($item);
188284
$attributes = $parsed->toArray();
189285
unset($attributes['id'], $attributes['created_at'], $attributes['updated_at'], $attributes['deleted_at'], $attributes['user_id']);
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\Actions\Registry\DeleteRegistryAction;
6+
use App\Actions\Registry\StoreRegistryAction;
7+
use App\Actions\Registry\UpdateRegistryAction;
8+
use App\Http\Requests\Registry\StoreRequest;
9+
use App\Http\Requests\Registry\UpdateRequest;
10+
use App\Models\Registry;
11+
use Illuminate\Http\Request;
12+
use Inertia\Inertia;
13+
use Inertia\Response;
14+
15+
class DashboardComponentsController extends Controller
16+
{
17+
/**
18+
* Display a listing of the components.
19+
*/
20+
public function index(Request $request): Response
21+
{
22+
$components = Registry::ofTypes([
23+
'registry:ui',
24+
'registry:block',
25+
'registry:hook',
26+
'registry:lib',
27+
])
28+
->orderBy('title')
29+
->get()
30+
->map(fn (Registry $item) => [
31+
'id' => $item->id,
32+
'name' => $item->name,
33+
'title' => $item->title,
34+
'type' => $item->type,
35+
'description' => $item->description,
36+
'categories' => $item->categories ?? [],
37+
'author' => $item->author,
38+
'dependencies' => $item->dependencies ?? [],
39+
'registryDependencies' => $item->registryDependencies ?? [],
40+
]);
41+
42+
return Inertia::render('dashboard/components/index', [
43+
'components' => $components,
44+
]);
45+
}
46+
47+
/**
48+
* Show the form for creating a new component.
49+
*/
50+
public function create(): Response
51+
{
52+
// Get all unique categories across components for suggestions
53+
$categories = Registry::ofTypes([
54+
'registry:ui',
55+
'registry:block',
56+
'registry:hook',
57+
'registry:lib',
58+
])
59+
->get()
60+
->flatMap(fn ($item) => $item->categories ?? [])
61+
->unique()
62+
->sort()
63+
->values()
64+
->all();
65+
66+
return Inertia::render('dashboard/components/create', [
67+
'categories' => $categories,
68+
]);
69+
}
70+
71+
/**
72+
* Store a newly created component in storage.
73+
*/
74+
public function store(StoreRequest $request, StoreRegistryAction $action)
75+
{
76+
$action->handle($request->validated());
77+
78+
return redirect()
79+
->route('dashboard.components.index')
80+
->with('success', 'Component created successfully.');
81+
}
82+
83+
/**
84+
* Show the form for editing the specified component.
85+
*/
86+
public function edit(string $name): Response
87+
{
88+
$component = Registry::where('name', $name)->firstOrFail();
89+
90+
// Get all unique categories for suggestions
91+
$categories = Registry::ofTypes([
92+
'registry:ui',
93+
'registry:block',
94+
'registry:hook',
95+
'registry:lib',
96+
])
97+
->get()
98+
->flatMap(fn ($item) => $item->categories ?? [])
99+
->unique()
100+
->sort()
101+
->values()
102+
->all();
103+
104+
return Inertia::render('dashboard/components/edit', [
105+
'component' => [
106+
'id' => $component->id,
107+
'name' => $component->name,
108+
'title' => $component->title,
109+
'type' => $component->type,
110+
'description' => $component->description,
111+
'author' => $component->author,
112+
'categories' => $component->categories ?? [],
113+
'dependencies' => $component->dependencies ?? [],
114+
'registryDependencies' => $component->registryDependencies ?? [],
115+
'files' => $component->files ?? [],
116+
'css' => $component->css ?? [],
117+
'css_base' => $component->css_base ?? [],
118+
'vars_theme' => $component->vars_theme ?? [],
119+
'vars_light' => $component->vars_light ?? [],
120+
'vars_dark' => $component->vars_dark ?? [],
121+
],
122+
'categories' => $categories,
123+
]);
124+
}
125+
126+
/**
127+
* Update the specified component in storage.
128+
*/
129+
public function update(UpdateRequest $request, string $name, UpdateRegistryAction $action)
130+
{
131+
$component = Registry::where('name', $name)->firstOrFail();
132+
133+
// Ensure the ID is available for uniqueness validation checks
134+
$request->merge(['id' => $component->id]);
135+
136+
$action->handle($component, $request->validated());
137+
138+
return redirect()
139+
->route('dashboard.components.index')
140+
->with('success', 'Component updated successfully.');
141+
}
142+
143+
/**
144+
* Remove the specified component from storage.
145+
*/
146+
public function destroy(string $name, DeleteRegistryAction $action)
147+
{
148+
$action->handle($name);
149+
150+
return redirect()
151+
->route('dashboard.components.index')
152+
->with('success', 'Component deleted successfully.');
153+
}
154+
}

app/Http/Middleware/HandleInertiaRequests.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public function share(Request $request): array
4646
'plan_name' => $subscription?->type,
4747
'on_grace_period' => $subscription?->onGracePeriod() ?? false,
4848
'ends_at' => $subscription?->ends_at,
49+
'is_admin' => $user->hasAnyRole(['super-admin', 'admin']),
4950
]);
5051
}
5152

0 commit comments

Comments
 (0)