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 · f307c78a
The commit introduces a new CLI command for importing Indian pincodes, adds an admin controller for pincodes, enhances product validation and storage, fixes phone validation, and adds shipping setting management. The code-quality is good with proper input validation and pagination for searches. The commit message is inadequate and uninformative. Security is good but input validation could be stricter, and there are potential risks in file handling (no CSV header validation, no exception handling when reading file). The business value is decent as it improves admin features and data import. Minor bug risk due to lack of exception handling and assumptions about CSV format. Phone validation fixes enhance data quality.
Quality
?
85%
Security
?
70%
Business Value
?
80%
Maintainability
?
85%
Issues & Suggested Fixes
?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Issue
Where
commit message
Issue / Evidence
issue
Suggested Fix
provide a descriptive commit message explaining the purpose and scope of the commit
File Handling Without Exception Handling
Where
app/Console/Commands/ImportPincodes.php:15
Issue / Evidence
file handling without exception handling
Suggested Fix
add try-catch or similar to handle potential file read errors
Assume Csv Header Columns Exist
Where
app/Console/Commands/ImportPincodes.php:21
Issue / Evidence
assume CSV header columns exist
Suggested Fix
validate presence of 'pincode', 'district', 'statename' in header before accessing indices
Lack Of Logging On Skipped Rows
Where
app/Console/Commands/ImportPincodes.php:27
Issue / Evidence
lack of logging on skipped rows
Suggested Fix
consider logging or reporting malformed rows for data quality
Missing Validation
Where
app/Http/Controllers/AdminCustomerController.php:33
Issue / Evidence
phone validation changed but no user feedback or conversion
Suggested Fix
consider adding validation messages or formatting for better UX
Search Accepts Short Queries >= 2 Chars On...
Where
app/Http/Controllers/AdminPincodeController.php:19
Issue / Evidence
search accepts short queries >= 2 chars only
Suggested Fix
consider configurable minimum length or validation messaging
Incomplete Controller Method 'Store'
Where
app/Http/Controllers/AdminShippingSettingController.php:114
Issue / Evidence
incomplete controller method 'store'
Suggested Fix
ensure method implementation is complete or commit only finished code
Code Change Preview · app/Console/Commands/ImportPincodes.php
?
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
- { - $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
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
- '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'] ?? []), - 'includes' => $this->cleanRows($validated['includes'] ?? []), - 'attributes' => $this->cleanAttributeRows($validated['attributes'] ?? []), - 'thumbnail' => $this->cleanImagePaths($thumbnailPaths), - 'featured' => (bool) ($validated['featured'] ?? false),
Added / After Commit
+ 'attributes.*.in_stock' => ['nullable', 'boolean'], + 'how_to_use' => ['nullable', 'array'], + 'how_to_use.*' => ['nullable', 'string', 'max:255'], + 'fragrance' => ['nullable', 'array'], + 'fragrance.*' => ['nullable', 'string', 'max:255'], + 'sold_as' => ['nullable', 'array'], + 'sold_as.*' => ['nullable', 'string', 'max:255'], + 'country_of_origin' => ['nullable', 'string', 'max:255'], + 'storage_instructions' => ['nullable', 'string'], + 'disclaimer' => ['nullable', 'string'], + 'important_notes' => ['nullable', 'string'], + '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'] ?? []), + 'includes' => $this->cleanRows($validated['includes'] ?? []), + 'fragrance' => $this->cleanRows($validated['fragrance'] ?? []),
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
- 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
- 'message' => 'Message sent successfully!', - ], 201); - } - }
Added / After Commit
+ 'message' => 'Message sent successfully!', + ], 201); + } + + public function subscribe(Request $request) + { + $request->validate([ + 'email' => 'required|email', + ]); + + $contact = Contact::create([ + 'name' => 'Footer Subscriber', + 'email' => $request->email, + 'phone' => null, + 'service_type' => 'Newsletter', + 'message' => 'Subscribed to the newsletter from the website footer.', + ]); +
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\Models\PaymentSetting; - use App\Models\Product; - use App\Services\CouponService; - use App\Services\TaxService; - use Illuminate\Http\JsonResponse; - use Illuminate\Http\Request; - Log::info('COD order attempt', ['customer_id' => $customerId, 'total' => $request->input('total', 0)]); - - $subtotal = (float) $request->input('subtotal', 0); - $shippingCharge = (float) $request->input('shipping', 0); - $couponCode = $request->input('coupon_code'); - - $discount = 0; - $appliedCouponCode = $couponResult['coupon']->code; - } - - $taxResult = TaxService::calculate($subtotal - $discount); - $totalAmount = round($subtotal - $discount + $shippingCharge + $taxResult['tax_amount'], 2);
Added / After Commit
+ 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; + Log::info('COD order attempt', ['customer_id' => $customerId, 'total' => $request->input('total', 0)]); + + $subtotal = (float) $request->input('subtotal', 0); + $couponCode = $request->input('coupon_code'); + + $discount = 0; + $appliedCouponCode = $couponResult['coupon']->code; + } + + $taxResult = TaxService::calculate($subtotal - $discount); + $shippingResult = ShippingService::calculate($subtotal - $discount, $shippingAddress['pincode'] ?? null);
Removed / Before Commit
- use App\Models\Order; - use App\Models\Product; - use App\Services\CouponService; - use App\Services\TaxService; - use Illuminate\Http\JsonResponse; - use Illuminate\Http\Request; - } - - $subtotal = (float) $request->input('subtotal', 0); - $shippingCharge = (float) $request->input('shipping', 0); - $couponCode = $request->input('coupon_code'); - - $discount = 0; - } - - $taxResult = TaxService::calculate($subtotal - $discount); - - $order = Order::create([
Added / After Commit
+ 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; + } + + $subtotal = (float) $request->input('subtotal', 0); + $couponCode = $request->input('coupon_code'); + + $discount = 0; + } + + $taxResult = TaxService::calculate($subtotal - $discount); + $shippingResult = ShippingService::calculate($subtotal - $discount, $shippingAddress['pincode'] ?? null); + $shippingCharge = $shippingResult['shipping_charge'];
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\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
- { - 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
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', + 'storage_instructions', + 'disclaimer', + 'important_notes', + 'attributes', + 'thumbnail', + 'featured', + 'best_for' => 'array', + 'how_to_use' => 'array', + 'includes' => 'array', + 'fragrance' => 'array', + 'sold_as' => 'array', + 'attributes' => '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\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 + + 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
- <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) }}"
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)) }}
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)) }}
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
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
- $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
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
+ @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
- <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
- <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
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
- $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>
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
- <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
+ <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
- Tax Settings - </a> - - <a href="{{ route('coupons.index') }}" class="flex items-center gap-3 px-3 py-2.5 rounded-xl {{ request()->routeIs('coupons.*') ? $activeClass : $inactiveClass }}"> - <i class="fa-solid fa-ticket"></i> - Coupons
Added / After Commit
+ 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> + + <a href="{{ route('coupons.index') }}" class="flex items-center gap-3 px-3 py-2.5 rounded-xl {{ request()->routeIs('coupons.*') ? $activeClass : $inactiveClass }}"> + <i class="fa-solid fa-ticket"></i> + Coupons
Removed / Before Commit
- use App\Http\Controllers\Api\WishlistController; - use App\Http\Controllers\Api\CustomerProfileController; - use App\Http\Controllers\Api\RazorpayController; - use App\Http\Controllers\Api\TaxController; - use App\Http\Controllers\Api\ComboProductController; - use App\Http\Controllers\Api\PaymentSettingController; - Route::get('/combo-products', [ComboProductController::class, 'index']); - Route::get('/combo-products/{slug}', [ComboProductController::class, 'show']); - Route::post('/contact', [ContactController::class, 'store']); - Route::post('/tax/calculate', [TaxController::class, 'calculate']); - Route::get('/payment-settings', [PaymentSettingController::class, 'index']); - - Route::prefix('customer')->group(function () { - Route::post('/register', [CustomerAuthController::class, 'register']); - Route::post('/login', [CustomerAuthController::class, 'login']); - Route::post('/forgot-password', [CustomerAuthController::class, 'forgotPassword']); - Route::post('/reset-password', [CustomerAuthController::class, 'resetPassword']);
Added / After Commit
+ 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; + Route::get('/combo-products', [ComboProductController::class, 'index']); + Route::get('/combo-products/{slug}', [ComboProductController::class, 'show']); + Route::post('/contact', [ContactController::class, 'store']); + Route::post('/subscribe', [ContactController::class, 'subscribe']); + Route::post('/tax/calculate', [TaxController::class, 'calculate']); + Route::post('/shipping/calculate', [ShippingController::class, 'calculate']); + Route::get('/payment-settings', [PaymentSettingController::class, 'index']); + + Route::prefix('customer')->group(function () { + Route::post('/register', [CustomerAuthController::class, 'register']); + Route::post('/login', [CustomerAuthController::class, 'login']);
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 App\Http\Controllers\AdminTaxSettingController; - use App\Http\Controllers\AdminComboProductController; - use App\Http\Controllers\AdminCouponController; - Route::patch('/tax-settings/{taxSetting}/activate', [AdminTaxSettingController::class, 'activate'])->name('tax-settings.activate'); - Route::delete('/tax-settings/{taxSetting}', [AdminTaxSettingController::class, 'destroy'])->name('tax-settings.destroy'); - - Route::get('/coupons', [AdminCouponController::class, 'index'])->name('coupons.index'); - Route::post('/coupons', [AdminCouponController::class, 'store'])->name('coupons.store'); - Route::put('/coupons/{coupon}', [AdminCouponController::class, 'update'])->name('coupons.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; + Route::patch('/tax-settings/{taxSetting}/activate', [AdminTaxSettingController::class, 'activate'])->name('tax-settings.activate'); + Route::delete('/tax-settings/{taxSetting}', [AdminTaxSettingController::class, 'destroy'])->name('tax-settings.destroy'); + + Route::get('/shipping-settings', [AdminShippingSettingController::class, 'index'])->name('shipping-settings.index'); + Route::get('/shipping-settings/create', [AdminShippingSettingController::class, 'create'])->name('shipping-settings.create'); + Route::post('/shipping-settings', [AdminShippingSettingController::class, 'store'])->name('shipping-settings.store');