Pārlūkot izejas kodu

feat: :sparkles: feat (loja-admin) criada a loja no layout admin

foi criada a loja no layout admin, com visualizacao e edicao dos itens, por categoria e tipo de variacao

fase:dev | origin:escopo
Gustavo Zanatta 1 mēnesi atpakaļ
vecāks
revīzija
245c720914

+ 31 - 2
app/Http/Controllers/PartnerAgreementController.php

@@ -7,6 +7,11 @@ use App\Http\Requests\UploadLogoRequest;
 use App\Http\Requests\UploadMediaRequest;
 use App\Http\Resources\MediaResource;
 use App\Http\Resources\PartnerAgreementResource;
+use App\Http\Resources\PartnerAgreementListResource;
+use App\Http\Resources\PartnerAgreementDadosResource;
+use App\Http\Resources\PartnerAgreementContatoResource;
+use App\Http\Resources\PartnerAgreementEnderecoResource;
+use App\Http\Resources\PartnerAgreementContratoResource;
 use App\Services\MediaService;
 use App\Services\PartnerAgreementService;
 use Illuminate\Http\JsonResponse;
@@ -22,7 +27,7 @@ class PartnerAgreementController extends Controller
     public function index(): JsonResponse
     {
         $items = $this->service->getAll();
-        return $this->successResponse(payload: PartnerAgreementResource::collection($items));
+        return $this->successResponse(payload: PartnerAgreementListResource::collection($items));
     }
 
     public function indexPaginated(Request $request): JsonResponse
@@ -32,7 +37,7 @@ class PartnerAgreementController extends Controller
         $paginator = $this->service->getAllPaginated($filters, $perPage);
 
         return $this->successResponse(payload: [
-            'data'  => PartnerAgreementResource::collection($paginator->items()),
+            'data'  => PartnerAgreementListResource::collection($paginator->items()),
             'total' => $paginator->total(),
             'from'  => $paginator->firstItem() ?? 0,
             'to'    => $paginator->lastItem() ?? 0,
@@ -89,4 +94,28 @@ class PartnerAgreementController extends Controller
         $this->mediaService->delete($mediaId);
         return $this->successResponse(message: __('messages.deleted'), code: 204);
     }
+
+    public function showDados(int $id): JsonResponse
+    {
+        $item = $this->service->findDados($id);
+        return $this->successResponse(payload: new PartnerAgreementDadosResource($item));
+    }
+
+    public function showContato(int $id): JsonResponse
+    {
+        $item = $this->service->findContato($id);
+        return $this->successResponse(payload: new PartnerAgreementContatoResource($item));
+    }
+
+    public function showEndereco(int $id): JsonResponse
+    {
+        $item = $this->service->findEndereco($id);
+        return $this->successResponse(payload: new PartnerAgreementEnderecoResource($item));
+    }
+
+    public function showContrato(int $id): JsonResponse
+    {
+        $item = $this->service->findContrato($id);
+        return $this->successResponse(payload: new PartnerAgreementContratoResource($item));
+    }
 }

+ 81 - 1
app/Http/Controllers/StoreItemController.php

@@ -3,13 +3,21 @@
 namespace App\Http\Controllers;
 
 use App\Http\Requests\StoreItemRequest;
+use App\Http\Requests\UploadMediaRequest;
+use App\Http\Resources\MediaResource;
 use App\Http\Resources\StoreItemResource;
+use App\Http\Resources\StoreItemVariationResource;
+use App\Services\MediaService;
 use App\Services\StoreItemService;
 use Illuminate\Http\JsonResponse;
+use Illuminate\Http\Request;
 
 class StoreItemController extends Controller
 {
-    public function __construct(protected StoreItemService $service) {}
+    public function __construct(
+        protected StoreItemService $service,
+        protected MediaService $mediaService,
+    ) {}
 
     public function index(): JsonResponse
     {
@@ -48,6 +56,30 @@ class StoreItemController extends Controller
         return $this->successResponse(message: __('messages.deleted'), code: 204);
     }
 
+    public function indexPaginated(Request $request): JsonResponse
+    {
+        $perPage = (int) $request->query('per_page', 10);
+        $filters = $request->only(['search', 'status', 'category_id']);
+
+        $paginator = $this->service->getAllPaginated($filters, $perPage);
+
+        return $this->successResponse(payload: [
+            'data'  => StoreItemResource::collection($paginator->items()),
+            'total' => $paginator->total(),
+            'from'  => $paginator->firstItem(),
+            'to'    => $paginator->lastItem(),
+        ]);
+    }
+
+    public function toggleStatus(int $id): JsonResponse
+    {
+        $item = $this->service->toggleStatus($id);
+        return $this->successResponse(
+            payload: new StoreItemResource($item),
+            message: __('messages.updated'),
+        );
+    }
+
     public function myInterests(): JsonResponse
     {
         $items = $this->service->getMyInterests();
@@ -62,4 +94,52 @@ class StoreItemController extends Controller
             message: __('messages.updated'),
         );
     }
+
+    public function uploadMedia(UploadMediaRequest $request, int $id): JsonResponse
+    {
+        $file  = $request->file('file');
+        $media = $this->mediaService->upload($file, 'store_item', $id, 'imagem');
+        return $this->successResponse(payload: new MediaResource($media), code: 201);
+    }
+
+    public function deleteMedia(int $id, int $mediaId): JsonResponse
+    {
+        $this->mediaService->delete($mediaId);
+        return $this->successResponse(message: __('messages.deleted'), code: 204);
+    }
+
+    public function getInterests(int $id): JsonResponse
+    {
+        $interests = $this->service->getInterestsByItem($id);
+        return $this->successResponse(payload: $interests);
+    }
+
+    public function addVariation(Request $request, int $id): JsonResponse
+    {
+        $data = $request->validate([
+            'variation_type'  => 'required|string|in:tamanho,cor,modelo',
+            'variation_label' => 'required|string|max:100',
+            'variation_value' => 'nullable|numeric|min:0',
+            'stock'           => 'nullable|integer|min:0',
+        ]);
+        $variation = $this->service->addVariation($id, $data);
+        return $this->successResponse(payload: new StoreItemVariationResource($variation), code: 201);
+    }
+
+    public function updateVariation(Request $request, int $id, int $variationId): JsonResponse
+    {
+        $data = $request->validate([
+            'variation_label' => 'sometimes|string|max:100',
+            'variation_value' => 'nullable|numeric|min:0',
+            'stock'           => 'nullable|integer|min:0',
+        ]);
+        $variation = $this->service->updateVariation($id, $variationId, $data);
+        return $this->successResponse(payload: new StoreItemVariationResource($variation));
+    }
+
+    public function deleteVariation(int $id, int $variationId): JsonResponse
+    {
+        $this->service->deleteVariation($id, $variationId);
+        return $this->successResponse(code: 204);
+    }
 }

+ 1 - 1
app/Http/Requests/CategoryRequest.php

@@ -10,7 +10,7 @@ class CategoryRequest extends FormRequest
     {
         $rules = [
             'name'   => 'sometimes|string|max:255',
-            'type'   => 'sometimes|nullable|string|in:partner,service,order',
+            'type'   => 'sometimes|nullable|string|in:partner,service,order,store',
             'active' => 'sometimes|boolean',
         ];
 

+ 6 - 8
app/Http/Requests/StoreItemRequest.php

@@ -17,15 +17,13 @@ class StoreItemRequest extends FormRequest
             'price'           => 'sometimes|nullable|numeric|min:0',
             'associate_price' => 'sometimes|nullable|numeric|min:0',
             'supplier_price'  => 'sometimes|nullable|numeric|min:0',
-            'size_s'          => 'sometimes|boolean',
-            'stock_s'         => 'sometimes|integer|min:0',
-            'size_m'          => 'sometimes|boolean',
-            'stock_m'         => 'sometimes|integer|min:0',
-            'size_l'          => 'sometimes|boolean',
-            'stock_l'         => 'sometimes|integer|min:0',
-            'size_xl'         => 'sometimes|boolean',
-            'stock_xl'        => 'sometimes|integer|min:0',
             'status'          => ['sometimes', Rule::enum(StoreItemStatusEnum::class)],
+
+            'variations'                       => 'sometimes|array',
+            'variations.*.variation_type'      => 'required_with:variations|string|in:tamanho,cor,modelo',
+            'variations.*.variation_label'     => 'required_with:variations|string|max:100',
+            'variations.*.variation_value'     => 'nullable|numeric|min:0',
+            'variations.*.stock'               => 'nullable|integer|min:0',
         ];
 
         if ($this->isMethod('post')) {

+ 20 - 0
app/Http/Resources/PartnerAgreementContatoResource.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class PartnerAgreementContatoResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id'       => $this->id,
+            'email'    => $this->email,
+            'phone'    => $this->phone,
+            'whatsapp' => $this->whatsapp,
+            'website'  => $this->website,
+        ];
+    }
+}

+ 21 - 0
app/Http/Resources/PartnerAgreementContratoResource.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Carbon\Carbon;
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class PartnerAgreementContratoResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id'             => $this->id,
+            'working_hours'  => $this->working_hours,
+            'contract_start' => $this->contract_start?->format('Y-m-d'),
+            'contract_end'   => $this->contract_end?->format('Y-m-d'),
+            'media'          => $this->whenLoaded('media', fn() => MediaResource::collection($this->media)),
+        ];
+    }
+}

+ 24 - 0
app/Http/Resources/PartnerAgreementDadosResource.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class PartnerAgreementDadosResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id'                  => $this->id,
+            'company_name'        => $this->company_name,
+            'cnpj'                => $this->cnpj,
+            'category_id'         => $this->category_id,
+            'category'            => $this->whenLoaded('category', fn() => new CategoryResource($this->category)),
+            'responsible'         => $this->responsible,
+            'discount_percentage' => $this->discount_percentage,
+            'description'         => $this->description,
+            'logo'                => $this->whenLoaded('logo', fn() => $this->logo ? new MediaResource($this->logo) : null),
+        ];
+    }
+}

+ 23 - 0
app/Http/Resources/PartnerAgreementEnderecoResource.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class PartnerAgreementEnderecoResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id'           => $this->id,
+            'zip_code'     => $this->zip_code,
+            'address'      => $this->address,
+            'neighborhood' => $this->neighborhood,
+            'city_id'      => $this->city_id,
+            'city'         => $this->whenLoaded('city', fn() => new CityResource($this->city)),
+            'state_id'     => $this->state_id,
+            'state'        => $this->whenLoaded('state', fn() => new StateResource($this->state)),
+        ];
+    }
+}

+ 29 - 0
app/Http/Resources/PartnerAgreementListResource.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class PartnerAgreementListResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id'                  => $this->id,
+            'company_name'        => $this->company_name,
+            'cnpj'                => $this->cnpj,
+            'responsible'         => $this->responsible,
+            'email'               => $this->email,
+            'phone'               => $this->phone,
+            'category_id'         => $this->category_id,
+            'category'            => $this->whenLoaded('category', fn() => new CategoryResource($this->category)),
+            'address'             => $this->address,
+            'neighborhood'        => $this->neighborhood,
+            'city'                => $this->whenLoaded('city', fn() => new CityResource($this->city)),
+            'logo'                => $this->whenLoaded('logo', fn() => $this->logo ? ['url' => $this->logo->url] : null),
+            'discount_percentage' => $this->discount_percentage,
+            'contract_end'        => $this->contract_end?->format('Y-m-d'),
+        ];
+    }
+}

+ 2 - 8
app/Http/Resources/StoreItemResource.php

@@ -19,15 +19,9 @@ class StoreItemResource extends JsonResource
             'price'           => $this->price,
             'associate_price' => $this->associate_price,
             'supplier_price'  => $this->supplier_price,
-            'size_s'          => $this->size_s,
-            'stock_s'         => $this->stock_s,
-            'size_m'          => $this->size_m,
-            'stock_m'         => $this->stock_m,
-            'size_l'          => $this->size_l,
-            'stock_l'         => $this->stock_l,
-            'size_xl'         => $this->size_xl,
-            'stock_xl'        => $this->stock_xl,
             'status'          => $this->status,
+            'interests_count' => $this->interests_count ?? 0,
+            'variations'      => $this->whenLoaded('variations', fn() => StoreItemVariationResource::collection($this->variations)),
             'media'           => $this->whenLoaded('media', fn() => MediaResource::collection($this->media)),
             'created_at'      => Carbon::parse($this->created_at)->format('Y-m-d H:i:s'),
             'updated_at'      => Carbon::parse($this->updated_at)->format('Y-m-d H:i:s'),

+ 20 - 0
app/Http/Resources/StoreItemVariationResource.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class StoreItemVariationResource extends JsonResource
+{
+    public function toArray(Request $request): array
+    {
+        return [
+            'id'              => $this->id,
+            'variation_type'  => $this->variation_type,
+            'variation_label' => $this->variation_label,
+            'variation_value' => $this->variation_value,
+            'stock'           => $this->stock ?? 0,
+        ];
+    }
+}

+ 8 - 11
app/Models/StoreItem.php

@@ -17,18 +17,10 @@ class StoreItem extends Model
     protected function casts(): array
     {
         return [
-            'price'          => 'float',
+            'price'           => 'float',
             'associate_price' => 'float',
-            'supplier_price' => 'float',
-            'size_s'         => 'boolean',
-            'size_m'         => 'boolean',
-            'size_l'         => 'boolean',
-            'size_xl'        => 'boolean',
-            'stock_s'        => 'integer',
-            'stock_m'        => 'integer',
-            'stock_l'        => 'integer',
-            'stock_xl'       => 'integer',
-            'status'         => StoreItemStatusEnum::class,
+            'supplier_price'  => 'float',
+            'status'          => StoreItemStatusEnum::class,
         ];
     }
 
@@ -46,4 +38,9 @@ class StoreItem extends Model
     {
         return $this->hasMany(Media::class, 'source_id')->where('source', 'store_item');
     }
+
+    public function variations(): HasMany
+    {
+        return $this->hasMany(StoreItemVariation::class);
+    }
 }

+ 30 - 0
app/Models/StoreItemVariation.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class StoreItemVariation extends Model
+{
+    protected $fillable = [
+        'store_item_id',
+        'variation_type',
+        'variation_label',
+        'variation_value',
+        'stock',
+    ];
+
+    protected function casts(): array
+    {
+        return [
+            'variation_value' => 'float',
+            'stock'           => 'integer',
+        ];
+    }
+
+    public function storeItem(): BelongsTo
+    {
+        return $this->belongsTo(StoreItem::class);
+    }
+}

+ 24 - 3
app/Services/PartnerAgreementService.php

@@ -10,14 +10,14 @@ class PartnerAgreementService
 {
     public function getAll(): Collection
     {
-        return PartnerAgreement::with(['category', 'city', 'state', 'logo'])
+        return PartnerAgreement::with(['category', 'city', 'logo'])
             ->orderBy('company_name')
             ->get();
     }
 
     public function getAllPaginated(array $filters = [], int $perPage = 10): LengthAwarePaginator
     {
-        $query = PartnerAgreement::with(['category', 'city', 'state', 'logo'])
+        $query = PartnerAgreement::with(['category', 'city', 'logo'])
             ->orderBy('company_name');
 
         if (!empty($filters['search'])) {
@@ -47,9 +47,30 @@ class PartnerAgreementService
         return PartnerAgreement::with(['category', 'city', 'state', 'services', 'logo', 'media'])->find($id);
     }
 
+    public function findDados(int $id): ?PartnerAgreement
+    {
+        return PartnerAgreement::with(['category', 'logo'])->find($id);
+    }
+
+    public function findContato(int $id): ?PartnerAgreement
+    {
+        return PartnerAgreement::find($id);
+    }
+
+    public function findEndereco(int $id): ?PartnerAgreement
+    {
+        return PartnerAgreement::with(['city', 'state'])->find($id);
+    }
+
+    public function findContrato(int $id): ?PartnerAgreement
+    {
+        return PartnerAgreement::with(['media'])->find($id);
+    }
+
     public function create(array $data): PartnerAgreement
     {
-        return PartnerAgreement::create($data);
+        $model = PartnerAgreement::create($data);
+        return $model->fresh(['category', 'logo']);
     }
 
     public function update(int $id, array $data): ?PartnerAgreement

+ 96 - 14
app/Services/StoreItemService.php

@@ -4,7 +4,9 @@ namespace App\Services;
 
 use App\Models\StoreItem;
 use App\Models\StoreItemInterest;
+use App\Models\StoreItemVariation;
 use Illuminate\Database\Eloquent\Collection;
+use Illuminate\Support\Arr;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
 
@@ -12,46 +14,92 @@ class StoreItemService
 {
     public function getAll(): Collection
     {
-        return StoreItem::with('category')->orderBy('name')->get();
+        return StoreItem::with(['category', 'media', 'variations'])
+            ->withCount('interests')
+            ->orderBy('name')
+            ->get();
     }
 
     public function findById(int $id): ?StoreItem
     {
-        return StoreItem::with(['category', 'media'])->find($id);
+        return StoreItem::with(['category', 'media', 'variations'])->find($id);
     }
 
     public function create(array $data): StoreItem
     {
-        return StoreItem::create($data);
+        return DB::transaction(function () use ($data) {
+            $variations = $data['variations'] ?? [];
+            $item = StoreItem::create(Arr::except($data, ['variations']));
+            foreach ($variations as $variation) {
+                $item->variations()->create($variation);
+            }
+            return $item->load(['category', 'media', 'variations']);
+        });
     }
 
     public function update(int $id, array $data): ?StoreItem
+    {
+        return DB::transaction(function () use ($id, $data) {
+            $model = StoreItem::findOrFail($id);
+            $variations = array_key_exists('variations', $data) ? $data['variations'] : null;
+            $model->update(Arr::except($data, ['variations']));
+            if (!is_null($variations)) {
+                $model->variations()->delete();
+                foreach ($variations as $variation) {
+                    $model->variations()->create($variation);
+                }
+            }
+            return $model->fresh(['category', 'media', 'variations']);
+        });
+    }
+
+    public function delete(int $id): bool
     {
         $model = StoreItem::find($id);
+        if (!$model) return false;
+        return $model->delete();
+    }
 
-        if (!$model) {
-            return null;
+    public function getAllPaginated(array $filters = [], int $perPage = 10): \Illuminate\Contracts\Pagination\LengthAwarePaginator
+    {
+        $query = StoreItem::with(['category', 'media', 'variations'])
+            ->withCount('interests')
+            ->orderBy('name');
+
+        if (!empty($filters['search'])) {
+            $search = $filters['search'];
+            $query->where('name', 'ilike', "%{$search}%");
+        }
+
+        if (!empty($filters['status'])) {
+            $query->where('status', $filters['status']);
         }
 
-        $model->update($data);
-        return $model->fresh(['category']);
+        if (!empty($filters['category_id'])) {
+            $query->where('category_id', $filters['category_id']);
+        }
+
+        return $query->paginate($perPage);
     }
 
-    public function delete(int $id): bool
+    public function toggleStatus(int $id): ?StoreItem
     {
         $model = StoreItem::find($id);
+        if (!$model) return null;
 
-        if (!$model) {
-            return false;
-        }
+        $model->status = $model->status->value === 'active'
+            ? \App\Enums\StoreItemStatusEnum::INACTIVE
+            : \App\Enums\StoreItemStatusEnum::ACTIVE;
+        $model->save();
 
-        return $model->delete();
+        return $model->fresh(['category', 'media', 'variations']);
     }
 
     public function getMyInterests(): Collection
     {
         $userId = Auth::id();
-        return StoreItem::with('category')
+        return StoreItem::with(['category', 'media', 'variations'])
+            ->withCount('interests')
             ->whereHas('interests', fn($q) => $q->where('user_id', $userId))
             ->orderBy('name')
             ->get();
@@ -60,7 +108,6 @@ class StoreItemService
     public function toggleInterest(int $storeItemId): array
     {
         $userId = Auth::id();
-
         $existing = StoreItemInterest::where('user_id', $userId)
             ->where('store_item_id', $storeItemId)
             ->first();
@@ -73,4 +120,39 @@ class StoreItemService
         StoreItemInterest::create(['user_id' => $userId, 'store_item_id' => $storeItemId]);
         return ['interested' => true];
     }
+
+    public function getInterestsByItem(int $storeItemId): array
+    {
+        return StoreItemInterest::with('user')
+            ->where('store_item_id', $storeItemId)
+            ->get()
+            ->map(fn($interest) => [
+                'id'    => $interest->user?->id,
+                'name'  => $interest->user?->name,
+                'email' => $interest->user?->email,
+            ])
+            ->values()
+            ->toArray();
+    }
+
+    public function addVariation(int $storeItemId, array $data): StoreItemVariation
+    {
+        $item = StoreItem::findOrFail($storeItemId);
+        return $item->variations()->create($data);
+    }
+
+    public function updateVariation(int $storeItemId, int $variationId, array $data): StoreItemVariation
+    {
+        $variation = StoreItemVariation::where('store_item_id', $storeItemId)
+            ->findOrFail($variationId);
+        $variation->update($data);
+        return $variation->fresh();
+    }
+
+    public function deleteVariation(int $storeItemId, int $variationId): void
+    {
+        StoreItemVariation::where('store_item_id', $storeItemId)
+            ->findOrFail($variationId)
+            ->delete();
+    }
 }

+ 26 - 0
database/migrations/2026_05_13_090459_add_colors_to_store_items_table.php

@@ -0,0 +1,26 @@
+<?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('store_items', function (Blueprint $table) {
+            $table->boolean('color_purple')->default(false)->after('stock_xl');
+            $table->boolean('color_white')->default(false)->after('color_purple');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('store_items', function (Blueprint $table) {
+            $table->dropColumn(['color_purple', 'color_white']);
+        });
+    }
+};

+ 33 - 0
database/migrations/2026_05_13_103128_create_store_item_variations_table.php

@@ -0,0 +1,33 @@
+<?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('store_item_variations', function (Blueprint $table) {
+            $table->id();
+            $table->foreignId('store_item_id')->constrained('store_items')->cascadeOnDelete();
+            $table->string('variation_type');
+            $table->string('variation_label');
+            $table->decimal('variation_value', 10, 2)->nullable();
+            $table->timestamps();
+
+            $table->index('store_item_id');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('store_item_variations');
+    }
+};

+ 40 - 0
database/migrations/2026_05_13_103128_drop_old_variation_columns_from_store_items_table.php

@@ -0,0 +1,40 @@
+<?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('store_items', function (Blueprint $table) {
+            $table->dropColumn([
+                'size_s', 'stock_s',
+                'size_m', 'stock_m',
+                'size_l', 'stock_l',
+                'size_xl', 'stock_xl',
+                'color_purple', 'color_white',
+            ]);
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('store_items', function (Blueprint $table) {
+            $table->boolean('size_s')->default(false);
+            $table->integer('stock_s')->default(0);
+            $table->boolean('size_m')->default(false);
+            $table->integer('stock_m')->default(0);
+            $table->boolean('size_l')->default(false);
+            $table->integer('stock_l')->default(0);
+            $table->boolean('size_xl')->default(false);
+            $table->integer('stock_xl')->default(0);
+            $table->boolean('color_purple')->default(false);
+            $table->boolean('color_white')->default(false);
+        });
+    }
+};

+ 22 - 0
database/migrations/2026_05_13_120000_add_stock_to_store_item_variations_table.php

@@ -0,0 +1,22 @@
+<?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('store_item_variations', function (Blueprint $table) {
+            $table->unsignedInteger('stock')->default(0)->after('variation_value');
+        });
+    }
+
+    public function down(): void
+    {
+        Schema::table('store_item_variations', function (Blueprint $table) {
+            $table->dropColumn('stock');
+        });
+    }
+};

+ 27 - 0
database/seeders/CategoryStoreSeeder.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace Database\Seeders;
+
+use App\Models\Category;
+use Illuminate\Database\Seeder;
+
+class CategoryStoreSeeder extends Seeder
+{
+    public function run(): void
+    {
+        $categories = [
+            'Vestuário',
+            'Acessórios',
+            'Papelaria',
+            'Decoração',
+            'Outros',
+        ];
+
+        foreach ($categories as $name) {
+            Category::updateOrCreate(
+                ['name' => $name],
+                ['type' => 'store', 'active' => true],
+            );
+        }
+    }
+}

+ 3 - 1
database/seeders/DatabaseSeeder.php

@@ -18,7 +18,9 @@ class DatabaseSeeder extends Seeder
             BrazilCitiesSeeder::class,
             PositionSeeder::class,
             SectorSeeder::class,
-            CategorySeeder::class,
+            // CategorySeeder::class,
+            CategoryPartnerSeeder::class,
+            CategoryStoreSeeder::class,
         ]);
     }
 }

+ 5 - 0
routes/authRoutes/partner_agreement.php

@@ -10,6 +10,11 @@ Route::controller(PartnerAgreementController::class)->prefix('partner-agreement'
 
     Route::post('/', 'store')->middleware('permission:parceiro.convenio,add');
 
+    Route::get('/{id}/dados',    'showDados')   ->middleware('permission:parceiro.convenio,view');
+    Route::get('/{id}/contato',  'showContato') ->middleware('permission:parceiro.convenio,view');
+    Route::get('/{id}/endereco', 'showEndereco')->middleware('permission:parceiro.convenio,view');
+    Route::get('/{id}/contrato', 'showContrato')->middleware('permission:parceiro.convenio,view');
+
     Route::get('/{id}', 'show')->middleware('permission:parceiro.convenio,view');
 
     Route::put('/{id}', 'update')->middleware('permission:parceiro.convenio,edit');

+ 13 - 1
routes/authRoutes/store_item.php

@@ -4,6 +4,10 @@ use App\Http\Controllers\StoreItemController;
 use Illuminate\Support\Facades\Route;
 
 Route::controller(StoreItemController::class)->prefix('store-item')->group(function () {
+    Route::get('/paginated', 'indexPaginated')->middleware('permission:loja.item,view');
+
+    Route::get('/my/interests', 'myInterests')->middleware('permission:loja.item,view');
+
     Route::get('/', 'index')->middleware('permission:loja.item,view');
 
     Route::post('/', 'store')->middleware('permission:loja.item,add');
@@ -14,7 +18,15 @@ Route::controller(StoreItemController::class)->prefix('store-item')->group(funct
 
     Route::delete('/{id}', 'destroy')->middleware('permission:loja.item,delete');
 
-    Route::get('/my/interests', 'myInterests')->middleware('permission:loja.item,view');
+    Route::patch('/{id}/toggle-status', 'toggleStatus')->middleware('permission:loja.item,edit');
 
     Route::post('/{id}/interest', 'toggleInterest')->middleware('permission:loja.item,view');
+
+    Route::post('/{id}/media', 'uploadMedia')->middleware('permission:loja.item,edit');
+    Route::delete('/{id}/media/{mediaId}', 'deleteMedia')->middleware('permission:loja.item,edit');
+    Route::get('/{id}/interests', 'getInterests')->middleware('permission:loja.item,view');
+
+    Route::post('/{id}/variation', 'addVariation')->middleware('permission:loja.item,edit');
+    Route::patch('/{id}/variation/{variationId}', 'updateVariation')->middleware('permission:loja.item,edit');
+    Route::delete('/{id}/variation/{variationId}', 'deleteVariation')->middleware('permission:loja.item,edit');
 });