499 lines
15 KiB
PHP
499 lines
15 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Gender;
|
|
use App\Models\StoreCategory;
|
|
use App\Repositories\Catalog\CategoryRepository;
|
|
use App\Repositories\Catalog\GenderRepository;
|
|
use App\Repositories\Catalog\ProductRepository;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
class ProductController extends Controller
|
|
{
|
|
public function genders(Request $request)
|
|
{
|
|
$genderRepository = new GenderRepository;
|
|
$genders = $genderRepository->getList([]);
|
|
|
|
// Render gender links HTML
|
|
$genderHtml = '';
|
|
$currentGenderId = $request->input('current_gender');
|
|
|
|
foreach ($genders as $gender) {
|
|
$isActive = $currentGenderId == $gender->id;
|
|
$genderHtml .= '<li class="nav-item mb-1">';
|
|
$genderHtml .= '<a class="nav-link d-block fw-normal p-0 '.($isActive ? 'active text-primary' : '').'" ';
|
|
$genderHtml .= 'href="#" data-gender-id="'.$gender->id.'">';
|
|
$genderHtml .= $gender->name;
|
|
$genderHtml .= '</a></li>';
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'genders' => $genderHtml,
|
|
]);
|
|
}
|
|
|
|
public function categories(Request $request)
|
|
{
|
|
$categoryRepository = new CategoryRepository;
|
|
$categories = $categoryRepository->getList([]);
|
|
|
|
// Render category links HTML
|
|
$categoryHtml = '';
|
|
$currentCategoryId = $request->input('current_category');
|
|
|
|
foreach ($categories as $category) {
|
|
$isActive = $currentCategoryId == $category->id;
|
|
$categoryHtml .= '<li class="nav-item mb-1">';
|
|
$categoryHtml .= '<a class="nav-link d-block fw-normal p-0 '.($isActive ? 'active text-primary' : '').'" ';
|
|
$categoryHtml .= 'href="#" data-category-id="'.$category->id.'">';
|
|
$categoryHtml .= $category->name;
|
|
$categoryHtml .= '</a></li>';
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'categories' => $categoryHtml,
|
|
]);
|
|
}
|
|
|
|
public function ajax(Request $request)
|
|
{
|
|
$limit = 20;
|
|
$page = $request->page ?? 1;
|
|
|
|
$search = $request->search;
|
|
|
|
$filter = $request->filter ?? [];
|
|
$sortBy = $request->sort_by ?? 'relevance';
|
|
|
|
$price_range_start = $request->price_range_start ?? null;
|
|
$price_range_end = $request->price_range_end ?? null;
|
|
|
|
$user = auth()->user();
|
|
$userId = $user ? $user->id : 0;
|
|
[$location_id, $is_consignment] = Cache::remember('employee_user_'.$userId, 60 * 60 * 24, function () use ($user) {
|
|
|
|
if ($user == null) {
|
|
return [10, false];
|
|
}
|
|
|
|
$employee = @$user->employee;
|
|
$location_id = @$employee->location_id;
|
|
$location = @$employee->location;
|
|
$is_consignment = (bool) @$location->is_consignment;
|
|
|
|
return [$location_id, $is_consignment];
|
|
|
|
});
|
|
|
|
$productRepository = new ProductRepository;
|
|
$products = $productRepository->getList([
|
|
'limit' => $page * $limit,
|
|
'sort' => $sortBy,
|
|
'category_id' => $filter['category'] ?? null,
|
|
'gender_id' => $filter['gender'] ?? null,
|
|
'brand_id' => $filter['brand'] ?? null,
|
|
'search' => $search,
|
|
'location_id' => $location_id,
|
|
'is_consignment' => $is_consignment,
|
|
'price_range_start' => $price_range_start,
|
|
'price_range_end' => $price_range_end,
|
|
]);
|
|
|
|
// Check if there are more products
|
|
$hasMore = count($products) >= $limit;
|
|
|
|
// Render product cards HTML
|
|
$productHtml = '';
|
|
if (count($products) == 0) {
|
|
$productHtml = '<div class="col-12">';
|
|
$productHtml .= 'Pencarian tidak ditemukan';
|
|
$productHtml .= '</div>';
|
|
} else {
|
|
foreach ($products as $product) {
|
|
$productHtml .= '<div class="col">';
|
|
$productHtml .= view('components.home.product-card', ['product' => $product])->render();
|
|
$productHtml .= '</div>';
|
|
}
|
|
}
|
|
|
|
// filter
|
|
$filter = $request->filter ?? [];
|
|
if (isset($filter['category']) && $filter['category']) {
|
|
$category = StoreCategory::find($filter['category']);
|
|
|
|
if ($category) {
|
|
$filter['category'] = $category->name;
|
|
} else {
|
|
unset($filter);
|
|
}
|
|
}
|
|
|
|
if (isset($filter['gender']) && $filter['gender']) {
|
|
$gender = Gender::find($filter['gender']);
|
|
|
|
if ($gender) {
|
|
$filter['gender'] = $gender->name;
|
|
} else {
|
|
unset($filter);
|
|
}
|
|
}
|
|
|
|
if (isset($filter['brand']) && $filter['brand']) {
|
|
$brand = \App\Models\Brand::find($filter['brand']);
|
|
|
|
if ($brand) {
|
|
$filter['brand'] = $brand->name;
|
|
} else {
|
|
unset($filter);
|
|
}
|
|
}
|
|
|
|
$filters = $filter;
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'filters' => $filters,
|
|
'products' => $productHtml,
|
|
'count' => count($products),
|
|
'has_more' => $hasMore,
|
|
'current_page' => $page,
|
|
]);
|
|
}
|
|
|
|
public function index(Request $request)
|
|
{
|
|
$productRepository = new ProductRepository;
|
|
$products = [];
|
|
|
|
$filters = [];
|
|
|
|
$min_max_price = $productRepository->getMinMaxPrice();
|
|
|
|
return view('shop.catalog-fashion', [
|
|
|
|
'products' => $products,
|
|
'min_max_price' => $min_max_price,
|
|
]);
|
|
}
|
|
|
|
public function brands(Request $request)
|
|
{
|
|
$brandRepository = new \App\Repositories\Catalog\BrandRepository;
|
|
$brands = $brandRepository->getList([]);
|
|
|
|
// Render brand links HTML
|
|
$brandHtml = '';
|
|
$currentBrandId = $request->input('current_brand');
|
|
|
|
foreach ($brands as $brand) {
|
|
$isActive = $currentBrandId == $brand->id;
|
|
$brandHtml .= '<li class="nav-item mb-1">';
|
|
$brandHtml .= '<a class="nav-link d-block fw-normal p-0 '.($isActive ? 'active text-primary' : '').'" ';
|
|
$brandHtml .= 'href="#" data-brand-id="'.$brand->id.'">';
|
|
$brandHtml .= $brand->name;
|
|
$brandHtml .= '</a></li>';
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'brands' => $brandHtml,
|
|
]);
|
|
}
|
|
|
|
public function brandsWithImages(Request $request)
|
|
{
|
|
$brandRepository = new \App\Repositories\Catalog\BrandRepository;
|
|
$brands = $brandRepository->getList([]);
|
|
|
|
// Render brand links HTML with images as swiper slides
|
|
$brandHtml = '';
|
|
$currentBrandId = $request->input('current_brand');
|
|
|
|
foreach ($brands as $brand) {
|
|
$isActive = $currentBrandId == $brand->id;
|
|
// Only show brands that have images
|
|
if ($brand->image_url) {
|
|
$brandHtml .= '<a class="swiper-slide text-body" href="#!" aria-label="'.$brand->name.'" role="group" style="width: 170.2px; margin-right: 20px;">';
|
|
$brandHtml .= '<img src="'.$brand->image_url.'" alt="'.$brand->name.'" class="me-2" width="100" height="100">';
|
|
$brandHtml .= '</a>';
|
|
}
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'brands' => $brandHtml,
|
|
]);
|
|
}
|
|
|
|
public function announcements(Request $request)
|
|
{
|
|
// Static announcements for now - can be moved to database later
|
|
$announcements = [
|
|
[
|
|
'icon' => '🎉',
|
|
'message' => 'Free Shipping on orders over $250',
|
|
'detail' => "Don't miss a discount!",
|
|
],
|
|
[
|
|
'icon' => '💰',
|
|
'message' => 'Money back guarantee',
|
|
'detail' => 'We return money within 30 days',
|
|
],
|
|
[
|
|
'icon' => '💪',
|
|
'message' => 'Friendly 24/7 customer support',
|
|
'detail' => "We've got you covered!",
|
|
],
|
|
];
|
|
|
|
// Render announcement slides HTML
|
|
$announcementHtml = '';
|
|
foreach ($announcements as $announcement) {
|
|
$announcementHtml .= '<div class="swiper-slide text-truncate text-center">';
|
|
$announcementHtml .= $announcement['icon'].' '.$announcement['message'].' <span class="d-none d-sm-inline">'.$announcement['detail'].'</span>';
|
|
$announcementHtml .= '</div>';
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'announcements' => $announcementHtml,
|
|
]);
|
|
}
|
|
|
|
public function highlights(Request $request)
|
|
{
|
|
$type = $request->input('type', 'new');
|
|
$limit = 8;
|
|
|
|
$user = auth()->user();
|
|
$userId = $user ? $user->id : 0;
|
|
[$location_id, $is_consignment] = Cache::remember('employee_user_'.$userId, 60 * 60 * 24, function () use ($user) {
|
|
|
|
if ($user == null) {
|
|
return [10, false];
|
|
}
|
|
|
|
$employee = @$user->employee;
|
|
$location_id = @$employee->location_id;
|
|
$location = @$employee->location;
|
|
$is_consignment = (bool) @$location->is_consignment;
|
|
|
|
return [$location_id, $is_consignment];
|
|
|
|
});
|
|
|
|
$productRepository = new ProductRepository;
|
|
|
|
// Set parameters based on type
|
|
$params = [
|
|
'limit' => $limit,
|
|
'location_id' => $location_id,
|
|
'is_consignment' => $is_consignment,
|
|
];
|
|
|
|
switch ($type) {
|
|
case 'best_sellers':
|
|
$params['sort'] = 'random';
|
|
break;
|
|
case 'new_arrivals':
|
|
$params['sort'] = 'new';
|
|
break;
|
|
case 'sale_items':
|
|
$params['event'] = 'special-offer';
|
|
break;
|
|
case 'top_rated':
|
|
$params['sort'] = 'random';
|
|
break;
|
|
default:
|
|
$params['sort'] = 'new';
|
|
break;
|
|
}
|
|
|
|
$params['limit'] = 10;
|
|
|
|
$products = $productRepository->getList($params);
|
|
|
|
// Render product cards HTML
|
|
$productHtml = '';
|
|
if (count($products) == 0) {
|
|
$productHtml = '<div class="col-12 text-center py-4">';
|
|
$productHtml .= 'No products found';
|
|
$productHtml .= '</div>';
|
|
} else {
|
|
foreach ($products as $product) {
|
|
$productHtml .= '<div class="col">';
|
|
$productHtml .= view('components.home.product-card', ['product' => $product])->render();
|
|
$productHtml .= '</div>';
|
|
}
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'products' => $productHtml,
|
|
'count' => count($products),
|
|
'type' => $type,
|
|
]);
|
|
}
|
|
|
|
public function populers(Request $request)
|
|
{
|
|
$type = $request->input('type', 'new');
|
|
$limit = 6;
|
|
|
|
$user = auth()->user();
|
|
$userId = $user ? $user->id : 0;
|
|
[$location_id, $is_consignment] = Cache::remember('employee_user_'.$userId, 60 * 60 * 24, function () use ($user) {
|
|
|
|
if ($user == null) {
|
|
return [10, false];
|
|
}
|
|
|
|
$employee = @$user->employee;
|
|
$location_id = @$employee->location_id;
|
|
$location = @$employee->location;
|
|
$is_consignment = (bool) @$location->is_consignment;
|
|
|
|
return [$location_id, $is_consignment];
|
|
|
|
});
|
|
|
|
$productRepository = new ProductRepository;
|
|
|
|
// Set parameters based on type
|
|
$params = [
|
|
'limit' => $limit,
|
|
'location_id' => $location_id,
|
|
'is_consignment' => $is_consignment,
|
|
];
|
|
|
|
switch ($type) {
|
|
case 'new':
|
|
$params['sort'] = 'new';
|
|
break;
|
|
case 'best_sellers':
|
|
$params['sort'] = 'best_sellers';
|
|
break;
|
|
case 'special-offer':
|
|
$params['event'] = 'special-offer';
|
|
break;
|
|
case 'top_rated':
|
|
$params['sort'] = 'random';
|
|
break;
|
|
default:
|
|
$params['sort'] = 'new';
|
|
break;
|
|
}
|
|
|
|
$products = $productRepository->getList($params);
|
|
|
|
// Render product cards HTML
|
|
$productHtml = '';
|
|
if (count($products) == 0) {
|
|
$productHtml = '<div class="col-12 text-center py-4">';
|
|
$productHtml .= 'No products found';
|
|
$productHtml .= '</div>';
|
|
} else {
|
|
foreach ($products as $product) {
|
|
$productHtml .= '<div class="col">';
|
|
$productHtml .= view('components.home.product-card', ['product' => $product])->render();
|
|
$productHtml .= '</div>';
|
|
}
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'products' => $productHtml,
|
|
'count' => count($products),
|
|
'type' => $type,
|
|
]);
|
|
}
|
|
|
|
public function populersJson(Request $request)
|
|
{
|
|
$type = $request->input('type', 'new');
|
|
$limit = 6;
|
|
|
|
$user = auth()->user();
|
|
$userId = $user ? $user->id : 0;
|
|
[$location_id, $is_consignment] = Cache::remember('employee_user_'.$userId, 60 * 60 * 24, function () use ($user) {
|
|
|
|
if ($user == null) {
|
|
return [10, false];
|
|
}
|
|
|
|
$employee = @$user->employee;
|
|
$location_id = @$employee->location_id;
|
|
$location = @$employee->location;
|
|
$is_consignment = (bool) @$location->is_consignment;
|
|
|
|
return [$location_id, $is_consignment];
|
|
|
|
});
|
|
|
|
$productRepository = new ProductRepository;
|
|
|
|
// Set parameters based on type
|
|
$params = [
|
|
'limit' => $limit,
|
|
'location_id' => $location_id,
|
|
'is_consignment' => $is_consignment,
|
|
];
|
|
|
|
switch ($type) {
|
|
case 'new':
|
|
$params['sort'] = 'new';
|
|
break;
|
|
case 'best_sellers':
|
|
$params['sort'] = 'best_sellers';
|
|
break;
|
|
case 'special-offer':
|
|
$params['event'] = 'special-offer';
|
|
break;
|
|
case 'top_rated':
|
|
$params['sort'] = 'random';
|
|
break;
|
|
default:
|
|
$params['sort'] = 'new';
|
|
break;
|
|
}
|
|
|
|
$params['limit'] = 10;
|
|
|
|
$products = $productRepository->getList($params);
|
|
|
|
|
|
$p = $products->map(function($row){
|
|
$row->image_url = $row->image_url;
|
|
return $row;
|
|
});
|
|
|
|
return response()->json([
|
|
'data' =>$p,
|
|
]);
|
|
}
|
|
|
|
public function detail($slug, Request $request, ProductRepository $productRepository)
|
|
{
|
|
|
|
$product = $productRepository->show($slug);
|
|
|
|
$complete_look_products_data = $productRepository->getList([
|
|
'category_id' => $product->category1_id,
|
|
'limit' => 4,
|
|
]);
|
|
|
|
$complete_look_products = collect($complete_look_products_data->items())->chunk(2);
|
|
|
|
return view('shop.product-fashion', [
|
|
'product' => $product,
|
|
'complete_look_products' => $complete_look_products,
|
|
|
|
]);
|
|
}
|
|
}
|