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 · ecc59c40
The commit introduces a new console command for importing pincodes and a brand new controller for managing combo products, both of which add substantial business value by enabling key features. However, the .env file now contains live credentials and environment configurations committed in plain text which is a major security risk. Moreover, the commit message is vague and uninformative which reduces maintainability and traceability. The .gitignore shows an odd re-inclusion of .env files which can cause accidental exposure of secrets. The new code appears functional but lacks comments and tests visible in the diff, so quality and bug risk could be improved. Suggestions are provided to improve security, maintainability, and code readability.
Quality
?
60%
Security
?
20%
Business Value
?
70%
Maintainability
?
65%
Issues & Suggested Fixes
?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Security Issue
Where
.env:1
Issue / Evidence
security
Suggested Fix
remove all sensitive secrets and environment configurations from the repository and use environment-specific config management
Security Issue
Where
.env:6
Issue / Evidence
security
Suggested Fix
do not commit APP_KEY, RAZORPAY secrets, or DB passwords; use environment variables outside the repo
Security Issue
Where
.env:15
Issue / Evidence
security
Suggested Fix
Do not enable APP_DEBUG=true in the repository for production use, change to false
Security Issue
Where
.gitignore:5
Issue / Evidence
security
Suggested Fix
keep .env files ignored in git to prevent accidental committing of secrets
Quality
Where
commit message
Issue / Evidence
quality
Suggested Fix
use descriptive messages explaining the intent and scope of the merge for better traceability
Quality
Where
app/Console/Commands/ImportPincodes.php:1
Issue / Evidence
quality
Suggested Fix
add PHPDoc comments for class and methods to improve maintainability
Quality
Where
app/Http/Controllers/AdminComboProductController.php:1
Issue / Evidence
quality
Suggested Fix
add comments and input validation for enhanced robustness and maintainability
Quality
Where
app/Http/Controllers/AdminComboProductController.php (future lines)
Issue / Evidence
quality
Suggested Fix
add unit and integration tests for new controller code
Security Issue
Where
.env:31
Issue / Evidence
security
Suggested Fix
avoid committing secrets such as DB_PASSWORD in source code
Code Change Preview · .env
?
Removed / Before Commit
- APP_NAME=Laravel - # APP_ENV=local - APP_ENV=production - APP_KEY=base64:YkLfLJ78zljyLuLqC2wnmybild13CNeNzhXDOGCDc4g= - APP_DEBUG=true - - APP_URL=https://api.digitalmission.in - FRONTEND_URL=https://avriti.digitalmission.in - # FRONTEND_URL=http://localhost:3000 - # APP_URL=http://localhost - - RAZORPAY_KEY_ID=rzp_test_T0r9de6Z2mdqEI - RAZORPAY_KEY_SECRET=2oVeudmd81fe9zRSm4yVS8Hx - LOG_DEPRECATIONS_CHANNEL=null - LOG_LEVEL=debug - - # DB_CONNECTION=mysql - # DB_HOST=127.0.0.1
Added / After Commit
+ APP_NAME=Laravel + + + APP_KEY=base64:YkLfLJ78zljyLuLqC2wnmybild13CNeNzhXDOGCDc4g= + APP_DEBUG=true + + # APP_ENV=production + # APP_URL=https://api.digitalmission.in + # FRONTEND_URL=https://avriti.digitalmission.in + FRONTEND_URL=http://localhost:3000 + APP_URL=http://localhost + APP_ENV=local + + + RAZORPAY_KEY_ID=rzp_test_T0r9de6Z2mdqEI + RAZORPAY_KEY_SECRET=2oVeudmd81fe9zRSm4yVS8Hx + LOG_DEPRECATIONS_CHANNEL=null + LOG_LEVEL=debug
Removed / Before Commit
- *.log - .DS_Store - # .env - # .env.backup - # .env.production - .phpactor.json - .phpunit.result.cache - /.fleet - Homestead.json - Homestead.yaml - Thumbs.db - \ No newline at end of file
Added / After Commit
+ *.log + .DS_Store + .env + .env.backup + .env.production + .phpactor.json + .phpunit.result.cache + /.fleet + Homestead.json + Homestead.yaml + Thumbs.db + + + # Custom Ignore + + # Custom Ignore + .claude + avrithi.xlsx
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Console\Commands; + + use Illuminate\Console\Command; + use Illuminate\Support\Facades\DB; + + class ImportPincodes extends Command + { + protected $signature = 'app:import-pincodes {file=public/state-pincode.csv}'; + + protected $description = 'Import the India Post pincode-to-state CSV into the pincode_states lookup table'; + + public function handle(): int + { + $path = base_path($this->argument('file')); + + if (! file_exists($path)) {
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers; + + use App\Models\ComboProduct; + use App\Models\Product; + use App\Models\Variant; + use Illuminate\Http\RedirectResponse; + use Illuminate\Http\Request; + use Illuminate\Support\Facades\File; + use Illuminate\Support\Str; + use Illuminate\Validation\ValidationException; + use Illuminate\View\View; + + class AdminComboProductController extends Controller + { + public function index(): View + {
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers; + + use App\Models\Coupon; + use Illuminate\Http\RedirectResponse; + use Illuminate\Http\Request; + use Illuminate\Support\Str; + use Illuminate\Validation\Rule; + use Illuminate\Validation\Rules\Unique; + use Illuminate\View\View; + + class AdminCouponController extends Controller + { + public function index(): View + { + $coupons = Coupon::query() + ->latest()
Removed / Before Commit
- { - $validated = $request->validate([ - 'full_name' => ['required', 'string', 'max:150'], - 'phone' => ['required', 'string', 'max:20'], - 'is_active' => ['required', 'boolean'], - ]);
Added / After Commit
+ { + $validated = $request->validate([ + 'full_name' => ['required', 'string', 'max:150'], + 'phone' => ['required', 'digits:10'], + 'is_active' => ['required', 'boolean'], + ]);
Removed / Before Commit
- return view('admin.orders', compact('orders')); - } - - public function show(Order $order): View - { - $order->load(['customer', 'items']); - - return view('admin.order-detail', compact('order')); - } - ]); - - $order->order_status = $request->order_status; - $order->save(); - - if ($request->expectsJson() || $request->ajax()) {
Added / After Commit
+ return view('admin.orders', compact('orders')); + } + + public function transactions(): View + { + $orders = Order::with(['customer', 'items']) + ->latest() + // ->latest('created_at') + ->get(); + + return view('admin.transactions', compact('orders')); + } + + public function show(Order $order): View + { + $order->load(['customer', 'items.comboProduct.items.product.variant']); + + return view('admin.order-detail', compact('order'));
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers; + + use App\Models\PaymentSetting; + use Illuminate\Http\RedirectResponse; + use Illuminate\Http\Request; + use Illuminate\View\View; + + class AdminPaymentSettingController extends Controller + { + public function index(): View + { + return view('admin.payment-settings', [ + 'paymentSetting' => PaymentSetting::current(), + ]); + } +
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers; + + use App\Models\PincodeState; + use Illuminate\Http\JsonResponse; + use Illuminate\Http\Request; + + class AdminPincodeController extends Controller + { + public function search(Request $request): JsonResponse + { + $query = trim((string) $request->query('q', '')); + + if (mb_strlen($query) < 2) { + return response()->json(['data' => []]); + } +
Removed / Before Commit
- use Illuminate\Http\RedirectResponse; - use Illuminate\Http\Request; - use Illuminate\Support\Str; - use Illuminate\Validation\ValidationException; - use Illuminate\View\View; - - - public function update(Request $request, ProductCategory $productCategory): RedirectResponse - { - $validated = $this->validateCategory($request); - $slug = $this->prepareSlug($validated['slug'] ?? '', $validated['name']); - - $this->ensureSlugIsUnique($slug, $productCategory->id); - /** - * @return array{name:string, slug?:string|null, description?:string|null, is_active:bool} - */ - private function validateCategory(Request $request): array - {
Added / After Commit
+ use Illuminate\Http\RedirectResponse; + use Illuminate\Http\Request; + use Illuminate\Support\Str; + use Illuminate\Validation\Rule; + use Illuminate\Validation\ValidationException; + use Illuminate\View\View; + + + public function update(Request $request, ProductCategory $productCategory): RedirectResponse + { + $validated = $this->validateCategory($request, $productCategory->id); + $slug = $this->prepareSlug($validated['slug'] ?? '', $validated['name']); + + $this->ensureSlugIsUnique($slug, $productCategory->id); + /** + * @return array{name:string, slug?:string|null, description?:string|null, is_active:bool} + */ + private function validateCategory(Request $request, ?int $ignoreId = null): array
Removed / Before Commit
- - return view('admin.products', [ - 'products' => $products, - 'categories' => ProductCategory::query()->orderBy('name')->get(), - 'types' => ProductType::query()->orderBy('name')->get(), - 'variants' => Variant::query() - ->orderByDesc('is_active') - ->orderBy('name') - ->get(), - ]); - 'attributes.*.in_stock' => ['nullable', 'boolean'], - 'how_to_use' => ['nullable', 'array'], - 'how_to_use.*' => ['nullable', 'string', 'max:255'], - 'existing_thumbnails' => ['nullable', 'array'], - 'existing_thumbnails.*' => ['nullable', 'string'], - 'thumbnail' => ['nullable', 'array'], - 'best_for' => $this->cleanRows($validated['best_for'] ?? []), - 'how_to_use' => $this->cleanRows($validated['how_to_use'] ?? []),
Added / After Commit
+ + return view('admin.products', [ + 'products' => $products, + 'categories' => ProductCategory::query() + ->where('is_active', true) + ->orderBy('name') + ->get(), + 'types' => ProductType::query() + ->where('is_active', true) + ->orderBy('name') + ->get(), + 'variants' => Variant::query() + ->where('is_active', true) + ->orderBy('name') + ->get(), + ]); + 'attributes.*.in_stock' => ['nullable', 'boolean'], + 'how_to_use' => ['nullable', 'array'],
Removed / Before Commit
- use Illuminate\Http\RedirectResponse; - use Illuminate\Http\Request; - use Illuminate\Support\Str; - use Illuminate\Validation\ValidationException; - use Illuminate\View\View; - - - public function update(Request $request, ProductType $productType): RedirectResponse - { - $validated = $this->validateType($request); - $slug = $this->prepareSlug($validated['slug'] ?? '', $validated['name']); - - $this->ensureSlugIsUnique($slug, $productType->id); - /** - * @return array{name:string, slug?:string|null, is_active:bool} - */ - private function validateType(Request $request): array - {
Added / After Commit
+ use Illuminate\Http\RedirectResponse; + use Illuminate\Http\Request; + use Illuminate\Support\Str; + use Illuminate\Validation\Rule; + use Illuminate\Validation\ValidationException; + use Illuminate\View\View; + + + public function update(Request $request, ProductType $productType): RedirectResponse + { + $validated = $this->validateType($request, $productType->id); + $slug = $this->prepareSlug($validated['slug'] ?? '', $validated['name']); + + $this->ensureSlugIsUnique($slug, $productType->id); + /** + * @return array{name:string, slug?:string|null, is_active:bool} + */ + private function validateType(Request $request, ?int $ignoreId = null): array
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers; + + use App\Models\ShippingZone; + use Illuminate\Http\RedirectResponse; + use Illuminate\Http\Request; + use Illuminate\View\View; + + class AdminShippingSettingController extends Controller + { + public function index(): View + { + $shippingZones = ShippingZone::latest()->get(); + + return view('admin.shipping-settings', [ + 'shippingZones' => $shippingZones, + ]);
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers; + + use App\Models\TaxSetting; + use Illuminate\Http\RedirectResponse; + use Illuminate\Http\Request; + use Illuminate\View\View; + + class AdminTaxSettingController extends Controller + { + public function index(): View + { + $taxSettings = TaxSetting::with('components')->latest()->get(); + + return view('admin.tax-settings', [ + 'taxSettings' => $taxSettings, + ]);
Removed / Before Commit
- public function update(Request $request, User $user): RedirectResponse - { - $validated = $request->validate([ - 'username' => ['required', 'string', 'max:255', Rule::unique('users', 'username')->ignore($user->id)], - 'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users', 'email')->ignore($user->id)], - 'is_active' => ['required', 'boolean'], - 'name' => ['nullable', 'string', 'max:255'], - 'phone_number' => ['nullable', 'string', 'max:255'], - 'destination' => ['nullable', 'string', 'max:255'], - 'location' => ['nullable', 'string', 'max:255'], - 'date_of_birth' => ['nullable', 'date'], - 'total_reviews' => ['required', 'integer', 'min:0'], - 'user_img' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'], - ]);
Added / After Commit
+ public function update(Request $request, User $user): RedirectResponse + { + $validated = $request->validate([ + 'username' => ['required', 'string', 'max:60', Rule::unique('users', 'username')->ignore($user->id)], + 'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users', 'email')->ignore($user->id)], + 'is_active' => ['required', 'boolean'], + 'name' => ['required', 'string', 'max:255'], + 'phone_number' => ['required', 'digits:10'], + 'destination' => ['required', 'string', 'max:70'], + 'location' => ['required', 'string', 'max:100'], + 'date_of_birth' => ['required', 'date'], + 'total_reviews' => ['required', 'integer', 'min:0'], + 'user_img' => ['nullable', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'], + ]);
Removed / Before Commit
- use App\Models\Variant; - use Illuminate\Http\RedirectResponse; - use Illuminate\Http\Request; - use Illuminate\View\View; - - class AdminVariantController extends Controller - - public function update(Request $request, Variant $variant): RedirectResponse - { - $validated = $this->validateVariant($request); - - $variant->update([ - 'name' => $validated['name'], - /** - * @return array{name:string, unit?:string|null, is_active:bool} - */ - private function validateVariant(Request $request): array - {
Added / After Commit
+ use App\Models\Variant; + use Illuminate\Http\RedirectResponse; + use Illuminate\Http\Request; + use Illuminate\Validation\Rule; + use Illuminate\View\View; + + class AdminVariantController extends Controller + + public function update(Request $request, Variant $variant): RedirectResponse + { + $validated = $this->validateVariant($request, $variant->id); + + $variant->update([ + 'name' => $validated['name'], + /** + * @return array{name:string, unit?:string|null, is_active:bool} + */ + private function validateVariant(Request $request, ?int $ignoreId = null): array
Removed / Before Commit
- public function update(Request $request, int $id) - { - $request->validate([ - 'email' => ['nullable', 'email'], - ]); - - $address = Address::where('id', $id)->where('customer_id', $request->user()->id)->firstOrFail(); - - if ($request->boolean('is_default')) { - Address::where('customer_id', $request->user()->id)->update(['is_default' => false]); - } - - $address->update([ - ...$request->only(['full_name','phone','email','address_line1','address_line2','landmark','city','state','pincode','country','address_type']), - 'is_default' => $request->boolean('is_default'), - ]); - - return response()->json(['success' => true, 'data' => $address]);
Added / After Commit
+ public function update(Request $request, int $id) + { + $request->validate([ + 'email' => ['nullable', 'email'], + 'is_default' => ['sometimes', 'boolean'], + ]); + + $customerId = $request->user()->id; + $address = Address::where('id', $id)->where('customer_id', $customerId)->firstOrFail(); + + // Only touch is_default if the client explicitly sent it; otherwise keep the existing value. + $isDefault = $request->has('is_default') ? $request->boolean('is_default') : $address->is_default; + + // Never allow unsetting the only/current default without another address taking its place. + if ($address->is_default && ! $isDefault) { + $hasOtherAddress = Address::where('customer_id', $customerId)->where('id', '!=', $address->id)->exists(); + if (! $hasOtherAddress) { + $isDefault = true;
Removed / Before Commit
- - use App\Http\Controllers\Controller; - use App\Models\CartItem; - use App\Models\Product; - use Illuminate\Http\JsonResponse; - use Illuminate\Http\Request; - { - public function index(Request $request): JsonResponse - { - $items = CartItem::with('product.variant') - ->where('customer_id', $request->user()->id) - ->get() - ->map(fn($item) => $this->formatItem($item)); - public function add(Request $request): JsonResponse - { - $request->validate([ - 'product_id' => ['required', 'integer', 'exists:products,id'], - 'attribute_name' => ['nullable', 'string'],
Added / After Commit
+ + use App\Http\Controllers\Controller; + use App\Models\CartItem; + use App\Models\ComboProduct; + use App\Models\Product; + use Illuminate\Http\JsonResponse; + use Illuminate\Http\Request; + { + public function index(Request $request): JsonResponse + { + $items = CartItem::with('product.variant', 'comboProduct') + ->where('customer_id', $request->user()->id) + ->get() + ->map(fn($item) => $this->formatItem($item)); + public function add(Request $request): JsonResponse + { + $request->validate([ + 'product_id' => ['nullable', 'integer', 'exists:products,id', 'required_without:combo_product_id'],
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers\Api; + + use App\Http\Controllers\Controller; + use App\Models\ComboProduct; + use Illuminate\Http\JsonResponse; + use Illuminate\Http\Request; + + class ComboProductController extends Controller + { + public function index(Request $request): JsonResponse + { + $query = ComboProduct::query() + ->with('items.product.variant') + ->where('is_active', true); + + if ($request->boolean('featured')) {
Removed / Before Commit
- public function store(Request $request) - { - $request->validate([ - 'name' => 'required|string', - 'email' => 'required|email', - 'phone' => 'nullable|string', - 'message' => 'required|string', - ]); - - $contact = Contact::create([ - 'name' => $request->name, - 'email' => $request->email, - 'phone' => $request->phone, - 'message' => $request->message, - ]); - - Mail::to(config('mail.admin_address', env('ADMIN_MAIL')))->send(new ContactAdminMail($contact)); - 'message' => 'Message sent successfully!',
Added / After Commit
+ public function store(Request $request) + { + $request->validate([ + 'name' => 'required|string', + 'email' => 'required|email', + 'phone' => 'nullable|string', + 'service_type' => 'nullable|string', + 'message' => 'required|string', + ]); + + $contact = Contact::create([ + 'name' => $request->name, + 'email' => $request->email, + 'phone' => $request->phone, + 'service_type' => $request->service_type, + 'message' => $request->message, + ]); +
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers\Api; + + use App\Http\Controllers\Controller; + use Illuminate\Http\Request; + use App\Models\Coupon; + use Illuminate\Support\Str; + use Carbon\Carbon; + + class CouponController extends Controller + { + // All Coupons + public function index() + { + return response()->json(Coupon::all()); + } +
Removed / Before Commit
- use App\Http\Controllers\Controller; - use App\Mail\CustomerRegistrationMail; - use App\Mail\CustomerResetPasswordMail; - use App\Mail\CustomerWelcomeMail; - use App\Models\Customer; - use Illuminate\Http\JsonResponse; - $request->validate([ - 'full_name' => ['required', 'string', 'max:150'], - 'email' => ['required', 'email', 'unique:customers,email'], - 'phone' => ['required', 'string', 'max:20'], - 'password' => ['required', 'string', 'min:8'], - ]); - - $customer = Customer::create([ - 'full_name' => $request->full_name, - 'email' => $request->email, - 'phone' => $request->phone, - 'password' => $request->password,
Added / After Commit
+ use App\Http\Controllers\Controller; + use App\Mail\CustomerRegistrationMail; + use App\Mail\CustomerResetPasswordMail; + use App\Mail\CustomerVerifyEmailMail; + use App\Mail\CustomerWelcomeMail; + use App\Models\Customer; + use Illuminate\Http\JsonResponse; + $request->validate([ + 'full_name' => ['required', 'string', 'max:150'], + 'email' => ['required', 'email', 'unique:customers,email'], + 'phone' => ['required', 'digits:10', 'unique:customers,phone'], + 'password' => ['required', 'string', 'min:8'], + ]); + + $verificationToken = Str::random(64); + + $customer = Customer::create([ + 'full_name' => $request->full_name,
Removed / Before Commit
- - use App\Http\Controllers\Controller; - use App\Mail\OrderPlacedMail; - use App\Models\Order; - use App\Models\CartItem; - use App\Models\Product; - use Illuminate\Http\JsonResponse; - use Illuminate\Http\Request; - use Illuminate\Support\Facades\Log; - 'total' => ['required', 'numeric'], - ]); - - $customerId = $request->user()->id; - $shippingAddress = $request->input('shipping_address'); - $billingAddress = $request->input('billing_address', $shippingAddress); - - Log::info('COD order attempt', ['customer_id' => $customerId, 'total' => $request->input('total', 0)]); -
Added / After Commit
+ + use App\Http\Controllers\Controller; + use App\Mail\OrderPlacedMail; + use App\Models\ComboProduct; + use App\Models\Coupon; + use App\Models\Order; + use App\Models\CartItem; + use App\Models\PaymentSetting; + use App\Models\Product; + use App\Services\CouponService; + use App\Services\ShippingService; + use App\Services\TaxService; + use Illuminate\Http\JsonResponse; + use Illuminate\Http\Request; + use Illuminate\Support\Facades\Log; + 'total' => ['required', 'numeric'], + ]); +
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers\Api; + + use App\Http\Controllers\Controller; + use App\Models\PaymentSetting; + use Illuminate\Http\JsonResponse; + + class PaymentSettingController extends Controller + { + public function index(): JsonResponse + { + $setting = PaymentSetting::current(); + + return response()->json([ + 'success' => true, + 'data' => [ + 'cod_enabled' => (bool) $setting->cod_enabled,
Removed / Before Commit
- use App\Http\Controllers\Controller; - use App\Mail\OrderPlacedMail; - use App\Models\CartItem; - use App\Models\Order; - use App\Models\Product; - use Illuminate\Http\JsonResponse; - use Illuminate\Http\Request; - use Illuminate\Support\Facades\Log; - $orderNumber = 'AVR-' . strtoupper(Str::random(8)); - } - - $order = Order::create([ - 'order_number' => $orderNumber, - 'customer_id' => $customerId, - 'shipping_address_id' => $request->input('shipping_address_id'), - 'billing_address_id' => $request->input('billing_address_id'), - 'shipping_address_json' => $shippingAddress, - 'billing_email' => $billingEmail,
Added / After Commit
+ use App\Http\Controllers\Controller; + use App\Mail\OrderPlacedMail; + use App\Models\CartItem; + use App\Models\ComboProduct; + use App\Models\Coupon; + use App\Models\Order; + use App\Models\Product; + use App\Services\CouponService; + use App\Services\ShippingService; + use App\Services\TaxService; + use Illuminate\Http\JsonResponse; + use Illuminate\Http\Request; + use Illuminate\Support\Facades\Log; + $orderNumber = 'AVR-' . strtoupper(Str::random(8)); + } + + $subtotal = (float) $request->input('subtotal', 0); + $couponCode = $request->input('coupon_code');
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers\Api; + + use App\Http\Controllers\Controller; + use App\Services\ShippingService; + use Illuminate\Http\JsonResponse; + use Illuminate\Http\Request; + + class ShippingController extends Controller + { + public function calculate(Request $request): JsonResponse + { + $request->validate([ + 'subtotal' => ['required', 'numeric', 'min:0'], + 'pincode' => ['nullable', 'string', 'digits:6'], + ]); +
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Http\Controllers\Api; + + use App\Http\Controllers\Controller; + use App\Services\TaxService; + use Illuminate\Http\JsonResponse; + use Illuminate\Http\Request; + + class TaxController extends Controller + { + public function calculate(Request $request): JsonResponse + { + $request->validate([ + 'subtotal' => ['required', 'numeric', 'min:0'], + ]); + + $result = TaxService::calculate((float) $request->input('subtotal'));
Removed / Before Commit
- namespace App\Http\Controllers\Api; - - use App\Http\Controllers\Controller; - use App\Models\Product; - use App\Models\Wishlist; - use Illuminate\Http\JsonResponse; - { - public function index(Request $request): JsonResponse - { - $items = Wishlist::with('product.variant', 'product.category') - ->where('customer_id', $request->user()->id) - ->latest() - ->get() - public function store(Request $request): JsonResponse - { - $data = $request->validate([ - 'product_id' => ['required', 'integer', 'exists:products,id'], - 'attribute_name' => ['nullable', 'string'],
Added / After Commit
+ namespace App\Http\Controllers\Api; + + use App\Http\Controllers\Controller; + use App\Models\ComboProduct; + use App\Models\Product; + use App\Models\Wishlist; + use Illuminate\Http\JsonResponse; + { + public function index(Request $request): JsonResponse + { + $items = Wishlist::with('product.variant', 'product.category', 'comboProduct') + ->where('customer_id', $request->user()->id) + ->latest() + ->get() + public function store(Request $request): JsonResponse + { + $data = $request->validate([ + 'product_id' => ['nullable', 'integer', 'exists:products,id', 'required_without:combo_product_id'],
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Mail; + + use Illuminate\Bus\Queueable; + use Illuminate\Mail\Mailable; + use Illuminate\Queue\SerializesModels; + + class CustomerVerifyEmailMail extends Mailable + { + use Queueable, SerializesModels; + + public function __construct( + public string $email, + public string $token, + public ?string $name = null + ) { + }
Removed / Before Commit
- protected $fillable = [ - 'customer_id', - 'product_id', - 'variant_id', - 'attribute_name', - 'attribute_value', - return $this->belongsTo(Product::class); - } - - public function variant(): BelongsTo - { - return $this->belongsTo(Variant::class);
Added / After Commit
+ protected $fillable = [ + 'customer_id', + 'product_id', + 'combo_product_id', + 'variant_id', + 'attribute_name', + 'attribute_value', + return $this->belongsTo(Product::class); + } + + public function comboProduct(): BelongsTo + { + return $this->belongsTo(ComboProduct::class); + } + + public function variant(): BelongsTo + { + return $this->belongsTo(Variant::class);
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Models; + + use Illuminate\Database\Eloquent\Model; + use Illuminate\Database\Eloquent\Relations\HasMany; + + class ComboProduct extends Model + { + protected $fillable = [ + 'title', + 'slug', + 'sku', + 'short_description', + 'thumbnail', + 'combo_price', + 'is_active', + 'featured',
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Models; + + use Illuminate\Database\Eloquent\Model; + use Illuminate\Database\Eloquent\Relations\BelongsTo; + + class ComboProductItem extends Model + { + protected $fillable = [ + 'combo_product_id', + 'product_id', + 'attribute_value', + 'quantity', + ]; + + public function comboProduct(): BelongsTo + {
Removed / Before Commit
- 'name', - 'email', - 'phone', - 'message', - ]; - }
Added / After Commit
+ 'name', + 'email', + 'phone', + 'service_type', + 'message', + ]; + }
Removed / Before Commit
- \ No newline at end of file
Added / After Commit
+ <?php + + namespace App\Models; + + use Illuminate\Database\Eloquent\Model; + + class Coupon extends Model + { + protected $fillable = [ + 'code', + 'title', + 'discount_type', + 'discount_value', + 'max_discount', + 'min_order_amount', + 'usage_limit', + 'used_count', + 'start_date',
Removed / Before Commit
- { - use HasApiTokens; - - protected $fillable = ['full_name', 'email', 'phone', 'profile_img', 'is_active', 'password']; - - protected $hidden = ['password']; - - protected function casts(): array - { - return [ - 'is_active' => 'boolean', - 'password' => 'hashed', - ]; - }
Added / After Commit
+ { + use HasApiTokens; + + protected $fillable = ['full_name', 'email', 'phone', 'profile_img', 'is_active', 'password', 'email_verified_at', 'email_verification_token']; + + protected $hidden = ['password', 'email_verification_token']; + + protected function casts(): array + { + return [ + 'is_active' => 'boolean', + 'password' => 'hashed', + 'email_verified_at' => 'datetime', + ]; + }
Removed / Before Commit
- protected $fillable = [ - 'order_number', - 'customer_id', - 'shipping_address_id', - 'billing_address_id', - 'shipping_address_json', - 'discount', - 'shipping_charge', - 'tax', - 'total_amount', - 'payment_method', - 'payment_status', - protected $casts = [ - 'shipping_address_json' => 'array', - 'billing_address_json' => 'array', - ]; - - public function customer(): BelongsTo
Added / After Commit
+ protected $fillable = [ + 'order_number', + 'customer_id', + 'coupon_id', + 'coupon_code', + 'shipping_address_id', + 'billing_address_id', + 'shipping_address_json', + 'discount', + 'shipping_charge', + 'tax', + 'tax_breakup_json', + 'total_amount', + 'payment_method', + 'payment_status', + protected $casts = [ + 'shipping_address_json' => 'array', + 'billing_address_json' => 'array',
Removed / Before Commit
- protected $fillable = [ - 'order_id', - 'product_id', - 'variant_id', - 'product_name', - 'variant_name', - { - return $this->belongsTo(Product::class); - } - }
Added / After Commit
+ protected $fillable = [ + 'order_id', + 'product_id', + 'combo_product_id', + 'variant_id', + 'product_name', + 'variant_name', + { + return $this->belongsTo(Product::class); + } + + public function comboProduct(): BelongsTo + { + return $this->belongsTo(ComboProduct::class); + } + }
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Models; + + use Illuminate\Database\Eloquent\Model; + + class PaymentSetting extends Model + { + protected $fillable = [ + 'cod_enabled', + ]; + + protected function casts(): array + { + return [ + 'cod_enabled' => 'boolean', + ]; + }
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Models; + + use Illuminate\Database\Eloquent\Model; + + class PincodeState extends Model + { + public $incrementing = false; + + protected $primaryKey = 'pincode'; + + protected $keyType = 'string'; + + public $timestamps = false; + + protected $fillable = ['pincode', 'district', 'state']; + }
Removed / Before Commit
- 'best_for', - 'how_to_use', - 'includes', - 'attributes', - 'thumbnail', - 'featured', - 'best_for' => 'array', - 'how_to_use' => 'array', - 'includes' => 'array', - 'attributes' => 'array', - 'thumbnail' => 'array', - 'featured' => 'boolean',
Added / After Commit
+ 'best_for', + 'how_to_use', + 'includes', + 'fragrance', + 'sold_as', + 'country_of_origin', + 'one_line_meaning', + 'storage_instructions', + 'disclaimer', + 'important_notes', + 'attributes', + 'thumbnail', + 'featured', + 'best_for' => 'array', + 'how_to_use' => 'array', + 'includes' => 'array', + 'fragrance' => 'array', + 'sold_as' => 'array',
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Models; + + use Illuminate\Database\Eloquent\Model; + + class ShippingZone extends Model + { + protected $fillable = [ + 'name', + 'pincodes', + 'flat_rate', + 'free_shipping_threshold', + 'is_default', + 'is_active', + ]; + + protected function casts(): array
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Models; + + use Illuminate\Database\Eloquent\Model; + use Illuminate\Database\Eloquent\Relations\BelongsTo; + + class TaxComponent extends Model + { + protected $fillable = [ + 'tax_setting_id', + 'name', + 'rate_percent', + 'sort_order', + ]; + + public function taxSetting(): BelongsTo + {
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Models; + + use Illuminate\Database\Eloquent\Model; + use Illuminate\Database\Eloquent\Relations\HasMany; + + class TaxSetting extends Model + { + protected $fillable = [ + 'country_code', + 'country_name', + 'is_active', + ]; + + protected function casts(): array + { + return [
Removed / Before Commit
- protected $fillable = [ - 'customer_id', - 'product_id', - 'attribute_name', - 'attribute_value', - ]; - return $this->belongsTo(Product::class); - } - - public function customer(): BelongsTo - { - return $this->belongsTo(Customer::class);
Added / After Commit
+ protected $fillable = [ + 'customer_id', + 'product_id', + 'combo_product_id', + 'attribute_name', + 'attribute_value', + ]; + return $this->belongsTo(Product::class); + } + + public function comboProduct(): BelongsTo + { + return $this->belongsTo(ComboProduct::class); + } + + public function customer(): BelongsTo + { + return $this->belongsTo(Customer::class);
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Services; + + use App\Models\Coupon; + use Carbon\Carbon; + use Illuminate\Support\Str; + + class CouponService + { + /** + * @return array{success: bool, message: string, coupon: ?Coupon, discount: float} + */ + public static function validateAndCalculate(?string $couponCode, float $subtotal): array + { + if (! $couponCode) { + return [ + 'success' => false,
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Services; + + use App\Models\ShippingZone; + + class ShippingService + { + /** + * @return array{shipping_charge: float, is_free: bool, zone_name: string|null} + */ + public static function calculate(float $subtotal, ?string $pincode): array + { + $zones = ShippingZone::where('is_active', true)->get(); + + $zone = $pincode + ? $zones->first(fn (ShippingZone $z) => in_array($pincode, $z->pincodes ?? [], true)) + : null;
Removed / Before Commit
Added / After Commit
+ <?php + + namespace App\Services; + + use App\Models\TaxSetting; + + class TaxService + { + public static function activeSetting(): ?TaxSetting + { + return TaxSetting::with('components')->where('is_active', true)->first(); + } + + /** + * @return array{rate_percent: float, tax_amount: float, breakup: array<int, array{name: string, rate_percent: float, amount: float}>} + */ + public static function calculate(float $subtotal): array + {
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('contacts', function (Blueprint $table) { + $table->string('service_type')->nullable()->after('phone'); + }); + } +
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('tax_settings', function (Blueprint $table) { + $table->id(); + $table->string('country_code', 5); + $table->string('country_name'); + $table->boolean('is_active')->default(false);
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('orders', function (Blueprint $table) { + $table->longText('tax_breakup_json')->nullable()->after('tax'); + }); + } +
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('tax_components', function (Blueprint $table) { + $table->id(); + $table->foreignId('tax_setting_id')->constrained('tax_settings')->cascadeOnDelete(); + $table->string('name'); + $table->decimal('rate_percent', 5, 2);
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('combo_products', function (Blueprint $table) { + $table->id(); + $table->string('title'); + $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::create('combo_product_items', function (Blueprint $table) { + $table->id(); + $table->foreignId('combo_product_id')->constrained('combo_products')->cascadeOnDelete(); + $table->foreignId('product_id')->constrained('products')->cascadeOnDelete(); + $table->string('attribute_value')->nullable();
Removed / Before Commit
Added / After Commit
+ <?php + + use Illuminate\Database\Migrations\Migration; + use Illuminate\Database\Schema\Blueprint; + use Illuminate\Support\Facades\DB; + use Illuminate\Support\Facades\Schema; + + return new class extends Migration + { + /** + * Run the migrations. + */ + public function up(): void + { + DB::statement('ALTER TABLE cart_items MODIFY product_id BIGINT UNSIGNED NULL'); + + Schema::table('cart_items', function (Blueprint $table) { + $table->foreignId('combo_product_id')->nullable()->after('product_id')->constrained('combo_products')->cascadeOnDelete();
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('order_items', function (Blueprint $table) { + $table->foreignId('combo_product_id')->nullable()->after('product_id')->constrained('combo_products')->nullOnDelete(); + }); + } +
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('coupons', function (Blueprint $table) { + $table->id(); + $table->string('code')->unique(); + $table->string('title')->nullable(); + $table->enum('discount_type', ['fixed', 'percentage'])->default('fixed');
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('orders', function (Blueprint $table) { + // + $table->foreignId('coupon_id') + ->nullable() + ->after('customer_id')
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('combo_products', function (Blueprint $table) { + $table->string('sku')->nullable()->after('slug'); + }); + } +
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('payment_settings', function (Blueprint $table) { + $table->id(); + $table->boolean('cod_enabled')->default(true); + $table->timestamps(); + });
Removed / Before Commit
Added / After Commit
+ <?php + + use Illuminate\Database\Migrations\Migration; + use Illuminate\Database\Schema\Blueprint; + use Illuminate\Support\Facades\DB; + use Illuminate\Support\Facades\Schema; + + return new class extends Migration + { + /** + * Run the migrations. + */ + public function up(): void + { + // MySQL needs a dedicated index covering customer_id (the FK column) + // before the composite unique index — which currently serves that + // purpose — can be dropped. + DB::statement('ALTER TABLE wishlists ADD INDEX wishlists_customer_id_temp_index (customer_id)');
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('product_categories', function (Blueprint $table) { + $table->unique('name'); + }); + + Schema::table('product_types', function (Blueprint $table) { + $table->unique('name'); + }); +
Removed / Before Commit
Added / After Commit
+ <?php + + use Illuminate\Database\Migrations\Migration; + use Illuminate\Database\Schema\Blueprint; + use Illuminate\Support\Facades\DB; + use Illuminate\Support\Facades\Schema; + + return new class extends Migration + { + public function up(): void + { + Schema::table('customers', function (Blueprint $table) { + $table->timestamp('email_verified_at')->nullable()->after('phone'); + $table->string('email_verification_token')->nullable()->after('email_verified_at'); + }); + + // Existing customers were never asked to verify — grandfather them in so they aren't locked out. + DB::table('customers')->whereNull('email_verified_at')->update(['email_verified_at' => now()]);
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('shipping_settings', function (Blueprint $table) { + $table->id(); + $table->string('name'); + $table->decimal('flat_rate', 10, 2)->default(0); + $table->decimal('free_shipping_threshold', 10, 2)->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::create('pincode_states', function (Blueprint $table) { + $table->string('pincode', 10)->primary(); + $table->string('district', 100)->nullable(); + $table->string('state', 100); + });
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::dropIfExists('shipping_settings'); + + Schema::create('shipping_zones', function (Blueprint $table) { + $table->id(); + $table->string('name'); + $table->json('pincodes'); + $table->decimal('flat_rate', 10, 2)->default(0); + $table->decimal('free_shipping_threshold', 10, 2)->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('pincode_states', function (Blueprint $table) { + $table->index('district'); + }); + } +
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('products', function (Blueprint $table) { + $table->json('fragrance')->nullable()->after('includes'); + $table->json('sold_as')->nullable()->after('fragrance'); + $table->string('country_of_origin')->nullable()->after('sold_as'); + $table->longText('storage_instructions')->nullable()->after('country_of_origin');
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('products', function (Blueprint $table) { + $table->string('one_line_meaning')->nullable()->after('country_of_origin'); + }); + } +
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', 'Combo Products | Avriti Dashboard') + @section('content') + + @php + $openModal = old('_modal'); + @endphp + + <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]">Combo Products</h1> + </div> + <button type="button" data-modal-target="createComboModal" 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 Combo Product + </button> + </div>
Removed / Before Commit
- </div> - </div> - <div class="overflow-x-auto px-4"> - <table id="contactsTable" data-action-column="4" class="js-data-table min-w-full border-separate border-spacing-0 text-left text-sm text-gray-600"> - <thead class="bg-[#0b3dba] text-xs uppercase tracking-[0.2em] text-white"> - <tr> - <th class="px-6 py-4 w-[5%]">No</th> - <th class="px-6 py-4 w-[15%]">Name</th> - <th class="px-6 py-4 w-[20%]">Email</th> - <th class="px-6 py-4 w-[10%]">Phone</th> - <th class="px-6 py-4 w-[45%]">Message</th> - <!-- <th class="px-6 py-4">Action</th> --> - </tr> - </thead> - <td class="px-6 py-5 font-semibold text-gray-900">{{ $contact->name }}</td> - <td class="px-6 py-5 text-gray-500">{{ $contact->email }}</td> - <td class="px-6 py-5 text-gray-500 ">{{ $contact->phone ?? '—' }}</td> - <td class="px-6 py-5 text-gray-500 max-w-xs break-all">{{ $contact->message }}</td>
Added / After Commit
+ </div> + </div> + <div class="overflow-x-auto px-4"> + <table id="contactsTable" data-action-column="5" class="js-data-table min-w-full border-separate border-spacing-0 text-left text-sm text-gray-600"> + <thead class="bg-[#0b3dba] text-xs uppercase tracking-[0.2em] text-white"> + <tr> + <th class="px-6 py-4 w-[5%]">No</th> + <th class="px-6 py-4 w-[13%]">Name</th> + <th class="px-6 py-4 w-[17%]">Email</th> + <th class="px-6 py-4 w-[10%]">Phone</th> + <th class="px-6 py-4 w-[15%]">Service</th> + <th class="px-6 py-4 w-[40%]">Message</th> + <!-- <th class="px-6 py-4">Action</th> --> + </tr> + </thead> + <td class="px-6 py-5 font-semibold text-gray-900">{{ $contact->name }}</td> + <td class="px-6 py-5 text-gray-500">{{ $contact->email }}</td> + <td class="px-6 py-5 text-gray-500 ">{{ $contact->phone ?? '—' }}</td>
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', 'Coupons | Avriti Dashboard') + @section('content') + + @php + $openModal = old('_modal'); + @endphp + + <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]">Coupons</h1> + </div> + <button type="button" data-modal-target="createCouponModal" 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 Coupon + </button> + </div>
Removed / Before Commit
- <p class="mt-2 text-sm font-semibold text-gray-900">{{ $customer->created_at?->format('d M, Y') ?? '-' }}</p> - </div> - @if ($customer->profile_img) - <img src="{{ asset($customer->profile_img) }}" alt="{{ $displayName }}" class="border-2 border-[#0b3dba] w-[48px] h-[48px] rounded-full object-cover" /> - @else - <div class="border-2 border-[#0b3dba] w-[48px] h-[48px] rounded-full flex items-center justify-center bg-[#eef4ff] text-[#0b3dba] font-semibold text-sm"> - {{ strtoupper(substr($displayName, 0, 1)) }} - type="text" - name="full_name" - value="{{ old('full_name', $customer->full_name) }}" - class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> - @error('full_name') - <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> - <input - type="text" - name="phone" - value="{{ old('phone', $customer->phone) }}" - class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" />
Added / After Commit
+ <p class="mt-2 text-sm font-semibold text-gray-900">{{ $customer->created_at?->format('d M, Y') ?? '-' }}</p> + </div> + @if ($customer->profile_img) + <img src="{{ asset($customer->profile_img) }}" alt="{{ $displayName }}" class="border-2 border-[#0b3dba] w-[48px] h-[48px] rounded-full object-contain" /> + @else + <div class="border-2 border-[#0b3dba] w-[48px] h-[48px] rounded-full flex items-center justify-center bg-[#eef4ff] text-[#0b3dba] font-semibold text-sm"> + {{ strtoupper(substr($displayName, 0, 1)) }} + type="text" + name="full_name" + value="{{ old('full_name', $customer->full_name) }}" + required + class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> + @error('full_name') + <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> + <input + type="text" + name="phone" + id="customerPhoneInput"
Removed / Before Commit
- <div class="bg-[#0b3dba] h-[80px]"></div> - <div class="px-6 pb-6 -mt-10 flex flex-col items-center text-center"> - @if ($customer->profile_img) - <img src="{{ asset($customer->profile_img) }}" alt="{{ $displayName }}" class="w-[80px] h-[80px] rounded-full border-4 border-white object-cover shadow" /> - @else - <div class="w-[80px] h-[80px] rounded-full border-4 border-white bg-[#eef4ff] flex items-center justify-center text-[#0b3dba] text-2xl font-bold shadow"> - {{ strtoupper(substr($displayName, 0, 1)) }} - </div> - - {{-- Default Address --}} - @if ($defaultAddress) - <div class="rounded-[24px] bg-white shadow-sm p-6"> - <h3 class="text-sm font-semibold text-[#0b3dba] mb-4 flex items-center gap-2"> - <i class="fa-solid fa-location-dot"></i> Default Address - @endif - </div> - </div> - @endif
Added / After Commit
+ <div class="bg-[#0b3dba] h-[80px]"></div> + <div class="px-6 pb-6 -mt-10 flex flex-col items-center text-center"> + @if ($customer->profile_img) + <img src="{{ asset($customer->profile_img) }}" alt="{{ $displayName }}" class="w-[80px] h-[80px] rounded-full border-4 border-white object-contain shadow" /> + @else + <div class="w-[80px] h-[80px] rounded-full border-4 border-white bg-[#eef4ff] flex items-center justify-center text-[#0b3dba] text-2xl font-bold shadow"> + {{ strtoupper(substr($displayName, 0, 1)) }} + </div> + + {{-- Default Address --}} + <!-- @if ($defaultAddress) + <div class="rounded-[24px] bg-white shadow-sm p-6"> + <h3 class="text-sm font-semibold text-[#0b3dba] mb-4 flex items-center gap-2"> + <i class="fa-solid fa-location-dot"></i> Default Address + @endif + </div> + </div> + @endif -->
Removed / Before Commit
- <td class="px-6 py-5"> - <div class="flex items-center gap-3"> - @if ($customer->profile_img) - <img src="{{ asset($customer->profile_img) }}" alt="{{ $displayName }}" class="border-2 border-[#0b3dba] w-[40px] h-[40px] rounded-full object-cover" /> - @else - <div class="border-2 border-[#0b3dba] w-[40px] h-[40px] rounded-full flex items-center justify-center bg-[#eef4ff] text-[#0b3dba] font-semibold text-sm"> - {{ strtoupper(substr($displayName, 0, 1)) }}
Added / After Commit
+ <td class="px-6 py-5"> + <div class="flex items-center gap-3"> + @if ($customer->profile_img) + <img src="{{ asset($customer->profile_img) }}" alt="{{ $displayName }}" class="border-2 border-[#0b3dba] w-[40px] h-[40px] rounded-full object-contain" /> + @else + <div class="border-2 border-[#0b3dba] w-[40px] h-[40px] rounded-full flex items-center justify-center bg-[#eef4ff] text-[#0b3dba] font-semibold text-sm"> + {{ strtoupper(substr($displayName, 0, 1)) }}
Removed / Before Commit
- @endif - - {{-- Items --}} - <div class="rounded-2xl border border-gray-200 overflow-hidden"> - <h3 class="px-4 py-3 text-sm font-semibold text-[#0b3dba] border-b border-gray-200">Items</h3> - <div class="overflow-x-auto"> - <table class="min-w-full text-left text-sm text-gray-600"> - <thead class="bg-gray-50 text-xs uppercase tracking-[0.1em] text-gray-500"> - <tr> - <th class="px-4 py-3">Product</th> - <th class="px-4 py-3">Variant</th> - <th class="px-4 py-3">SKU</th> - <th class="px-4 py-3">Price</th> - <th class="px-4 py-3">Qty</th> - <tbody class="divide-y divide-gray-100"> - @foreach ($order->items as $item) - <tr> - <td class="px-4 py-3">{{ $item->product_name }}</td>
Added / After Commit
+ @endif + + {{-- Items --}} + @php + $hasOnlyComboItems = $order->items->isNotEmpty() && $order->items->every(fn ($i) => $i->combo_product_id); + $itemsColumnCount = $hasOnlyComboItems ? 5 : 6; + @endphp + <div class="rounded-2xl border border-gray-200 overflow-hidden"> + <h3 class="px-4 py-3 text-sm font-semibold text-[#0b3dba] border-b border-gray-200">Items</h3> + <div class="overflow-x-auto"> + <table class="min-w-full text-left text-sm text-gray-600"> + <thead class="bg-gray-50 text-xs uppercase tracking-[0.1em] text-gray-500"> + <tr> + <th class="px-4 py-3">Product</th> + @unless ($hasOnlyComboItems) + <th class="px-4 py-3">Variant</th> + @endunless + <th class="px-4 py-3">SKU</th>
Removed / Before Commit
Added / After Commit
+ @php + $itemsList = old('items', $comboProduct?->items->map(fn ($i) => ['product_id' => $i->product_id, 'attribute_value' => $i->attribute_value, 'quantity' => $i->quantity])->toArray() ?? [['product_id' => '', 'attribute_value' => '', 'quantity' => 1]]); + $containerId = 'combo-items-' . ($comboProduct?->id ?? 'new'); + $thumbnails = is_array($comboProduct?->thumbnail) ? array_values(array_filter($comboProduct->thumbnail)) : []; + $productOptionsHtml = $products->map(fn ($p) => '<option value="' . $p->id . '">' . e($p->title) . '</option>')->join(''); + $productAttributesJson = json_encode($productAttributesMap ?? []); + @endphp + + <div class="max-h-[70vh] space-y-5 overflow-y-auto px-6 py-6"> + <div class="grid gap-4 sm:grid-cols-2"> + <div> + <label class="mb-1.5 block text-sm font-medium text-gray-700">Combo Title</label> + <input type="text" name="title" value="{{ old('title', $comboProduct?->title) }}" placeholder="e.g. Rudraksha + Chain Combo" required class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" /> + @error('title') + <p class="mt-1 text-xs text-red-500">{{ $message }}</p> + @enderror + </div> + <div>
Removed / Before Commit
Added / After Commit
+ @php + $discountType = old('discount_type', $coupon?->discount_type ?? 'percentage'); + @endphp + + <div class="space-y-5 px-6 py-6"> + <div class="grid gap-4 sm:grid-cols-2"> + <div> + <label class="mb-1.5 block text-sm font-medium text-gray-700">Coupon Code</label> + <input type="text" name="code" value="{{ old('code', $coupon?->code) }}" placeholder="e.g. WELCOME10" required class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm uppercase focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" /> + @error('code') + <p class="mt-1 text-xs text-red-500">{{ $message }}</p> + @enderror + </div> + <div> + <label class="mb-1.5 block text-sm font-medium text-gray-700">Title (optional)</label> + <input type="text" name="title" value="{{ old('title', $coupon?->title) }}" placeholder="e.g. Welcome Offer" class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" /> + </div> + </div>
Removed / Before Commit
Added / After Commit
+ <script> + (() => { + let searchTimer = null; + + document.addEventListener('input', (event) => { + const input = event.target.closest('[data-pincode-search]'); + if (! input) return; + + const wrapper = input.closest('[data-pincode-picker]'); + const resultsBox = wrapper.querySelector('[data-pincode-results]'); + const query = input.value.trim(); + + clearTimeout(searchTimer); + + if (query.length < 2) { + resultsBox.innerHTML = ''; + resultsBox.classList.add('hidden'); + return;
Removed / Before Commit
- value="{{ old('name', $category?->name) }}" - class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> - @error('name') - <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> - @enderror - </div> - - value="{{ old('slug', $category?->slug) }}" - class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> - @error('slug') - <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> - @enderror - </div> - - rows="4" - class="w-full px-4 py-3 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent">{{ old('description', $category?->description) }}</textarea> - @error('description') - <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p>
Added / After Commit
+ value="{{ old('name', $category?->name) }}" + class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> + @error('name') + <p data-error-message class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> + @enderror + </div> + + value="{{ old('slug', $category?->slug) }}" + class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> + @error('slug') + <p data-error-message class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> + @enderror + </div> + + rows="4" + class="w-full px-4 py-3 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent">{{ old('description', $category?->description) }}</textarea> + @error('description') + <p data-error-message class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p>
Removed / Before Commit
- $bestForRows = old('best_for', $product?->best_for ?? []); - $includeRows = old('includes', $product?->includes ?? []); - $howToUseRows = old('how_to_use', $product?->how_to_use ?? []); - $attributeRows = old('attributes', $product?->attributes ?? []); - - if (! is_array($bestForRows)) { - $howToUseRows = []; - } - - if (! is_array($attributeRows)) { - $attributeRows = []; - } - $howToUseRows = ['']; - } - - if ($attributeRows === []) { - $attributeRows = [['name' => '', 'value' => '', 'mrp' => '', 'selling_price' => '', 'stock_qty' => '', 'critical_qty' => '', 'sku' => '', 'in_stock' => true]]; - }
Added / After Commit
+ $bestForRows = old('best_for', $product?->best_for ?? []); + $includeRows = old('includes', $product?->includes ?? []); + $howToUseRows = old('how_to_use', $product?->how_to_use ?? []); + $fragranceRows = old('fragrance', $product?->fragrance ?? []); + $soldAsRows = old('sold_as', $product?->sold_as ?? []); + $attributeRows = old('attributes', $product?->attributes ?? []); + + if (! is_array($bestForRows)) { + $howToUseRows = []; + } + + if (! is_array($fragranceRows)) { + $fragranceRows = []; + } + + if (! is_array($soldAsRows)) { + $soldAsRows = []; + }
Removed / Before Commit
- value="{{ old('name', $type?->name) }}" - class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> - @error('name') - <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> - @enderror - </div> - - value="{{ old('slug', $type?->slug) }}" - class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> - @error('slug') - <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> - @enderror - </div> - - </label> - </div> - @error('is_active') - <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p>
Added / After Commit
+ value="{{ old('name', $type?->name) }}" + class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> + @error('name') + <p data-error-message class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> + @enderror + </div> + + value="{{ old('slug', $type?->slug) }}" + class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> + @error('slug') + <p data-error-message class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> + @enderror + </div> + + </label> + </div> + @error('is_active') + <p data-error-message class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p>
Removed / Before Commit
- <p class="mt-2 text-sm text-slate-500">{{ $subtitle }}</p> - </div> - - <div class="rounded-[28px] border border-slate-200 bg-slate-50 p-6"> - <div class="space-y-4"> - <div class="flex items-center justify-between gap-4 text-sm text-slate-600"> - <span>Username</span> - <span class="font-semibold text-slate-900">{{ $username }}</span> - </div> - </div> - - <div class="rounded-[28px] border border-slate-200 bg-slate-50 p-6"> - <div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"> - <div class="text-sm font-semibold text-slate-700">Social Media:</div> - <div class="flex flex-wrap items-center gap-3"> - <a href="#" class="inline-flex h-11 w-11 items-center justify-center rounded-2xl border border-slate-200 bg-white text-slate-700 shadow-sm hover:bg-slate-100"><i class="fab fa-whatsapp"></i></a> - </div> - </div>
Added / After Commit
+ <p class="mt-2 text-sm text-slate-500">{{ $subtitle }}</p> + </div> + + <div class="rounded-[28px] border border-slate-200 bg-slate-50 p-6 ]"> + <div class="space-y-8"> + <div class="flex items-center justify-between gap-4 text-sm text-slate-600"> + <span>Username</span> + <span class="font-semibold text-slate-900">{{ $username }}</span> + </div> + </div> + + <!-- <div class="rounded-[28px] border border-slate-200 bg-slate-50 p-6"> + <div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"> + <div class="text-sm font-semibold text-slate-700">Social Media:</div> + <div class="flex flex-wrap items-center gap-3"> + <a href="#" class="inline-flex h-11 w-11 items-center justify-center rounded-2xl border border-slate-200 bg-white text-slate-700 shadow-sm hover:bg-slate-100"><i class="fab fa-whatsapp"></i></a> + </div> + </div>
Removed / Before Commit
Added / After Commit
+ @php + $existingPincodes = old('pincodes', $shippingZone?->pincodes ?? []); + @endphp + + <div class="space-y-5 px-6 py-6"> + <div> + <label class="mb-1.5 block text-sm font-medium text-gray-700">Zone Name</label> + <input type="text" name="name" value="{{ old('name', $shippingZone?->name) }}" placeholder="e.g. Lucknow Local" required class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" /> + @error('name') + <p data-error-message class="mt-1 text-xs text-red-500">{{ $message }}</p> + @enderror + </div> + + <div data-pincode-picker class="relative"> + <label class="mb-1.5 block text-sm font-medium text-gray-700">Pincodes</label> + <input type="text" data-pincode-search placeholder="Type a pincode or city name..." autocomplete="off" class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" /> + <div data-pincode-results class="hidden absolute z-10 mt-1 w-full max-h-56 overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg"></div> +
Removed / Before Commit
Added / After Commit
+ @php + $componentsList = old('components', $taxSetting?->components->map(fn ($c) => ['name' => $c->name, 'rate_percent' => $c->rate_percent])->toArray() ?? [['name' => '', 'rate_percent' => '']]); + $containerId = 'components-' . ($taxSetting?->id ?? 'new'); + @endphp + + <div class="space-y-5 px-6 py-6"> + <div class="grid gap-4 sm:grid-cols-2"> + <div> + <label class="mb-1.5 block text-sm font-medium text-gray-700">Country Name</label> + <input type="text" name="country_name" value="{{ old('country_name', $taxSetting?->country_name) }}" placeholder="e.g. India" required class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" /> + @error('country_name') + <p class="mt-1 text-xs text-red-500">{{ $message }}</p> + @enderror + </div> + <div> + <label class="mb-1.5 block text-sm font-medium text-gray-700">Country Code</label> + <input type="text" name="country_code" value="{{ old('country_code', $taxSetting?->country_code) }}" placeholder="e.g. IN" maxlength="5" required class="h-11 w-full rounded-md border border-gray-300 px-4 text-sm uppercase focus:border-[#0b3dba] focus:outline-none focus:ring-2 focus:ring-blue-100" /> + @error('country_code')
Removed / Before Commit
- value="{{ old('name', $variant?->name) }}" - class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> - @error('name') - <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> - @enderror - </div> - - </label> - </div> - @error('is_active') - <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> - @enderror - </div> - </div>
Added / After Commit
+ value="{{ old('name', $variant?->name) }}" + class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> + @error('name') + <p data-error-message class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> + @enderror + </div> + + </label> + </div> + @error('is_active') + <p data-error-message class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> + @enderror + </div> + </div>
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', 'Payment Methods | 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]">Payment Methods</h1> + </div> + </div> + + @if (session('success')) + <div data-auto-hide-alert class="mb-6 rounded-2xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm font-semibold text-emerald-700 transition-opacity duration-500"> + {{ session('success') }} + </div> + @endif + + <div class="overflow-hidden rounded-[32px] bg-white shadow-sm">
Removed / Before Commit
- const closeModal = (modal) => { - modal?.classList.add('hidden'); - document.body.classList.remove('overflow-hidden'); - }; - - document.addEventListener('click', (event) => {
Added / After Commit
+ const closeModal = (modal) => { + modal?.classList.add('hidden'); + document.body.classList.remove('overflow-hidden'); + modal?.querySelector('form')?.reset(); + modal?.querySelectorAll('[data-error-message]').forEach((el) => el.remove()); + }; + + document.addEventListener('click', (event) => {
Removed / Before Commit
- const closeModal = (modal) => { - modal?.classList.add('hidden'); - document.body.classList.remove('overflow-hidden'); - }; - - document.addEventListener('click', (event) => {
Added / After Commit
+ const closeModal = (modal) => { + modal?.classList.add('hidden'); + document.body.classList.remove('overflow-hidden'); + modal?.querySelector('form')?.reset(); + modal?.querySelectorAll('[data-error-message]').forEach((el) => el.remove()); + }; + + document.addEventListener('click', (event) => {
Removed / Before Commit
- const closeModal = (modal) => { - modal?.classList.add('hidden'); - document.body.classList.remove('overflow-hidden'); - }; - - const refreshRepeaterNumbers = (repeater) => { - }, 3500); - }); - - const toolbarOptions = [ - [{ 'header': [1, 2, 3, false] }], - ['bold', 'italic', 'underline'], - quill.root.innerHTML = textarea.value; - } - - quill.on('text-change', function () { - const html = quill.root.innerHTML; - textarea.value = html === '<p><br></p>' ? '' : html;
Added / After Commit
+ const closeModal = (modal) => { + modal?.classList.add('hidden'); + document.body.classList.remove('overflow-hidden'); + modal?.querySelectorAll('[data-error-message], .js-validation-error').forEach((el) => el.remove()); + }; + + const refreshRepeaterNumbers = (repeater) => { + }, 3500); + }); + + const MAX_THUMBNAIL_BYTES = 1 * 1024 * 1024; + + const showFieldError = (anchorEl, message) => { + if (! anchorEl) return; + const insertAfter = anchorEl.nextElementSibling?.classList?.contains('select2-container') + ? anchorEl.nextElementSibling + : anchorEl; + let msg = insertAfter.parentElement?.querySelector('.js-validation-error');
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', 'Shipping Settings | 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]">Shipping Settings</h1> + </div> + <a href="{{ route('shipping-settings.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 Shipping Zone + </a> + </div> + + @if (session('success')) + <div data-auto-hide-alert class="mb-6 rounded-2xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm font-semibold text-emerald-700 transition-opacity duration-500"> + {{ session('success') }}
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', 'Add Shipping Zone | 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]">Add Shipping Zone</h1> + <p class="mt-2 text-sm text-gray-500">Create a new pincode-based shipping rate.</p> + </div> + <a href="{{ route('shipping-settings.index') }}" class="inline-flex h-11 items-center justify-center rounded-full border border-gray-200 bg-white px-5 text-sm font-semibold text-gray-600 shadow-sm transition hover:bg-gray-50"> + Back + </a> + </div> + + <form method="POST" action="{{ route('shipping-settings.store') }}" class="overflow-hidden rounded-[32px] bg-white shadow-sm"> + @csrf + @include('admin.partials.shipping-zone-form', ['shippingZone' => null, 'submitLabel' => 'Save'])
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', 'Edit Shipping Zone | 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]">Edit Shipping Zone</h1> + <p class="mt-2 text-sm text-gray-500">Update this pincode-based shipping rate.</p> + </div> + <a href="{{ route('shipping-settings.index') }}" class="inline-flex h-11 items-center justify-center rounded-full border border-gray-200 bg-white px-5 text-sm font-semibold text-gray-600 shadow-sm transition hover:bg-gray-50"> + Back + </a> + </div> + + <form method="POST" action="{{ route('shipping-settings.update', $shippingZone) }}" class="overflow-hidden rounded-[32px] bg-white shadow-sm"> + @csrf + @method('PUT')
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', 'Tax Settings | Avriti Dashboard') + @section('content') + + @php + $openModal = old('_modal'); + @endphp + + <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]">Tax Settings</h1> + </div> + <button type="button" data-modal-target="createTaxModal" 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 Country Tax + </button> + </div>
Removed / Before Commit
Added / After Commit
+ @extends('layouts.app') + + @section('title', 'Transactions | 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]">Transactions</h1> + </div> + </div> + + <div class="bg-white rounded-2xl shadow-sm overflow-hidden"> + <div class="overflow-x-auto px-4 py-4"> + <table id="transactionsTable" data-action-column="7" class="{{ $orders->isNotEmpty() ? 'js-data-table' : '' }} w-full text-sm text-left text-gray-600"> + <thead class="bg-[#0b3dba] border-b border-gray-200 text-gray-500"> + <tr> + <th class="px-5 py-4 font-semibold text-white">Order No</th> + <th class="px-5 py-4 font-semibold text-white">Customer</th>
Removed / Before Commit
- <p class="mt-2 text-sm font-semibold text-gray-900">{{ $user->created_at?->format('d M, Y') ?? '-' }}</p> - </div> - @if ($profile?->user_img) - <img src="{{ asset($profile->user_img) }}" alt="{{ old('name', $profile?->name) ?: $user->username }}" class="border-2 border-[#0b3dba] w-[48px] h-[48px] rounded-full object-cover" /> - @else - <div class="border-2 border-[#0b3dba] w-[48px] h-[48px] rounded-full flex items-center justify-center text-[#0b3dba]"><i class="fa-solid fa-user"></i></div> - @endif - type="text" - name="name" - value="{{ old('name', $profile?->name) }}" - class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> - @error('name') - <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> - type="text" - name="destination" - value="{{ old('destination', $profile?->destination) }}" - class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> - @error('destination')
Added / After Commit
+ <p class="mt-2 text-sm font-semibold text-gray-900">{{ $user->created_at?->format('d M, Y') ?? '-' }}</p> + </div> + @if ($profile?->user_img) + <img src="{{ asset($profile->user_img) }}" alt="{{ old('name', $profile?->name) ?: $user->username }}" class="border-2 border-[#0b3dba] w-[48px] h-[48px] rounded-full object-contain" /> + @else + <div class="border-2 border-[#0b3dba] w-[48px] h-[48px] rounded-full flex items-center justify-center text-[#0b3dba]"><i class="fa-solid fa-user"></i></div> + @endif + type="text" + name="name" + value="{{ old('name', $profile?->name) }}" + required + class="w-full h-12 px-4 border border-gray-300 rounded-md outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent" /> + @error('name') + <p class="mt-2 text-xs font-medium text-red-500">{{ $message }}</p> + type="text" + name="destination" + value="{{ old('destination', $profile?->destination) }}" + required
Removed / Before Commit
- $profileData = [ - 'image' => $profile?->user_img ?: null, - 'name' => $profile?->name ?: $user->username ?: '-', - 'subtitle' => $profile?->destination ?: '-', - 'location' => $profile?->location ?: '-', - 'email' => $user->email ?: '-',
Added / After Commit
+ $profileData = [ + 'image' => $profile?->user_img ?: null, + 'name' => $profile?->name ?: $user->username ?: '-', + 'username' => $user->username ?: '-', + 'subtitle' => $profile?->destination ?: '-', + 'location' => $profile?->location ?: '-', + 'email' => $user->email ?: '-',
Removed / Before Commit
- <td class="px-6 py-5"> - <div class="flex items-center gap-3"> - @if ($profile?->user_img) - <img src="{{ asset($profile->user_img) }}" alt="{{ $displayName }}" class="border-2 border-[#0b3dba] w-[40px] h-[40px] rounded-full object-cover" /> - @else - <div class="border-2 border-[#0b3dba] w-[40px] h-[40px] rounded-full flex items-center justify-center"><i class="fa-solid fa-user"></i></div> - @endif
Added / After Commit
+ <td class="px-6 py-5"> + <div class="flex items-center gap-3"> + @if ($profile?->user_img) + <img src="{{ asset($profile->user_img) }}" alt="{{ $displayName }}" class="border-2 border-[#0b3dba] w-[40px] h-[40px] rounded-full object-contain" /> + @else + <div class="border-2 border-[#0b3dba] w-[40px] h-[40px] rounded-full flex items-center justify-center"><i class="fa-solid fa-user"></i></div> + @endif
Removed / Before Commit
- const closeModal = (modal) => { - modal?.classList.add('hidden'); - document.body.classList.remove('overflow-hidden'); - }; - - document.addEventListener('click', (event) => {
Added / After Commit
+ const closeModal = (modal) => { + modal?.classList.add('hidden'); + document.body.classList.remove('overflow-hidden'); + modal?.querySelector('form')?.reset(); + modal?.querySelectorAll('[data-error-message]').forEach((el) => el.remove()); + }; + + document.addEventListener('click', (event) => {
Removed / Before Commit
- <td style="padding:15px 18px;border-bottom:1px solid #eeeeee;color:#111827;font-size:14px;">{{ $contact->email }}</td> - </tr> - <tr> - <td style="padding:15px 18px;color:#7a7a7a;font-size:13px;">Phone</td> - <td style="padding:15px 18px;color:#111827;font-size:14px;">{{ $contact->phone ?: '-' }}</td> - </tr> - </table>
Added / After Commit
+ <td style="padding:15px 18px;border-bottom:1px solid #eeeeee;color:#111827;font-size:14px;">{{ $contact->email }}</td> + </tr> + <tr> + <td style="padding:15px 18px;border-bottom:1px solid #eeeeee;color:#7a7a7a;font-size:13px;">Phone</td> + <td style="padding:15px 18px;border-bottom:1px solid #eeeeee;color:#111827;font-size:14px;">{{ $contact->phone ?: '-' }}</td> + </tr> + <tr> + <td style="padding:15px 18px;color:#7a7a7a;font-size:13px;">Service</td> + <td style="padding:15px 18px;color:#111827;font-size:14px;">{{ $contact->service_type ?: '-' }}</td> + </tr> + </table>
Removed / Before Commit
- <td style="padding:13px 16px;border-bottom:1px solid #eeeeee;color:#111827;font-size:13px;">{{ $contact->email }}</td> - </tr> - <tr> - <td style="padding:13px 16px;color:#7a7a7a;font-size:13px;">Phone</td> - <td style="padding:13px 16px;color:#111827;font-size:13px;">{{ $contact->phone ?: '-' }}</td> - </tr> - </table> - </td>
Added / After Commit
+ <td style="padding:13px 16px;border-bottom:1px solid #eeeeee;color:#111827;font-size:13px;">{{ $contact->email }}</td> + </tr> + <tr> + <td style="padding:13px 16px;border-bottom:1px solid #eeeeee;color:#7a7a7a;font-size:13px;">Phone</td> + <td style="padding:13px 16px;border-bottom:1px solid #eeeeee;color:#111827;font-size:13px;">{{ $contact->phone ?: '-' }}</td> + </tr> + <tr> + <td style="padding:13px 16px;color:#7a7a7a;font-size:13px;">Service</td> + <td style="padding:13px 16px;color:#111827;font-size:13px;">{{ $contact->service_type ?: '-' }}</td> + </tr> + </table> + </td>
Removed / Before Commit
- <!DOCTYPE html> - <html lang="en"> - <head> - <tr> - <td style="padding:14px 20px; border-bottom:1px solid #f0f0f0; font-size:13px; color:#444;"> - <span style="color:#888; display:inline-block; width:110px;">Web Address:</span> - <span style="color:#1a1a1a;">{{ config('app.url') }}</span> - </td> - </tr> - <tr>
Added / After Commit
+ @php($frontendUrl = rtrim(env('FRONTEND_URL', config('app.url')), '/')) + <!DOCTYPE html> + <html lang="en"> + <head> + <tr> + <td style="padding:14px 20px; border-bottom:1px solid #f0f0f0; font-size:13px; color:#444;"> + <span style="color:#888; display:inline-block; width:110px;">Web Address:</span> + <span style="color:#1a1a1a;">{{ $frontendUrl }}</span> + </td> + </tr> + <tr>
Removed / Before Commit
Added / After Commit
+ <!DOCTYPE html> + <html lang="en"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + <link href="https://fonts.googleapis.com/css2?family=Basic&display=swap" rel="stylesheet"> + <title>Verify Your Email</title> + </head> + <body style="margin:0; padding:0; font-family: 'Basic', Arial, sans-serif; background:#f0f4f8;"> + @php($verifyUrl = rtrim(env('FRONTEND_URL', config('app.url')), '/') . '/verify-email?email=' . urlencode($email) . '&token=' . urlencode($token)) + <table width="420" cellpadding="0" cellspacing="0" border="0" style="max-width:500px; width:90%; margin:20px auto;background-color:#ffffff; border-radius:16px; overflow:hidden; box-shadow:0 4px 20px rgba(0,0,0,0.08);"> + <tr><td align="center" style="padding: 30px 20px 0 20px;"><img src="{{ url('img/logo1.png') }}" alt="Avriti" style="max-width:150px; width:100%;"></td></tr> + <tr> + <td align="center" style="padding:40px 40px 30px 40px;"> + <div style="font-size:64px; line-height:1; margin-bottom:6px;">📧✅</div> + <div style="font-size:22px; font-weight:700; color:#1a1a1a; margin-top:20px;">Verify your email</div> + <div style="font-size:14px; color:#0b3dba; font-weight:600; margin-top:16px;">Hey {{ $name ?: 'there' }},</div> + <div style="font-size:13px; color:#555555; margin-top:10px; line-height:1.7; text-align:center; max-width:300px; margin-left:auto; margin-right:auto;">Thanks for signing up with Avriti. Please verify your email address to activate your account.</div>
Removed / Before Commit
- <!DOCTYPE html> - <html lang="en"> - <head> - <tr> - <td style="padding:0 40px 20px;"> - <div style="text-align:center;"> - <a href="{{ config('app.url') }}" style="display:inline-block;text-decoration:none;font-family:'Basic',Arial,sans-serif;text-transform:uppercase;background:#0b3dba; padding:10px 30px; border-radius:10px; color:#fff; border:1px solid #0b3dba; margin:0 auto;">Visit Avriti</a> - </div> - </td> - </tr>
Added / After Commit
+ @php($frontendUrl = rtrim(env('FRONTEND_URL', config('app.url')), '/')) + <!DOCTYPE html> + <html lang="en"> + <head> + <tr> + <td style="padding:0 40px 20px;"> + <div style="text-align:center;"> + <a href="{{ $frontendUrl }}" style="display:inline-block;text-decoration:none;font-family:'Basic',Arial,sans-serif;text-transform:uppercase;background:#0b3dba; padding:10px 30px; border-radius:10px; color:#fff; border:1px solid #0b3dba; margin:0 auto;">Visit Avriti</a> + </div> + </td> + </tr>
Removed / Before Commit
- $shipping_addr = $orderData['shipping_address'] ?? []; - $itemsCount = count($items); - $subtotal = (float) ($orderData['subtotal'] ?? 0); - $tax = (float) ($orderData['tax'] ?? 0); - $shippingCost = (float) ($orderData['shipping'] ?? 0); - $total = (float) ($orderData['total'] ?? 0); - <td style="font-size:13px; color:#555; padding:4px 0;">Items ({{ $itemsCount }})</td> - <td align="right" style="font-size:13px; color:#1a1a1a; padding:4px 0;">₹{{ number_format($subtotal, 2) }}</td> - </tr> - <tr> - <td style="font-size:13px; color:#555; padding:4px 0;">Tax</td> - <td align="right" style="font-size:13px; color:#1a1a1a; padding:4px 0;">₹{{ number_format($tax, 2) }}</td> - <div style="font-size:12px; font-weight:700; color:#0b3dba; margin-bottom:8px;">📦 Shipping Address</div> - <div style="font-size:12px; font-weight:600; color:#1a1a1a; margin-bottom:4px;">{{ $shipping_addr['full_name'] ?? $billing['full_name'] ?? 'Customer' }}</div> - <div style="font-size:11px; color:#666; line-height:1.8;"> - {{ $shipping_addr['phone'] ?? $billing['phone'] ?? '-' }}<br> - {{ $shipping_addr['address_line1'] ?? $billing['address_line1'] ?? '-' }}@if(!empty($shipping_addr['address_line2'] ?? $billing['address_line2'])), {{ $shipping_addr['address_line2'] ?? $billing['address_line2'] }}@endif<br> - {{ $shipping_addr['city'] ?? $billing['city'] ?? '-' }}, {{ $shipping_addr['state'] ?? $billing['state'] ?? '-' }}<br>
Added / After Commit
+ $shipping_addr = $orderData['shipping_address'] ?? []; + $itemsCount = count($items); + $subtotal = (float) ($orderData['subtotal'] ?? 0); + $discount = (float) ($orderData['discount'] ?? 0); + $tax = (float) ($orderData['tax'] ?? 0); + $shippingCost = (float) ($orderData['shipping'] ?? 0); + $total = (float) ($orderData['total'] ?? 0); + <td style="font-size:13px; color:#555; padding:4px 0;">Items ({{ $itemsCount }})</td> + <td align="right" style="font-size:13px; color:#1a1a1a; padding:4px 0;">₹{{ number_format($subtotal, 2) }}</td> + </tr> + @if($discount > 0) + <tr> + <td style="font-size:13px; color:#555; padding:4px 0;">Discount</td> + <td align="right" style="font-size:13px; color:#22c55e; font-weight:600; padding:4px 0;">-₹{{ number_format($discount, 2) }}</td> + </tr> + @endif + <tr> + <td style="font-size:13px; color:#555; padding:4px 0;">Tax</td>
Removed / Before Commit
- <span class="block lg:hidden text-xl font-bold tracking-tight"> - <img src="{{ asset('img/logo1.png') }}" class="invert brightness-0 w-[100px]" /> - </span> - <div class="hidden md:flex items-center gap-2 bg-gray-100 rounded-full px-4 py-2 md:w-72"> - <svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg> - <input type="text" placeholder="Search..." class="bg-transparent text-sm text-gray-600 placeholder-gray-400 outline-none w-full"/> - </div> - </div> - - <!-- Right: flags, icons, avatar --> - <div class="relative" data-user-menu> - <button type="button" data-user-menu-toggle class="flex items-center gap-2 cursor-pointer"> - @if ($headerImage) - <img src="{{ asset($headerImage) }}" alt="{{ $headerUser->username ?? 'User' }}" class="w-9 h-9 rounded-full border-2 border-[#0b3dba] object-cover bg-gray-100"/> - @else - <div class="w-9 h-9 rounded-full border-2 border-[#0b3dba] flex items-center justify-center bg-gray-100 text-gray-600"> - <i class="fa-solid fa-user"></i>
Added / After Commit
+ <span class="block lg:hidden text-xl font-bold tracking-tight"> + <img src="{{ asset('img/logo1.png') }}" class="invert brightness-0 w-[100px]" /> + </span> + <!-- <div class="hidden md:flex items-center gap-2 bg-gray-100 rounded-full px-4 py-2 md:w-72"> + <svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg> + <input type="text" placeholder="Search..." class="bg-transparent text-sm text-gray-600 placeholder-gray-400 outline-none w-full"/> + </div> --> + </div> + + <!-- Right: flags, icons, avatar --> + <div class="relative" data-user-menu> + <button type="button" data-user-menu-toggle class="flex items-center gap-2 cursor-pointer"> + @if ($headerImage) + <img src="{{ asset($headerImage) }}" alt="{{ $headerUser->username ?? 'User' }}" class="w-9 h-9 rounded-full border-2 border-[#0b3dba] object-contain bg-gray-100"/> + @else + <div class="w-9 h-9 rounded-full border-2 border-[#0b3dba] flex items-center justify-center bg-gray-100 text-gray-600"> + <i class="fa-solid fa-user"></i>
Removed / Before Commit
- Orders - </a> - - <!-- <a href="{{ route('return-refund.index') }}" class="flex items-center gap-3 px-3 py-2.5 rounded-xl {{ request()->routeIs('return-refund.*') ? $activeClass : $inactiveClass }}"> - <i class="fa-solid fa-arrow-rotate-left"></i> - Returns & Refunds - </a> --> - - {{-- Products Group --}} - @php $productsOpen = request()->routeIs('product-categories.*', 'product-types.*', 'variants.*', 'products.*'); @endphp - <div> - <button type="button" id="productsToggle" - 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"> - <i class="fa-solid fa-box-open"></i> - Products - </a> - </div> - </div>
Added / After Commit
+ Orders + </a> + + <a href="{{ route('transactions.index') }}" class="flex items-center gap-3 px-3 py-2.5 rounded-xl {{ request()->routeIs('transactions.*') ? $activeClass : $inactiveClass }}"> + <i class="fa-solid fa-money-bill-transfer"></i> + Transactions + </a> + + <a href="{{ route('tax-settings.index') }}" class="flex items-center gap-3 px-3 py-2.5 rounded-xl {{ request()->routeIs('tax-settings.*') ? $activeClass : $inactiveClass }}"> + <i class="fa-solid fa-percent"></i> + Tax Settings + </a> + + <a href="{{ route('shipping-settings.index') }}" class="flex items-center gap-3 px-3 py-2.5 rounded-xl {{ request()->routeIs('shipping-settings.*') ? $activeClass : $inactiveClass }}"> + <i class="fa-solid fa-truck"></i> + Shipping Settings + </a> +
Removed / Before Commit
- <?php - - use App\Http\Controllers\AuthController; - use App\Http\Controllers\Api\CartController; - use App\Http\Controllers\Api\CustomerAuthController; - use App\Http\Controllers\Api\WishlistController; - use App\Http\Controllers\Api\CustomerProfileController; - use App\Http\Controllers\Api\RazorpayController; - use App\Http\Middleware\CheckCustomerActive; - - Route::post('/register', [AuthController::class, 'apiRegister'])->name('api.register'); - Route::get('/faqs', [FaqController::class, 'index']); - Route::get('/home', [HomeController::class, 'index']); - Route::get('/services', [ServiceController::class, 'index']); - Route::post('/contact', [ContactController::class, 'store']); - - Route::prefix('customer')->group(function () { - Route::post('/register', [CustomerAuthController::class, 'register']);
Added / After Commit
+ <?php + use App\Http\Controllers\Api\CouponController; + use App\Http\Controllers\AuthController; + use App\Http\Controllers\Api\CartController; + use App\Http\Controllers\Api\CustomerAuthController; + use App\Http\Controllers\Api\WishlistController; + use App\Http\Controllers\Api\CustomerProfileController; + use App\Http\Controllers\Api\RazorpayController; + use App\Http\Controllers\Api\ShippingController; + use App\Http\Controllers\Api\TaxController; + use App\Http\Controllers\Api\ComboProductController; + use App\Http\Controllers\Api\PaymentSettingController; + use App\Http\Middleware\CheckCustomerActive; + + Route::post('/register', [AuthController::class, 'apiRegister'])->name('api.register'); + Route::get('/faqs', [FaqController::class, 'index']); + Route::get('/home', [HomeController::class, 'index']); + Route::get('/services', [ServiceController::class, 'index']);
Removed / Before Commit
- use App\Http\Controllers\AdminHomeController; - use App\Http\Controllers\AdminFaqController; - use App\Http\Controllers\AdminContactController; - use App\Http\Controllers\AdminServiceController; - use App\Http\Controllers\AdminCustomerController; - use App\Http\Controllers\AdminDashboardController; - use App\Http\Controllers\AdminOrderController; - use Illuminate\Support\Facades\Route; - - Route::get('/', function () { - Route::delete('/users/{user}', [AdminUserController::class, 'destroy'])->name('users.destroy'); - - Route::get('/orders', [AdminOrderController::class, 'index'])->name('orders.index'); - Route::get('/orders/{order}', [AdminOrderController::class, 'show'])->name('orders.show'); - Route::patch('/orders/{order}/status', [AdminOrderController::class, 'updateStatus'])->name('orders.updateStatus'); - Route::view('/return-refund', 'admin.return-refund')->name('return-refund.index'); - Route::post('/variants', [AdminVariantController::class, 'store'])->name('variants.store'); - Route::put('/variants/{variant}', [AdminVariantController::class, 'update'])->name('variants.update');
Added / After Commit
+ use App\Http\Controllers\AdminHomeController; + use App\Http\Controllers\AdminFaqController; + 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\AdminShippingSettingController; + use App\Http\Controllers\AdminTaxSettingController; + 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('/users/{user}', [AdminUserController::class, 'destroy'])->name('users.destroy'); +