diff --git a/app/Http/Controllers/Client/HomeController.php b/app/Http/Controllers/Client/HomeController.php
index 616e195..57947f2 100644
--- a/app/Http/Controllers/Client/HomeController.php
+++ b/app/Http/Controllers/Client/HomeController.php
@@ -4,6 +4,9 @@ namespace App\Http\Controllers\Client;
use App\Http\Controllers\Controller;
use App\Models\Carousel;
+use App\Models\Faq;
+use App\Models\Product;
+use App\Models\Testimonial;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Storage;
@@ -13,6 +16,7 @@ class HomeController extends Controller
public function home()
{
$carousel = Carousel::all();
+ $testimonail = Testimonial::all();
$response = [
@@ -21,6 +25,14 @@ class HomeController extends Controller
"alt" => $item->alt,
"image_url" => $item->image_url ? asset(Storage::url($item->image_url)) : null,
];
+ }),
+ "testimonial" => $testimonail->map(function ($item) {
+ return [
+ "name" => $item->name,
+ "location" => $item->location,
+ "image" => $item->image ? asset(Storage::url($item->image)) : null,
+ "description" => $item->description
+ ];
})
];
return Inertia::render('welcome', ['data' => $response]);
@@ -28,12 +40,39 @@ class HomeController extends Controller
}
public function product()
{
- return Inertia::render('product');
+ $product = Product::all();
+ $productResponse = $product->map(function ($item) {
+ return [
+ "id" => $item->id,
+ "title" => $item->title,
+ "type" => $item->type,
+ "image_url" => $item->image_url ? asset(Storage::url($item->image_url)) : null,
+ ];
+ });
+ return Inertia::render('product', ['product' => $productResponse]);
}
public function art()
{
return Inertia::render('art');
}
+
+ public function bespoke()
+ {
+ $product = Product::where("type", "bespoke")->get();
+ $productResponse = $product->map(function ($item) {
+ return [
+ "id" => $item->id,
+ "title" => $item->title,
+ "type" => $item->type,
+ "image_url" => $item->image_url ? asset(Storage::url($item->image_url)) : null,
+ ];
+ })->values();
+ return Inertia::render("bespoke", ["product" => $productResponse]);
+ }
+ public function gallery()
+ {
+ return Inertia::render("gallery");
+ }
public function contact()
{
return Inertia::render('contact');
diff --git a/app/Http/Controllers/Client/ProductController.php b/app/Http/Controllers/Client/ProductController.php
new file mode 100644
index 0000000..3f55a01
--- /dev/null
+++ b/app/Http/Controllers/Client/ProductController.php
@@ -0,0 +1,63 @@
+map(function ($item) {
+ return [
+ "id" => $item->id,
+ "title" => $item->title,
+ "type" => $item->type,
+ "image_url" => $item->image_url ? asset(Storage::url($item->image_url)) : null,
+ ];
+ });
+
+ return Inertia::render("dashboard/products/index", ['product' => $productResponse]);
+ }
+
+ public function productAdd()
+ {
+ return Inertia::render("dashboard/products/add");
+ }
+ public function productAddPost(Request $request)
+ {
+ $validated = $request->validate([
+ "title" => "required|string",
+ "type" => "required|string",
+ "image_url" => "file"
+ ]);
+
+ if ($request->hasFile('image_url')) {
+ $path = $request->file('image_url')->store('product', 'public');
+
+ $product = Product::create([
+ 'title' => $validated['title'],
+ "type" => $validated['type'],
+ 'image_url' => $path
+ ]);
+
+ $productResponse = [
+ "title" => $product->title,
+ "type" => $product->type,
+ "image_url" => $product->image_url ? asset(Storage::url($product->image_url)) : null,
+ ];
+
+ return to_route('dashboard.product.index', $productResponse);
+ }
+
+ return response()->json([
+ 'status' => 'error',
+ 'message' => 'File upload failed',
+ ], 400);
+ }
+}
diff --git a/app/Http/Controllers/Client/TestimonialController.php b/app/Http/Controllers/Client/TestimonialController.php
index 1382c03..2c30b66 100644
--- a/app/Http/Controllers/Client/TestimonialController.php
+++ b/app/Http/Controllers/Client/TestimonialController.php
@@ -4,20 +4,57 @@ namespace App\Http\Controllers\Client;
use App\Http\Controllers\Controller;
use App\Http\Requests\testimonialRequest;
+use App\Models\testimonial;
use Illuminate\Http\Request;
use Inertia\Inertia;
+use Spatie\LaravelImageOptimizer\Facades\ImageOptimizer;
+use Storage;
class TestimonialController extends Controller
{
public function index()
{
- return Inertia::render('dashboard/testimonial');
+ $testimonial = Testimonial::all();
+ $testimonialResponse = $testimonial->map(function ($item) {
+ return [
+ "name" => $item->name,
+ "description" => $item->description,
+ "location" => $item->location,
+ "image" => $item->image ? asset(Storage::url($item->image)) : null,
+ ];
+ });
+
+ return Inertia::render('dashboard/testimonial', ["testimonial" => $testimonialResponse]);
}
public function store(testimonialRequest $request)
{
$request->validated();
- dd($request);
+ if ($request->hasFile('image')) {
+ $path = $request->file('image')->store('testimonial', 'public');
+ $fullPath = storage_path('app/public/' . $path);
+ ImageOptimizer::optimize($fullPath);
+
+ $testimonial = Testimonial::create([
+ "name" => $request->name,
+ "location" => $request->location,
+ "description" => $request->description,
+ "image" => $path
+ ]);
+
+ $testimonialResponse = [
+ "name" => $testimonial->name,
+ "location" => $testimonial->location,
+ "description" => $testimonial->description,
+ "image" => $testimonial->image ? asset(Storage::url($testimonial->image)) : null
+ ];
+
+ return to_route('home', $testimonialResponse);
+ }
+ return response()->json([
+ 'status' => 'error',
+ 'message' => 'File upload failed',
+ ], 400);
}
}
diff --git a/app/Http/Middleware/HandleInertiaRequests.php b/app/Http/Middleware/HandleInertiaRequests.php
index bd89013..2102f0e 100644
--- a/app/Http/Middleware/HandleInertiaRequests.php
+++ b/app/Http/Middleware/HandleInertiaRequests.php
@@ -4,6 +4,9 @@ namespace App\Http\Middleware;
use Illuminate\Foundation\Inspiring;
use Illuminate\Http\Request;
+use Illuminate\Support\Facades\App;
+use Illuminate\Support\Facades\File;
+use Illuminate\Support\Facades\Session;
use Inertia\Middleware;
class HandleInertiaRequests extends Middleware
@@ -38,6 +41,10 @@ class HandleInertiaRequests extends Middleware
{
[$message, $author] = str(Inspiring::quotes()->random())->explode('-');
+ $locale = Session::get('locale', 'en');
+ App::setLocale($locale);
+
+
return [
...parent::share($request),
'name' => config('app.name'),
@@ -45,7 +52,9 @@ class HandleInertiaRequests extends Middleware
'auth' => [
'user' => $request->user(),
],
- 'sidebarOpen' => ! $request->hasCookie('sidebar_state') || $request->cookie('sidebar_state') === 'true',
+ 'sidebarOpen' => !$request->hasCookie('sidebar_state') || $request->cookie('sidebar_state') === 'true',
+ 'locale' => $locale,
+ 'translations' => trans("message")
];
}
}
diff --git a/app/Http/Requests/testimonialRequest.php b/app/Http/Requests/testimonialRequest.php
index 0f4fb99..0d71d66 100644
--- a/app/Http/Requests/testimonialRequest.php
+++ b/app/Http/Requests/testimonialRequest.php
@@ -23,11 +23,9 @@ class testimonialRequest extends FormRequest
{
return [
'name' => 'required|string',
- 'rating' => 'required|string',
- 'company' => 'string',
- 'post' => 'string',
'location' => 'string',
- 'description' => 'required|string'
+ 'description' => 'required|string',
+ 'image' => 'required|file'
];
}
}
diff --git a/app/Models/Product.php b/app/Models/Product.php
new file mode 100644
index 0000000..3e7ae44
--- /dev/null
+++ b/app/Models/Product.php
@@ -0,0 +1,14 @@
+ function () {
+ $locale = Session::get('locale', config('app.locale'));
+ App::setLocale($locale);
+ return $locale;
+ },
+ 'translations' => function () {
+ $locale = Session::get('locale', config('app.locale'));
+ App::setLocale($locale);
+ return trans('messages');
+ },
+ ]);
+ // App::setLocale(Session::get('locale', config('app.locale')));
}
}
diff --git a/bootstrap/app.php b/bootstrap/app.php
index 134581a..c0af528 100644
--- a/bootstrap/app.php
+++ b/bootstrap/app.php
@@ -6,11 +6,12 @@ use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets;
+use Spatie\LaravelImageOptimizer\Middlewares\OptimizeImages;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
- web: __DIR__.'/../routes/web.php',
- commands: __DIR__.'/../routes/console.php',
+ web: __DIR__ . '/../routes/web.php',
+ commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
@@ -20,6 +21,7 @@ return Application::configure(basePath: dirname(__DIR__))
HandleAppearance::class,
HandleInertiaRequests::class,
AddLinkHeadersForPreloadedAssets::class,
+ OptimizeImages::class,
]);
})
->withExceptions(function (Exceptions $exceptions) {
diff --git a/composer.json b/composer.json
index 33ddaff..3a2363d 100644
--- a/composer.json
+++ b/composer.json
@@ -14,7 +14,9 @@
"laravel/fortify": "^1.30",
"laravel/framework": "^12.0",
"laravel/tinker": "^2.10.1",
- "laravel/wayfinder": "^0.1.9"
+ "laravel/wayfinder": "^0.1.9",
+ "spatie/laravel-image-optimizer": "^1.8",
+ "spatie/laravel-sitemap": "^7.3"
},
"require-dev": {
"fakerphp/faker": "^1.23",
@@ -83,4 +85,4 @@
},
"minimum-stability": "stable",
"prefer-stable": true
-}
\ No newline at end of file
+}
diff --git a/composer.lock b/composer.lock
index 5fc33a8..bb0673f 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "db1a607ff3200db016bc62d7a8dd6399",
+ "content-hash": "380388e121fb1b22c0f87fe4161b2452",
"packages": [
{
"name": "bacon/bacon-qr-code",
@@ -2312,6 +2312,73 @@
],
"time": "2024-12-08T08:18:47+00:00"
},
+ {
+ "name": "masterminds/html5",
+ "version": "2.10.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Masterminds/html5-php.git",
+ "reference": "fcf91eb64359852f00d921887b219479b4f21251"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251",
+ "reference": "fcf91eb64359852f00d921887b219479b4f21251",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Masterminds\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Matt Butcher",
+ "email": "technosophos@gmail.com"
+ },
+ {
+ "name": "Matt Farina",
+ "email": "matt@mattfarina.com"
+ },
+ {
+ "name": "Asmir Mustafic",
+ "email": "goetas@gmail.com"
+ }
+ ],
+ "description": "An HTML5 parser and serializer.",
+ "homepage": "http://masterminds.github.io/html5-php",
+ "keywords": [
+ "HTML5",
+ "dom",
+ "html",
+ "parser",
+ "querypath",
+ "serializer",
+ "xml"
+ ],
+ "support": {
+ "issues": "https://github.com/Masterminds/html5-php/issues",
+ "source": "https://github.com/Masterminds/html5-php/tree/2.10.0"
+ },
+ "time": "2025-07-25T09:04:22+00:00"
+ },
{
"name": "monolog/monolog",
"version": "3.9.0",
@@ -2671,6 +2738,60 @@
},
"time": "2025-08-06T21:43:34+00:00"
},
+ {
+ "name": "nicmart/tree",
+ "version": "0.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nicmart/Tree.git",
+ "reference": "f5e17bf18d78cfb0666ebb9f956c3acd8d14229d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nicmart/Tree/zipball/f5e17bf18d78cfb0666ebb9f956c3acd8d14229d",
+ "reference": "f5e17bf18d78cfb0666ebb9f956c3acd8d14229d",
+ "shasum": ""
+ },
+ "require": {
+ "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
+ },
+ "require-dev": {
+ "ergebnis/composer-normalize": "^2.44.0",
+ "ergebnis/license": "^2.6.0",
+ "ergebnis/php-cs-fixer-config": "^6.28.1",
+ "fakerphp/faker": "^1.24.1",
+ "infection/infection": "~0.26.19",
+ "phpunit/phpunit": "^9.6.19",
+ "psalm/plugin-phpunit": "~0.19.0",
+ "vimeo/psalm": "^5.26.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Tree\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolò Martini",
+ "email": "nicmartnic@gmail.com"
+ },
+ {
+ "name": "Andreas Möller",
+ "email": "am@localheinz.com"
+ }
+ ],
+ "description": "A basic but flexible php tree data structure and a fluent tree builder implementation.",
+ "support": {
+ "issues": "https://github.com/nicmart/Tree/issues",
+ "source": "https://github.com/nicmart/Tree/tree/0.9.0"
+ },
+ "time": "2024-11-22T15:36:01+00:00"
+ },
{
"name": "nikic/php-parser",
"version": "v5.6.1",
@@ -3816,6 +3937,520 @@
},
"time": "2025-09-04T20:59:21+00:00"
},
+ {
+ "name": "spatie/browsershot",
+ "version": "5.0.11",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/browsershot.git",
+ "reference": "f84d9c332899596d0884922772593a10e3925969"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/browsershot/zipball/f84d9c332899596d0884922772593a10e3925969",
+ "reference": "f84d9c332899596d0884922772593a10e3925969",
+ "shasum": ""
+ },
+ "require": {
+ "ext-fileinfo": "*",
+ "ext-json": "*",
+ "php": "^8.2",
+ "spatie/temporary-directory": "^2.0",
+ "symfony/process": "^6.0|^7.0"
+ },
+ "require-dev": {
+ "pestphp/pest": "^3.0",
+ "spatie/image": "^3.6",
+ "spatie/pdf-to-text": "^1.52",
+ "spatie/phpunit-snapshot-assertions": "^4.2.3|^5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\Browsershot\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://github.com/freekmurze",
+ "role": "Developer"
+ }
+ ],
+ "description": "Convert a webpage to an image or pdf using headless Chrome",
+ "homepage": "https://github.com/spatie/browsershot",
+ "keywords": [
+ "chrome",
+ "convert",
+ "headless",
+ "image",
+ "pdf",
+ "puppeteer",
+ "screenshot",
+ "webpage"
+ ],
+ "support": {
+ "source": "https://github.com/spatie/browsershot/tree/5.0.11"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2025-10-08T07:40:52+00:00"
+ },
+ {
+ "name": "spatie/crawler",
+ "version": "8.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/crawler.git",
+ "reference": "4f4c3ead439e7e57085c0b802bc4e5b44fb7d751"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/crawler/zipball/4f4c3ead439e7e57085c0b802bc4e5b44fb7d751",
+ "reference": "4f4c3ead439e7e57085c0b802bc4e5b44fb7d751",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/guzzle": "^7.3",
+ "guzzlehttp/psr7": "^2.0",
+ "illuminate/collections": "^10.0|^11.0|^12.0",
+ "nicmart/tree": "^0.9",
+ "php": "^8.2",
+ "spatie/browsershot": "^5.0.5",
+ "spatie/robots-txt": "^2.0",
+ "symfony/dom-crawler": "^6.0|^7.0"
+ },
+ "require-dev": {
+ "pestphp/pest": "^2.0|^3.0",
+ "spatie/ray": "^1.37"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\Crawler\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be"
+ }
+ ],
+ "description": "Crawl all internal links found on a website",
+ "homepage": "https://github.com/spatie/crawler",
+ "keywords": [
+ "crawler",
+ "link",
+ "spatie",
+ "website"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/crawler/issues",
+ "source": "https://github.com/spatie/crawler/tree/8.4.3"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2025-05-20T09:00:51+00:00"
+ },
+ {
+ "name": "spatie/image-optimizer",
+ "version": "1.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/image-optimizer.git",
+ "reference": "4fd22035e81d98fffced65a8c20d9ec4daa9671c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/image-optimizer/zipball/4fd22035e81d98fffced65a8c20d9ec4daa9671c",
+ "reference": "4fd22035e81d98fffced65a8c20d9ec4daa9671c",
+ "shasum": ""
+ },
+ "require": {
+ "ext-fileinfo": "*",
+ "php": "^7.3|^8.0",
+ "psr/log": "^1.0 | ^2.0 | ^3.0",
+ "symfony/process": "^4.2|^5.0|^6.0|^7.0"
+ },
+ "require-dev": {
+ "pestphp/pest": "^1.21",
+ "phpunit/phpunit": "^8.5.21|^9.4.4",
+ "symfony/var-dumper": "^4.2|^5.0|^6.0|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\ImageOptimizer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Easily optimize images using PHP",
+ "homepage": "https://github.com/spatie/image-optimizer",
+ "keywords": [
+ "image-optimizer",
+ "spatie"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/image-optimizer/issues",
+ "source": "https://github.com/spatie/image-optimizer/tree/1.8.0"
+ },
+ "time": "2024-11-04T08:24:54+00:00"
+ },
+ {
+ "name": "spatie/laravel-image-optimizer",
+ "version": "1.8.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/laravel-image-optimizer.git",
+ "reference": "6681a48097009bba1800f0215190816df22fe116"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/laravel-image-optimizer/zipball/6681a48097009bba1800f0215190816df22fe116",
+ "reference": "6681a48097009bba1800f0215190816df22fe116",
+ "shasum": ""
+ },
+ "require": {
+ "laravel/framework": "^8.0|^9.0|^10.0|^11.0|^12.0",
+ "php": "^8.0",
+ "spatie/image-optimizer": "^1.2.0"
+ },
+ "require-dev": {
+ "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0|^10.0",
+ "phpunit/phpunit": "^9.4|^10.5|^11.5.3"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "aliases": {
+ "ImageOptimizer": "Spatie\\LaravelImageOptimizer\\Facades\\ImageOptimizer"
+ },
+ "providers": [
+ "Spatie\\LaravelImageOptimizer\\ImageOptimizerServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Spatie\\LaravelImageOptimizer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Optimize images in your Laravel app",
+ "homepage": "https://github.com/spatie/laravel-image-optimizer",
+ "keywords": [
+ "laravel-image-optimizer",
+ "spatie"
+ ],
+ "support": {
+ "source": "https://github.com/spatie/laravel-image-optimizer/tree/1.8.2"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ }
+ ],
+ "time": "2025-02-21T14:01:59+00:00"
+ },
+ {
+ "name": "spatie/laravel-package-tools",
+ "version": "1.92.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/laravel-package-tools.git",
+ "reference": "f09a799850b1ed765103a4f0b4355006360c49a5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/f09a799850b1ed765103a4f0b4355006360c49a5",
+ "reference": "f09a799850b1ed765103a4f0b4355006360c49a5",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/contracts": "^9.28|^10.0|^11.0|^12.0",
+ "php": "^8.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.5",
+ "orchestra/testbench": "^7.7|^8.0|^9.0|^10.0",
+ "pestphp/pest": "^1.23|^2.1|^3.1",
+ "phpunit/php-code-coverage": "^9.0|^10.0|^11.0",
+ "phpunit/phpunit": "^9.5.24|^10.5|^11.5",
+ "spatie/pest-plugin-test-time": "^1.1|^2.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\LaravelPackageTools\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Tools for creating Laravel packages",
+ "homepage": "https://github.com/spatie/laravel-package-tools",
+ "keywords": [
+ "laravel-package-tools",
+ "spatie"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/laravel-package-tools/issues",
+ "source": "https://github.com/spatie/laravel-package-tools/tree/1.92.7"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2025-07-17T15:46:43+00:00"
+ },
+ {
+ "name": "spatie/laravel-sitemap",
+ "version": "7.3.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/laravel-sitemap.git",
+ "reference": "077b36c64bc4f373f4d95a1ac6ee1c0624acfdd3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/laravel-sitemap/zipball/077b36c64bc4f373f4d95a1ac6ee1c0624acfdd3",
+ "reference": "077b36c64bc4f373f4d95a1ac6ee1c0624acfdd3",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/guzzle": "^7.8",
+ "illuminate/support": "^11.0|^12.0",
+ "nesbot/carbon": "^2.71|^3.0",
+ "php": "^8.2||^8.3||^8.4",
+ "spatie/crawler": "^8.0.1",
+ "spatie/laravel-package-tools": "^1.16.1",
+ "symfony/dom-crawler": "^6.3.4|^7.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.6.6",
+ "orchestra/testbench": "^9.0|^10.0",
+ "pestphp/pest": "^3.7.4",
+ "spatie/pest-plugin-snapshots": "^2.1",
+ "spatie/phpunit-snapshot-assertions": "^5.1.2",
+ "spatie/temporary-directory": "^2.2"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Spatie\\Sitemap\\SitemapServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Spatie\\Sitemap\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Create and generate sitemaps with ease",
+ "homepage": "https://github.com/spatie/laravel-sitemap",
+ "keywords": [
+ "laravel-sitemap",
+ "spatie"
+ ],
+ "support": {
+ "source": "https://github.com/spatie/laravel-sitemap/tree/7.3.7"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ }
+ ],
+ "time": "2025-08-25T08:07:09+00:00"
+ },
+ {
+ "name": "spatie/robots-txt",
+ "version": "2.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/robots-txt.git",
+ "reference": "1b59dde3fd4e1b71967b40841369c6e9779282f3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/robots-txt/zipball/1b59dde3fd4e1b71967b40841369c6e9779282f3",
+ "reference": "1b59dde3fd4e1b71967b40841369c6e9779282f3",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\Robots\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Brent Roose",
+ "email": "brent@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Determine if a page may be crawled from robots.txt and robots meta tags",
+ "homepage": "https://github.com/spatie/robots-txt",
+ "keywords": [
+ "robots-txt",
+ "spatie"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/robots-txt/issues",
+ "source": "https://github.com/spatie/robots-txt/tree/2.5.2"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2025-09-19T10:37:01+00:00"
+ },
+ {
+ "name": "spatie/temporary-directory",
+ "version": "2.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/temporary-directory.git",
+ "reference": "580eddfe9a0a41a902cac6eeb8f066b42e65a32b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/580eddfe9a0a41a902cac6eeb8f066b42e65a32b",
+ "reference": "580eddfe9a0a41a902cac6eeb8f066b42e65a32b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\TemporaryDirectory\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Alex Vanderbist",
+ "email": "alex@spatie.be",
+ "homepage": "https://spatie.be",
+ "role": "Developer"
+ }
+ ],
+ "description": "Easily create, use and destroy temporary directories",
+ "homepage": "https://github.com/spatie/temporary-directory",
+ "keywords": [
+ "php",
+ "spatie",
+ "temporary-directory"
+ ],
+ "support": {
+ "issues": "https://github.com/spatie/temporary-directory/issues",
+ "source": "https://github.com/spatie/temporary-directory/tree/2.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2025-01-13T13:04:43+00:00"
+ },
{
"name": "symfony/clock",
"version": "v7.3.0",
@@ -4120,6 +4755,77 @@
],
"time": "2024-09-25T14:21:43+00:00"
},
+ {
+ "name": "symfony/dom-crawler",
+ "version": "v7.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/dom-crawler.git",
+ "reference": "efa076ea0eeff504383ff0dcf827ea5ce15690ba"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/efa076ea0eeff504383ff0dcf827ea5ce15690ba",
+ "reference": "efa076ea0eeff504383ff0dcf827ea5ce15690ba",
+ "shasum": ""
+ },
+ "require": {
+ "masterminds/html5": "^2.6",
+ "php": ">=8.2",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "require-dev": {
+ "symfony/css-selector": "^6.4|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\DomCrawler\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Eases DOM navigation for HTML and XML documents",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/dom-crawler/tree/v7.3.3"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2025-08-06T20:13:54+00:00"
+ },
{
"name": "symfony/error-handler",
"version": "v7.3.2",
diff --git a/config/image-optimizer.php b/config/image-optimizer.php
new file mode 100644
index 0000000..9aa435a
--- /dev/null
+++ b/config/image-optimizer.php
@@ -0,0 +1,66 @@
+ [
+
+ Jpegoptim::class => [
+ '-m85', // set maximum quality to 85%
+ '--strip-all', // this strips out all text information such as comments and EXIF data
+ '--all-progressive', // this will make sure the resulting image is a progressive one
+ ],
+
+ Pngquant::class => [
+ '--force', // required parameter for this package
+ ],
+
+ Optipng::class => [
+ '-i0', // this will result in a non-interlaced, progressive scanned image
+ '-o2', // this set the optimization level to two (multiple IDAT compression trials)
+ '-quiet', // required parameter for this package
+ ],
+
+ Svgo::class => [
+ '--disable=cleanupIDs', // disabling because it is know to cause troubles
+ ],
+
+ Gifsicle::class => [
+ '-b', // required parameter for this package
+ '-O3', // this produces the slowest but best results
+ ],
+
+ Cwebp::class => [
+ '-m 6', // for the slowest compression method in order to get the best compression.
+ '-pass 10', // for maximizing the amount of analysis pass.
+ '-mt', // multithreading for some speed improvements.
+ '-q 90', // quality factor that brings the least noticeable changes.
+ ],
+ ],
+
+ /*
+ * The directory where your binaries are stored.
+ * Only use this when you binaries are not accessible in the global environment.
+ */
+ 'binary_path' => '',
+
+ /*
+ * The maximum time in seconds each optimizer is allowed to run separately.
+ */
+ 'timeout' => 60,
+
+ /*
+ * If set to `true` all output of the optimizer binaries will be appended to the default log.
+ * You can also set this to a class that implements `Psr\Log\LoggerInterface`.
+ */
+ 'log_optimizer_activity' => false,
+];
diff --git a/config/sitemap.php b/config/sitemap.php
new file mode 100644
index 0000000..69be0f3
--- /dev/null
+++ b/config/sitemap.php
@@ -0,0 +1,57 @@
+ [
+
+ /*
+ * Whether or not cookies are used in a request.
+ */
+ RequestOptions::COOKIES => true,
+
+ /*
+ * The number of seconds to wait while trying to connect to a server.
+ * Use 0 to wait indefinitely.
+ */
+ RequestOptions::CONNECT_TIMEOUT => 10,
+
+ /*
+ * The timeout of the request in seconds. Use 0 to wait indefinitely.
+ */
+ RequestOptions::TIMEOUT => 10,
+
+ /*
+ * Describes the redirect behavior of a request.
+ */
+ RequestOptions::ALLOW_REDIRECTS => false,
+ ],
+
+ /*
+ * The sitemap generator can execute JavaScript on each page so it will
+ * discover links that are generated by your JS scripts. This feature
+ * is powered by headless Chrome.
+ */
+ 'execute_javascript' => false,
+
+ /*
+ * The package will make an educated guess as to where Google Chrome is installed.
+ * You can also manually pass its location here.
+ */
+ 'chrome_binary_path' => null,
+
+ /*
+ * The sitemap generator uses a CrawlProfile implementation to determine
+ * which urls should be crawled for the sitemap.
+ */
+ 'crawl_profile' => Profile::class,
+
+];
diff --git a/database/migrations/2025_09_23_155833_create_testimonials_table.php b/database/migrations/2025_09_23_155833_create_testimonials_table.php
index 96d4fd8..72452af 100644
--- a/database/migrations/2025_09_23_155833_create_testimonials_table.php
+++ b/database/migrations/2025_09_23_155833_create_testimonials_table.php
@@ -13,10 +13,8 @@ return new class extends Migration {
Schema::create('testimonials', function (Blueprint $table) {
$table->id();
$table->string('name');
- $table->string('company');
- $table->string('post');
$table->string('location');
- $table->double('rating');
+ $table->string("image");
$table->text('description');
$table->timestamps();
});
diff --git a/database/migrations/2025_10_26_120138_create_products_table.php b/database/migrations/2025_10_26_120138_create_products_table.php
new file mode 100644
index 0000000..e3ce377
--- /dev/null
+++ b/database/migrations/2025_10_26_120138_create_products_table.php
@@ -0,0 +1,29 @@
+id();
+ $table->string('image_url');
+ $table->string('title');
+ $table->string('type');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::dropIfExists('products');
+ }
+};
diff --git a/public/favicon.png b/public/favicon.png
new file mode 100644
index 0000000..ef8115e
Binary files /dev/null and b/public/favicon.png differ
diff --git a/resources/assets/img/art/IMG_4715.jpg b/resources/assets/img/art/IMG_4715.jpg
deleted file mode 100644
index 09b1971..0000000
Binary files a/resources/assets/img/art/IMG_4715.jpg and /dev/null differ
diff --git a/resources/assets/img/production/IMG_2719.jpg b/resources/assets/img/production/IMG_2719.jpg
new file mode 100644
index 0000000..de72db4
Binary files /dev/null and b/resources/assets/img/production/IMG_2719.jpg differ
diff --git a/resources/assets/img/products/sci trad 8.jpg b/resources/assets/img/products/sci trad 8.jpg
new file mode 100644
index 0000000..34c7ebc
Binary files /dev/null and b/resources/assets/img/products/sci trad 8.jpg differ
diff --git a/resources/css/app.css b/resources/css/app.css
index 61528f2..138e6b2 100644
--- a/resources/css/app.css
+++ b/resources/css/app.css
@@ -187,3 +187,8 @@
.filepond--credits {
display: none;
}
+
+#testimonial .swiper .swiper-pagination {
+ position: relative;
+ margin-top: 1rem;
+}
diff --git a/resources/js/components/app-logo.tsx b/resources/js/components/app-logo.tsx
index 42d998f..77a57cb 100644
--- a/resources/js/components/app-logo.tsx
+++ b/resources/js/components/app-logo.tsx
@@ -8,7 +8,7 @@ export default function AppLogo() {
- Laravel Starter Kit
+ Soorya Carpet
>
diff --git a/resources/js/components/app-sidebar.tsx b/resources/js/components/app-sidebar.tsx
index f8d5d7f..65a9f87 100644
--- a/resources/js/components/app-sidebar.tsx
+++ b/resources/js/components/app-sidebar.tsx
@@ -1,4 +1,3 @@
-import { NavFooter } from '@/components/nav-footer';
import { NavMain } from '@/components/nav-main';
import { NavUser } from '@/components/nav-user';
import {
@@ -15,7 +14,12 @@ import dashboardcarousel from '@/routes/dashboard/carousel';
import testimonial from '@/routes/testimonial';
import { type NavItem } from '@/types';
import { Link } from '@inertiajs/react';
-import { BookOpen, Folder, GalleryHorizontal, LayoutGrid } from 'lucide-react';
+import {
+ GalleryHorizontal,
+ LayoutGrid,
+ Package,
+ TableOfContents,
+} from 'lucide-react';
import AppLogo from './app-logo';
const mainNavItems: NavItem[] = [
@@ -29,23 +33,20 @@ const mainNavItems: NavItem[] = [
href: dashboardcarousel.index(),
icon: GalleryHorizontal,
},
+ {
+ title: 'Products',
+ href: dashboard.product.index(),
+ icon: Package,
+ },
{
title: 'Testimonial',
href: testimonial.index(),
icon: GalleryHorizontal,
},
-];
-
-const footerNavItems: NavItem[] = [
{
- title: 'Repository',
- href: 'https://github.com/laravel/react-starter-kit',
- icon: Folder,
- },
- {
- title: 'Documentation',
- href: 'https://laravel.com/docs/starter-kits#react',
- icon: BookOpen,
+ title: 'FAQs',
+ href: dashboard.faq.show(),
+ icon: TableOfContents,
},
];
@@ -69,7 +70,6 @@ export function AppSidebar() {
-
diff --git a/resources/js/components/layout/Footer.tsx b/resources/js/components/layout/Footer.tsx
index 4c6479d..f73dedb 100644
--- a/resources/js/components/layout/Footer.tsx
+++ b/resources/js/components/layout/Footer.tsx
@@ -1,28 +1,30 @@
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
-import { about, artOfWeaving, contact, faq, home, product } from '@/routes';
+import { about, artOfWeaving, contact, faq, home } from '@/routes';
+import index from '@/routes/index/index';
+import { useTranslations } from '@/utils/i18n';
+import ns from '@asset/img/about/ns.gif';
+import oko from '@asset/img/about/oko.gif';
import logo from '@asset/img/logo/soorya.png';
import { SiFacebook, SiInstagram } from '@icons-pack/react-simple-icons';
import { Link } from '@inertiajs/react';
import { MoveRight } from 'lucide-react';
export default function Footer() {
+ const { t } = useTranslations();
return (