AI Review Center
Commit Review Workspace ?
Select a commit on the left to inspect quality, security, business value, findings, and suggested code changes.
Project AI Score
?
59%
Quality Avg
?
64%
Security Avg
?
45%
Reviews
?
57
Review Result ?
jattin01/avriti-backend · 886d9c91
The commit includes new controllers for managing banners and blogs with full CRUD, validation, and basic slug uniqueness handling, which is solid for a typical CMS backend. The business logic restricting the number of banners and image validation add value. However, security issues are present such as empty DB_PASSWORD in .env, which is a significant risk. The image upload handling lacks further security controls and sanitization. There is also a lack of authorization checks on these controller methods. The code quality is good but could improve with more comments and error handling. The commit message itself is a merge note and not descriptive of changes, lowering confidence.
Quality
?
80%
Security
?
50%
Business Value
?
75%
Maintainability
?
80%
Issues & Suggested Fixes
?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Security Issue
Where
.env:39
Issue / Evidence
security issue
Suggested Fix
do not commit empty or default passwords, enforce strong DB_PASSWORD before commit
Security Issue
Where
app/Http/Controllers/AdminBannerController.php:17
Issue / Evidence
missing authorization checks
Suggested Fix
add authorization to ensure only privileged users can manage banners
Security Issue
Where
app/Http/Controllers/AdminBlogController.php:29
Issue / Evidence
missing authorization checks
Suggested Fix
secure blog management routes with appropriate permissions
Security Issue
Where
app/Http/Controllers/AdminBannerController.php:27
Issue / Evidence
improve security
Suggested Fix
sanitize file uploads and validate image content beyond just file type and size
Security Issue
Where
app/Http/Controllers/AdminBlogController.php:39
Issue / Evidence
improve security
Suggested Fix
similarly sanitize and validate image uploads for blogs
Poor Commit Message
Where
commit message
Issue / Evidence
poor commit message
Suggested Fix
provide meaningful commit message summarizing the changes for better traceability
Missing Validation
Where
app/Http/Controllers/AdminBlogController.php:83
Issue / Evidence
validation could be tightened
Suggested Fix
consider stricter validation rules especially for content and metadata fields
Unclear Tag Parsing
Where
app/Http/Controllers/AdminBlogController.php:113
Issue / Evidence
unclear tag parsing
Suggested Fix
improve parsing logic to handle duplicates and case normalization
Code Change Preview · .env
?
Removed / Before Commit
- LOG_DEPRECATIONS_CHANNEL=null - LOG_LEVEL=debug - - #DB_CONNECTION=mysql - #DB_HOST=127.0.0.1 - #DB_PORT=3306 - #DB_DATABASE=avriti_db - #DB_USERNAME=root - #DB_PASSWORD= - - DB_CONNECTION=mysql - DB_HOST=127.0.0.1 - DB_PORT=3306 - DB_DATABASE=avriti - DB_USERNAME=root - DB_PASSWORD="H3llo#W0rld!2023" - # SESSION_DRIVER=database - # SESSION_LIFETIME=120
Added / After Commit
+ LOG_DEPRECATIONS_CHANNEL=null + LOG_LEVEL=debug + + DB_CONNECTION=mysql + DB_HOST=127.0.0.1 + DB_PORT=3306 + DB_DATABASE=avriti_db + DB_USERNAME=root + DB_PASSWORD= + + # DB_CONNECTION=mysql + # DB_HOST=127.0.0.1 + # DB_PORT=3306 + # DB_DATABASE=avriti + # DB_USERNAME=root + # DB_PASSWORD="H3llo#W0rld!2023" + # SESSION_DRIVER=database + # SESSION_LIFETIME=120
Removed / Before Commit
- .claude - avrithi.xlsx - /.claude - /avrithi.xlsx - \ No newline at end of file
Added / After Commit
+ .claude + avrithi.xlsx + /.claude + \ No newline at end of file + /avrithi.xlsx + /AVRITI_PROJECT_PROMPT.md + /Product Excel Common.xlsx + /Product Excel test only.xlsx + /Avriti_Ratna_Updated.xlsx + /Service Detail test.xlsx
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers; + + use App\Models\Banner; + use Illuminate\Http\Request; + + class AdminBannerController extends Controller + { + public function index() + { + $banners = Banner::orderBy('id')->get(); + return view('admin.banners', compact('banners')); + } + + public function store(Request $request) + { + if (Banner::count() >= 5) {
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers; + + use App\Models\Blog; + use Illuminate\Http\Request; + use Illuminate\Support\Str; + + class AdminBlogController extends Controller + { + public function index() + { + $blogs = Blog::orderByDesc('id')->get(); + return view('admin.blogs', compact('blogs')); + } + + public function create() + {
Removed / Before Commit
- ->with('success', 'Product updated successfully.'); - } - - public function import(Request $request): \Illuminate\Http\JsonResponse - { - $request->validate([ - 'file' => ['required', 'file', 'mimes:xlsx,xls', 'max:10240'], - ], [], ['file' => 'Excel file']); - - $file = $request->file('file'); - $filePath = $file->getPathname(); - - return response()->json(['success' => false, 'message' => 'Excel sheet data not found.'], 422); - } - - // Parse shared strings - $strings = []; - if ($sharedXml) {
Added / After Commit
+ ->with('success', 'Product updated successfully.'); + } + + /** Download the sample Excel template for product import. */ + public function sampleExcel(): \Symfony\Component\HttpFoundation\BinaryFileResponse + { + $path = storage_path('app/samples/product-sample.xlsx'); + abort_unless(file_exists($path), 404); + + return response()->download($path, 'Product Sample.xlsx'); + } + + public function import(Request $request): \Illuminate\Http\JsonResponse + { + $request->validate([ + 'file' => ['required', 'file', 'mimes:xlsx,xls', 'max:10240'], + ], [], ['file' => 'Excel file']); +
Removed / Before Commit
- namespace App\Http\Controllers; - - use App\Models\Service; - use Illuminate\Http\RedirectResponse; - use Illuminate\Http\Request; - use Illuminate\Support\Facades\File; - { - public function index(): View - { - $service = Service::first() ?? new Service(); - $svgFiles = $this->getSvgFiles(); - - return view('admin.service', compact('service', 'svgFiles')); - } - - public function update(Request $request): RedirectResponse
Added / After Commit
+ namespace App\Http\Controllers; + + use App\Models\Service; + use App\Models\ServiceDetail; + use Illuminate\Http\RedirectResponse; + use Illuminate\Http\Request; + use Illuminate\Support\Facades\File; + { + public function index(): View + { + $service = Service::first() ?? new Service(); + $svgFiles = $this->getSvgFiles(); + $serviceDetails = ServiceDetail::orderBy('id')->get(); + + return view('admin.service', compact('service', 'svgFiles', 'serviceDetails')); + } + + public function update(Request $request): RedirectResponse
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers; + + use App\Models\ServiceDetail; + use Illuminate\Http\RedirectResponse; + use Illuminate\Http\Request; + use Illuminate\Support\Facades\File; + use Illuminate\Support\Str; + use Illuminate\View\View; + + class AdminServiceDetailController extends Controller + { + public function create(): View + { + $svgFiles = $this->getSvgFiles(); + return view('admin.service-detail-form', compact('svgFiles')); + }
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers\Api; + + use App\Http\Controllers\Controller; + use App\Models\Banner; + + class BannerController extends Controller + { + public function index() + { + $banners = Banner::where('is_active', true) + ->orderBy('id') + ->get() + ->map(fn($b) => [ + 'id' => $b->id, + 'image' => asset($b->image), + 'url' => $b->url,
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers\Api; + + use App\Http\Controllers\Controller; + use App\Models\Blog; + + class BlogController extends Controller + { + public function index() + { + $blogs = Blog::where('is_active', true) + ->orderByDesc('created_at') + ->get() + ->map(fn ($b) => $this->card($b)) + ->values(); + + return response()->json(['success' => true, 'data' => $blogs]);
Removed / Before Commit
- use App\Models\CartItem; - use App\Models\PaymentSetting; - use App\Models\Product; - use App\Services\CouponService; - use App\Services\ShippingService; - use App\Services\TaxService; - } - - $taxResult = TaxService::calculate($subtotal - $discount); - $shippingResult = ShippingService::calculate($subtotal - $discount, $shippingAddress['pincode'] ?? null); - $shippingCharge = $shippingResult['shipping_charge']; - $totalAmount = round($subtotal - $discount + $shippingCharge + $taxResult['tax_amount'], 2); - - $order = Order::create([ - } - - // create order items from cart or buy_now payload - $items = $request->input('items', []);
Added / After Commit
+ use App\Models\CartItem; + use App\Models\PaymentSetting; + use App\Models\Product; + use App\Models\ServiceDetail; + use App\Services\CouponService; + use App\Services\ShippingService; + use App\Services\TaxService; + } + + $taxResult = TaxService::calculate($subtotal - $discount); + $requestItems = $request->input('items', []); + $allService = count($requestItems) > 0 && collect($requestItems)->every(fn($i) => !empty($i['service_detail_id'])); + $shippingCharge = $allService ? 0 : ShippingService::calculate($subtotal - $discount, $shippingAddress['pincode'] ?? null)['shipping_charge']; + $totalAmount = round($subtotal - $discount + $shippingCharge + $taxResult['tax_amount'], 2); + + $order = Order::create([ + } +
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers\Api; + + use App\Http\Controllers\Controller; + use App\Models\ServiceDetail; + + class ServiceDetailController extends Controller + { + public function index() + { + $details = ServiceDetail::where('is_active', true) + ->orderBy('id') + ->get(['id', 'name', 'slug', 'short_description', 'icon', 'image', 'consultation_fee']); + + $data = $details->map(function ($sd) { + return [ + 'id' => $sd->id,
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Models; + + use Illuminate\Database\Eloquent\Model; + + class Banner extends Model + { + protected $fillable = ['image', 'url', 'is_active']; + + protected function casts(): array + { + return ['is_active' => 'boolean']; + } + }
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Models; + + use Illuminate\Database\Eloquent\Model; + + class Blog extends Model + { + protected $fillable = [ + 'title', + 'slug', + 'excerpt', + 'image', + 'category', + 'tags', + 'author', + 'content', + 'read_time',
Removed / Before Commit
- 'order_id', - 'product_id', - 'combo_product_id', - 'variant_id', - 'product_name', - 'variant_name', - { - return $this->belongsTo(ComboProduct::class); - } - }
Added / After Commit
+ 'order_id', + 'product_id', + 'combo_product_id', + 'service_detail_id', + 'variant_id', + 'product_name', + 'variant_name', + { + return $this->belongsTo(ComboProduct::class); + } + + public function serviceDetail(): BelongsTo + { + return $this->belongsTo(ServiceDetail::class); + } + }
Removed / Before Commit
- 'product_details', - 'closing_tagline', - 'cleansing', - 'charging', - 'wearing', - 'daily_use',
Added / After Commit
+ 'product_details', + 'closing_tagline', + 'cleansing', + 'caring_for_crystal', + 'charging', + 'wearing', + 'daily_use',
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Models; + + use Illuminate\Database\Eloquent\Model; + + class ServiceDetail extends Model + { + protected $fillable = [ + 'name', + 'slug', + 'short_description', + 'consultation_fee', + 'icon', + 'image', + 'other_details', + 'taglines', + 'is_active',
Removed / Before Commit
Added / After Commit
+ <?php + + use Illuminate\Database\Migrations\Migration; + use Illuminate\Database\Schema\Blueprint; + use Illuminate\Support\Facades\Schema; + + return new class extends Migration + { + /** + * Run the migrations. + */ + public function up(): void + { + Schema::create('service_details', function (Blueprint $table) { + $table->id(); + $table->string('name'); + $table->string('slug')->unique(); + $table->text('short_description')->nullable();
Removed / Before Commit
Added / After Commit
+ <?php + + use Illuminate\Database\Migrations\Migration; + use Illuminate\Database\Schema\Blueprint; + use Illuminate\Support\Facades\Schema; + + return new class extends Migration + { + /** + * Run the migrations. + */ + public function up(): void + { + Schema::table('service_details', function (Blueprint $table) { + $table->text('taglines')->nullable()->after('other_details'); + }); + } +
Removed / Before Commit
Added / After Commit
+ <?php + + use Illuminate\Database\Migrations\Migration; + use Illuminate\Database\Schema\Blueprint; + use Illuminate\Support\Facades\Schema; + + return new class extends Migration + { + public function up(): void + { + Schema::table('order_items', function (Blueprint $table) { + $table->unsignedBigInteger('service_detail_id')->nullable()->after('combo_product_id'); + }); + } + + public function down(): void + { + Schema::table('order_items', function (Blueprint $table) {
Removed / Before Commit
Added / After Commit
+ <?php + + use Illuminate\Database\Migrations\Migration; + use Illuminate\Database\Schema\Blueprint; + use Illuminate\Support\Facades\Schema; + + return new class extends Migration + { + /** + * Run the migrations. + */ + public function up(): void + { + Schema::create('banners', function (Blueprint $table) { + $table->id(); + $table->string('image'); + $table->string('url'); + $table->boolean('is_active')->default(true);
Removed / Before Commit
Added / After Commit
+ <?php + + use Illuminate\Database\Migrations\Migration; + use Illuminate\Database\Schema\Blueprint; + use Illuminate\Support\Facades\Schema; + + return new class extends Migration + { + public function up(): void + { + Schema::create('blogs', function (Blueprint $table) { + $table->id(); + $table->string('title'); + $table->string('slug')->unique(); + $table->text('excerpt')->nullable(); + $table->string('image')->nullable(); + $table->string('category')->nullable(); + $table->json('tags')->nullable();
Removed / Before Commit
Added / After Commit
+ <?php + + use Illuminate\Database\Migrations\Migration; + use Illuminate\Database\Schema\Blueprint; + use Illuminate\Support\Facades\Schema; + + return new class extends Migration + { + public function up(): void + { + Schema::table('products', function (Blueprint $table) { + $table->longText('caring_for_crystal')->nullable()->after('cleansing'); + }); + } + + public function down(): void + { + Schema::table('products', function (Blueprint $table) {
Removed / Before Commit
Added / After Commit
+ <?php + + use Illuminate\Database\Migrations\Migration; + use Illuminate\Database\Schema\Blueprint; + use Illuminate\Support\Facades\Schema; + + return new class extends Migration + { + public function up(): void + { + Schema::table('products', function (Blueprint $table) { + $table->text('closing_tagline')->nullable()->change(); + }); + } + + public function down(): void + { + Schema::table('products', function (Blueprint $table) {
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', 'Special Offers | Avriti Dashboard') + + @section('content') + + <div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"> + <div> + <h1 class="text-2xl font-semibold text-[#0b3dba]">Special Offers</h1> + </div> + @if($banners->count() < 5) + <button type="button" data-modal-target="createBannerModal" + class="inline-flex h-11 items-center justify-center gap-2 rounded-md bg-[#0b3dba] px-5 text-sm font-semibold text-white shadow-sm transition hover:bg-blue-600"> + <i class="fa-solid fa-plus"></i> + Add Special Offer + </button> + @endif + </div>
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', isset($blog) ? 'Edit Blog | Avriti Dashboard' : 'Add Blog | Avriti Dashboard') + + @push('styles') + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jodit@4.2.27/es2021/jodit.min.css" /> + <style> + .jodit-container { border-radius: 1rem !important; } + /* hide native datalist dropdown arrow on category input */ + input[list]::-webkit-calendar-picker-indicator { display: none !important; opacity: 0; } + input[list] { appearance: none; } + /* show list bullets / numbers inside the Jodit editor */ + .jodit-wysiwyg ul { list-style: disc !important; padding-left: 24px !important; } + .jodit-wysiwyg ol { list-style: decimal !important; padding-left: 24px !important; } + .jodit-wysiwyg li { display: list-item !important; } + .jodit-wysiwyg h1 { font-size: 30px; font-weight: 700; } + .jodit-wysiwyg h2 { font-size: 26px; font-weight: 700; } + .jodit-wysiwyg h3 { font-size: 22px; font-weight: 600; }
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', 'Blogs | Avriti Dashboard') + + @section('content') + + <div class="mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"> + <div> + <h1 class="text-2xl font-semibold text-[#0b3dba]">Blogs</h1> + </div> + <a href="{{ route('blogs.create') }}" + class="inline-flex h-11 items-center justify-center gap-2 rounded-md bg-[#0b3dba] px-5 text-sm font-semibold text-white shadow-sm transition hover:bg-blue-600"> + <i class="fa-solid fa-plus"></i> + Add Blog + </a> + </div> + + @if(session('success'))
Removed / Before Commit
- - {{-- Create Modal --}} - <div id="createCouponModal" class="{{ $openModal === 'create' ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> - <div class="w-full max-w-2xl overflow-hidden rounded-[32px] bg-white shadow-xl"> - <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> - <h2 class="text-xl font-semibold text-[#0b3dba]">Add Coupon</h2> - <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50"> - {{-- Edit Modals --}} - @foreach ($coupons as $coupon) - <div id="editCouponModal{{ $coupon->id }}" class="{{ $openModal === 'edit-'.$coupon->id ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> - <div class="w-full max-w-2xl overflow-hidden rounded-[32px] bg-white shadow-xl"> - <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> - <h2 class="text-xl font-semibold text-[#0b3dba]">Edit Coupon</h2> - <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50">
Added / After Commit
+ + {{-- Create Modal --}} + <div id="createCouponModal" class="{{ $openModal === 'create' ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> + <div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-[32px] bg-white shadow-xl"> + <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> + <h2 class="text-xl font-semibold text-[#0b3dba]">Add Coupon</h2> + <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50"> + {{-- Edit Modals --}} + @foreach ($coupons as $coupon) + <div id="editCouponModal{{ $coupon->id }}" class="{{ $openModal === 'edit-'.$coupon->id ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> + <div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-[32px] bg-white shadow-xl"> + <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> + <h2 class="text-xl font-semibold text-[#0b3dba]">Edit Coupon</h2> + <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50">
Removed / Before Commit
- $formInstanceId = $product?->id ?? 'new'; - @endphp - - <div class="lg:col-span-3 py-5 "> - <label class=" block text-sm font-semibold text-gray-700 mb-2">Short Description</label> - <div id="editor-short_description-{{ $formInstanceId }}" class="rounded-2xl border border-gray-300 bg-white" style="min-height:90px" data-quill-editor data-max-length="300"></div> - <textarea name="short_description" id="input-short_description-{{ $formInstanceId }}" class="hidden" data-quill-input>{{ old('short_description', $product?->short_description) }}</textarea> - @enderror - </div> - - <div class="lg:col-span-3 py-6 mt-5"> - <label class=" block text-sm font-semibold text-gray-700 mb-2">Description</label> - <div id="editor-description-{{ $formInstanceId }}" class="rounded-2xl border border-gray-300 bg-white" style="min-height:130px" data-quill-editor></div> - <textarea name="description" id="input-description-{{ $formInstanceId }}" class="hidden" data-quill-input>{{ old('description', $product?->description) }}</textarea> - @enderror - </div> - - <div class="lg:col-span-3 rounded-[24px] border border-gray-200 bg-white py-8 mt-8">
Added / After Commit
+ $formInstanceId = $product?->id ?? 'new'; + @endphp + + <div class="lg:col-span-3"> + <label class=" block text-sm font-semibold text-gray-700 mb-2">Short Description</label> + <div id="editor-short_description-{{ $formInstanceId }}" class="rounded-2xl border border-gray-300 bg-white" style="min-height:90px" data-quill-editor data-max-length="300"></div> + <textarea name="short_description" id="input-short_description-{{ $formInstanceId }}" class="hidden" data-quill-input>{{ old('short_description', $product?->short_description) }}</textarea> + @enderror + </div> + + <div class="lg:col-span-3 mt-[90px] mb-[70px]"> + <label class=" block text-sm font-semibold text-gray-700 mb-2">Description</label> + <div id="editor-description-{{ $formInstanceId }}" class="rounded-2xl border border-gray-300 bg-white" style="min-height:130px" data-quill-editor></div> + <textarea name="description" id="input-description-{{ $formInstanceId }}" class="hidden" data-quill-input>{{ old('description', $product?->description) }}</textarea> + @enderror + </div> + + <!-- <div class="lg:col-span-3 rounded-[24px] border border-gray-200 bg-white py-8 mt-8">
Removed / Before Commit
- </div> - - <div id="createCategoryModal" class="{{ $openModal === 'create' ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> - <div class="w-full max-w-2xl overflow-hidden rounded-[32px] bg-white shadow-xl"> - <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> - <h2 class="text-xl font-semibold text-[#0b3dba]">Add Category</h2> - <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50"> - - @foreach ($categories as $category) - <div id="editCategoryModal{{ $category->id }}" class="{{ $openModal === 'edit-'.$category->id ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> - <div class="w-full max-w-2xl overflow-hidden rounded-[32px] bg-white shadow-xl"> - <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> - <h2 class="text-xl font-semibold text-[#0b3dba]">Edit Category</h2> - <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50">
Added / After Commit
+ </div> + + <div id="createCategoryModal" class="{{ $openModal === 'create' ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> + <div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-[32px] bg-white shadow-xl"> + <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> + <h2 class="text-xl font-semibold text-[#0b3dba]">Add Category</h2> + <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50"> + + @foreach ($categories as $category) + <div id="editCategoryModal{{ $category->id }}" class="{{ $openModal === 'edit-'.$category->id ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> + <div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-[32px] bg-white shadow-xl"> + <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> + <h2 class="text-xl font-semibold text-[#0b3dba]">Edit Category</h2> + <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50">
Removed / Before Commit
- </div> - - <div id="createTypeModal" class="{{ $openModal === 'create' ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> - <div class="w-full max-w-2xl overflow-hidden rounded-[32px] bg-white shadow-xl"> - <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> - <h2 class="text-xl font-semibold text-[#0b3dba]">Add Type</h2> - <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50"> - - @foreach ($types as $type) - <div id="editTypeModal{{ $type->id }}" class="{{ $openModal === 'edit-'.$type->id ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> - <div class="w-full max-w-2xl overflow-hidden rounded-[32px] bg-white shadow-xl"> - <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> - <h2 class="text-xl font-semibold text-[#0b3dba]">Edit Type</h2> - <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50">
Added / After Commit
+ </div> + + <div id="createTypeModal" class="{{ $openModal === 'create' ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> + <div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-[32px] bg-white shadow-xl"> + <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> + <h2 class="text-xl font-semibold text-[#0b3dba]">Add Type</h2> + <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50"> + + @foreach ($types as $type) + <div id="editTypeModal{{ $type->id }}" class="{{ $openModal === 'edit-'.$type->id ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> + <div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-[32px] bg-white shadow-xl"> + <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> + <h2 class="text-xl font-semibold text-[#0b3dba]">Edit Type</h2> + <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50">
Removed / Before Commit
- <h1 class="text-2xl font-semibold text-[#0b3dba]">Products</h1> - </div> - <div class="flex items-center gap-3"> - <button type="button" id="importExcelBtn" class="inline-flex h-11 items-center justify-center gap-2 rounded-md border border-[#0b3dba] bg-white px-5 text-sm font-semibold text-[#0b3dba] shadow-sm transition hover:bg-[#eef4ff]"> - <i class="fa-solid fa-file-excel"></i> - Import Excel - </div> - <div class="flex items-center justify-end gap-3 border-t border-gray-100 px-6 py-4"> - <button type="button" id="cancelImportBtn" class="rounded-lg border border-gray-200 px-5 py-2 text-sm font-medium text-gray-600 hover:bg-gray-50 transition">Cancel</button> - <button type="button" id="doImportBtn" class="inline-flex items-center gap-2 rounded-lg bg-[#0b3dba] px-5 py-2 text-sm font-semibold text-white hover:bg-blue-600 transition disabled:opacity-50" disabled> - <i class="fa-solid fa-upload"></i> - Import Now - </button> - - const addSelectedThumbnail = (preview, file) => { - const imageUrl = URL.createObjectURL(file); - const image = document.createElement('img'); - image.src = imageUrl;
Added / After Commit
+ <h1 class="text-2xl font-semibold text-[#0b3dba]">Products</h1> + </div> + <div class="flex items-center gap-3"> + <a href="{{ route('products.sample') }}" + class="group inline-flex h-11 items-center justify-center gap-2 rounded-md border border-emerald-200 bg-emerald-50 px-5 text-sm font-semibold text-emerald-700 shadow-sm transition hover:border-emerald-300 hover:bg-emerald-100"> + <i class="fa-solid fa-file-excel text-emerald-600"></i> + Download Sample Excel + <i class="fa-solid fa-download text-xs opacity-70 transition group-hover:translate-y-0.5"></i> + </a> + <button type="button" id="importExcelBtn" class="inline-flex h-11 items-center justify-center gap-2 rounded-md border border-[#0b3dba] bg-white px-5 text-sm font-semibold text-[#0b3dba] shadow-sm transition hover:bg-[#eef4ff]"> + <i class="fa-solid fa-file-excel"></i> + Import Excel + </div> + <div class="flex items-center justify-end gap-3 border-t border-gray-100 px-6 py-4"> + <button type="button" id="cancelImportBtn" class="rounded-lg border border-gray-200 px-5 py-2 text-sm font-medium text-gray-600 hover:bg-gray-50 transition">Cancel</button> + <button type="button" id="validateImportBtn" class="inline-flex items-center gap-2 rounded-lg border border-[#0b3dba] bg-white px-5 py-2 text-sm font-semibold text-[#0b3dba] hover:bg-[#eef4ff] transition disabled:opacity-50" disabled> + <i class="fa-solid fa-magnifying-glass"></i> + Validate
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', isset($serviceDetail) ? 'Edit Service Detail | Avriti Dashboard' : 'Add Service Detail | Avriti Dashboard') + + @push('styles') + <link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet" /> + <style> + .ql-container { font-size: 14px; } + .ql-editor { min-height: 80px; max-height: 160px; overflow-y: auto; } + .ql-editor::-webkit-scrollbar { width: 4px; } + .ql-editor::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; } + .word-count { font-size: 11px; color: #9ca3af; text-align: right; margin-top: 4px; } + .word-count.warn { color: #ef4444; } + </style> + @endpush + + @section('content') +
Removed / Before Commit
- </div> - </div> - - {{-- Section 2 — Cards --}} - <div class="overflow-hidden rounded-[32px] bg-white shadow-sm mb-6"> - <div class="flex items-center gap-3 border-b border-gray-200 px-6 py-5"> - <span class="inline-flex h-8 w-8 items-center justify-center rounded-xl bg-[#eef4ff] text-[#0b3dba] text-sm font-bold">2</span> - <h2 class="text-base font-semibold text-gray-800">Service Cards</h2> - </div> - <div class="px-6 py-6"> - - <div id="cards-container" class="flex flex-col gap-5"> - @php $existingCards = $service->cards ?? []; @endphp - @forelse ($existingCards as $index => $card) - @php $savedIcon = $card['s_card_icon'] ?? ''; $savedDesc = $card['s_card_description'] ?? ''; @endphp - <div class="card-item border border-gray-200 rounded-2xl p-5 relative"> - <button type="button" onclick="removeCard(this)" - class="absolute top-3 right-3 text-red-400 hover:text-red-600 text-sm font-semibold">
Added / After Commit
+ </div> + </div> + + {{-- Submit --}} + <div class="flex justify-end"> + <button type="submit" + </div> + </form> + + {{-- Section 2 — Service Details Table --}} + <div class="overflow-hidden rounded-[32px] bg-white shadow-sm mt-8"> + <div class="flex flex-col gap-3 border-b border-gray-200 px-6 py-5 sm:flex-row sm:items-center sm:justify-between"> + <div class="flex items-center gap-3"> + <span class="inline-flex h-8 w-8 items-center justify-center rounded-xl bg-[#eef4ff] text-[#0b3dba] text-sm font-bold">2</span> + <div> + <h2 class="text-base font-semibold text-gray-800">Service Details</h2> + <p class="text-sm text-gray-400 mt-0.5">Manage individual service detail pages.</p> + </div>
Removed / Before Commit
- - {{-- Create Modal --}} - <div id="createTaxModal" class="{{ $openModal === 'create' ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> - <div class="w-full max-w-2xl overflow-hidden rounded-[32px] bg-white shadow-xl"> - <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> - <h2 class="text-xl font-semibold text-[#0b3dba]">Add Country Tax</h2> - <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50"> - {{-- Edit Modals --}} - @foreach ($taxSettings as $taxSetting) - <div id="editTaxModal{{ $taxSetting->id }}" class="{{ $openModal === 'edit-'.$taxSetting->id ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> - <div class="w-full max-w-2xl overflow-hidden rounded-[32px] bg-white shadow-xl"> - <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> - <h2 class="text-xl font-semibold text-[#0b3dba]">Edit Country Tax</h2> - <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50">
Added / After Commit
+ + {{-- Create Modal --}} + <div id="createTaxModal" class="{{ $openModal === 'create' ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> + <div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-[32px] bg-white shadow-xl"> + <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> + <h2 class="text-xl font-semibold text-[#0b3dba]">Add Country Tax</h2> + <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50"> + {{-- Edit Modals --}} + @foreach ($taxSettings as $taxSetting) + <div id="editTaxModal{{ $taxSetting->id }}" class="{{ $openModal === 'edit-'.$taxSetting->id ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> + <div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-[32px] bg-white shadow-xl"> + <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> + <h2 class="text-xl font-semibold text-[#0b3dba]">Edit Country Tax</h2> + <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50">
Removed / Before Commit
- </div> - - <div id="createVariantModal" class="{{ $openModal === 'create' ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> - <div class="w-full max-w-2xl overflow-hidden rounded-[32px] bg-white shadow-xl"> - <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> - <h2 class="text-xl font-semibold text-[#0b3dba]">Add Attribute</h2> - <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50"> - - @foreach ($variants as $variant) - <div id="editVariantModal{{ $variant->id }}" class="{{ $openModal === 'edit-'.$variant->id ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> - <div class="w-full max-w-2xl overflow-hidden rounded-[32px] bg-white shadow-xl"> - <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> - <h2 class="text-xl font-semibold text-[#0b3dba]">Edit Attribute</h2> - <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50">
Added / After Commit
+ </div> + + <div id="createVariantModal" class="{{ $openModal === 'create' ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> + <div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-[32px] bg-white shadow-xl"> + <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> + <h2 class="text-xl font-semibold text-[#0b3dba]">Add Attribute</h2> + <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50"> + + @foreach ($variants as $variant) + <div id="editVariantModal{{ $variant->id }}" class="{{ $openModal === 'edit-'.$variant->id ? '' : 'hidden' }} fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4 py-6" data-modal> + <div class="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-[32px] bg-white shadow-xl"> + <div class="flex items-center justify-between border-b border-gray-200 px-6 py-5"> + <h2 class="text-xl font-semibold text-[#0b3dba]">Edit Attribute</h2> + <button type="button" data-modal-close class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-gray-200 text-gray-500 hover:bg-gray-50">
Removed / Before Commit
- - @foreach ($items as $item) - @php - $title = $item['title'] ?? $item['product_name'] ?? 'Product'; - $qty = (int) ($item['quantity'] ?? 1); - $price = (float) ($item['selling_price'] ?? $item['price'] ?? 0); - $lineTotal = $price * $qty;
Added / After Commit
+ + @foreach ($items as $item) + @php + $isService = !empty($item['is_service']); + $title = ($item['title'] ?? $item['product_name'] ?? 'Product') . ($isService ? ' (Service)' : ''); + $qty = (int) ($item['quantity'] ?? 1); + $price = (float) ($item['selling_price'] ?? $item['price'] ?? 0); + $lineTotal = $price * $qty;
Removed / Before Commit
- </div> - - {{-- CMS Group --}} - @php $cmsOpen = request()->routeIs('home-page.*', 'about-page.*', 'faq.*', 'service-page.*'); @endphp - <div> - <button type="button" id="cmsToggle" - class="w-full flex items-center justify-between px-3 py-2.5 rounded-xl text-white/70 hover:bg-white/10 hover:text-white transition"> - <a href="{{ route('home-page.index') }}" class="flex items-center gap-3 px-3 py-2 rounded-xl text-sm {{ request()->routeIs('home-page.*') ? $activeClass : $inactiveClass }}"> - <i class="fa-solid fa-house"></i> - Home Page - </a> - <a href="{{ route('about-page.index') }}" class="flex items-center gap-3 px-3 py-2 rounded-xl text-sm {{ request()->routeIs('about-page.*') ? $activeClass : $inactiveClass }}"> - <i class="fa-solid fa-circle-info"></i> - <i class="fa-solid fa-hand-sparkles"></i> - Services Page - </a> - <a href="{{ route('contacts.index') }}" class="flex items-center gap-3 px-3 py-2.5 rounded-xl {{ request()->routeIs('contacts.*') ? $activeClass : $inactiveClass }}"> - <i class="fa-solid fa-envelope"></i>
Added / After Commit
+ </div> + + {{-- CMS Group --}} + @php $cmsOpen = request()->routeIs('home-page.*', 'about-page.*', 'faq.*', 'service-page.*', 'banners.*', 'blogs.*'); @endphp + <div> + <button type="button" id="cmsToggle" + class="w-full flex items-center justify-between px-3 py-2.5 rounded-xl text-white/70 hover:bg-white/10 hover:text-white transition"> + <a href="{{ route('home-page.index') }}" class="flex items-center gap-3 px-3 py-2 rounded-xl text-sm {{ request()->routeIs('home-page.*') ? $activeClass : $inactiveClass }}"> + <i class="fa-solid fa-house"></i> + Home Page + </a> + <a href="{{ route('banners.index') }}" class="flex items-center gap-3 px-3 py-2 rounded-xl text-sm {{ request()->routeIs('banners.*') ? $activeClass : $inactiveClass }}"> + <i class="fa-solid fa-image"></i> + Special Offers + </a> + <a href="{{ route('blogs.index') }}" class="flex items-center gap-3 px-3 py-2 rounded-xl text-sm {{ request()->routeIs('blogs.*') ? $activeClass : $inactiveClass }}"> + <i class="fa-solid fa-newspaper"></i> + Blogs
Removed / Before Commit
- use App\Http\Controllers\Api\HomeController; - use App\Http\Controllers\Api\FaqController; - use App\Http\Controllers\Api\ServiceController; - use App\Http\Controllers\Api\ContactController; - use App\Http\Controllers\Api\AddressController; - use App\Http\Controllers\Api\OrderController; - Route::get('/faqs', [FaqController::class, 'index']); - Route::get('/home', [HomeController::class, 'index']); - Route::get('/services', [ServiceController::class, 'index']); - Route::get('/combo-products', [ComboProductController::class, 'index']); - Route::get('/combo-products/{slug}', [ComboProductController::class, 'show']); - Route::post('/contact', [ContactController::class, 'store']); - Route::post('/subscribe', [ContactController::class, 'subscribe']); - Route::post('/tax/calculate', [TaxController::class, 'calculate']); - Route::post('/shipping/calculate', [ShippingController::class, 'calculate']); - Route::get('/payment-settings', [PaymentSettingController::class, 'index']); - - Route::prefix('customer')->group(function () {
Added / After Commit
+ use App\Http\Controllers\Api\HomeController; + use App\Http\Controllers\Api\FaqController; + use App\Http\Controllers\Api\ServiceController; + use App\Http\Controllers\Api\ServiceDetailController; + use App\Http\Controllers\Api\BannerController; + use App\Http\Controllers\Api\BlogController; + use App\Http\Controllers\Api\ContactController; + use App\Http\Controllers\Api\AddressController; + use App\Http\Controllers\Api\OrderController; + Route::get('/faqs', [FaqController::class, 'index']); + Route::get('/home', [HomeController::class, 'index']); + Route::get('/services', [ServiceController::class, 'index']); + Route::get('/service-details', [ServiceDetailController::class, 'index']); + Route::get('/service-details/{slug}', [ServiceDetailController::class, 'show']); + Route::get('/combo-products', [ComboProductController::class, 'index']); + Route::get('/combo-products/{slug}', [ComboProductController::class, 'show']); + Route::post('/contact', [ContactController::class, 'store']); + Route::post('/subscribe', [ContactController::class, 'subscribe']);
Removed / Before Commit
- use App\Http\Controllers\AdminContactController; - use App\Http\Controllers\AdminPincodeController; - use App\Http\Controllers\AdminServiceController; - use App\Http\Controllers\AdminCustomerController; - use App\Http\Controllers\AdminDashboardController; - use App\Http\Controllers\AdminOrderController; - use App\Http\Controllers\AdminComboProductController; - use App\Http\Controllers\AdminCouponController; - use App\Http\Controllers\AdminPaymentSettingController; - use Illuminate\Support\Facades\Route; - - Route::get('/', function () { - Route::delete('/product-types/{productType}', [AdminProductTypeController::class, 'destroy'])->name('product-types.destroy'); - Route::get('/products', [AdminProductController::class, 'index'])->name('products.index'); - Route::post('/products', [AdminProductController::class, 'store'])->name('products.store'); - Route::post('/products/import', [AdminProductController::class, 'import'])->name('products.import'); - Route::put('/products/{product}', [AdminProductController::class, 'update'])->name('products.update'); - Route::delete('/products/{product}', [AdminProductController::class, 'destroy'])->name('products.destroy');
Added / After Commit
+ use App\Http\Controllers\AdminContactController; + use App\Http\Controllers\AdminPincodeController; + use App\Http\Controllers\AdminServiceController; + use App\Http\Controllers\AdminServiceDetailController; + use App\Http\Controllers\AdminCustomerController; + use App\Http\Controllers\AdminDashboardController; + use App\Http\Controllers\AdminOrderController; + use App\Http\Controllers\AdminComboProductController; + use App\Http\Controllers\AdminCouponController; + use App\Http\Controllers\AdminPaymentSettingController; + use App\Http\Controllers\AdminBannerController; + use App\Http\Controllers\AdminBlogController; + use Illuminate\Support\Facades\Route; + + Route::get('/', function () { + Route::delete('/product-types/{productType}', [AdminProductTypeController::class, 'destroy'])->name('product-types.destroy'); + Route::get('/products', [AdminProductController::class, 'index'])->name('products.index'); + Route::post('/products', [AdminProductController::class, 'store'])->name('products.store');