use App\Constants\ExtensionConst; use Illuminate\Support\Facades\DB; use App\Constants\LanguageConst; use Exception; use Illuminate\Support\Str; use Illuminate\Http\Request; use App\Models\Admin\Language; use App\Models\Admin\UsefulLink; use App\Models\Admin\SiteSections; use App\Models\Frontend\Subscribe; use App\Constants\SiteSectionConst; use App\Http\Controllers\Controller; use App\Models\Admin\AppSettings; use App\Models\Admin\BasicSettings; use App\Models\Admin\InvestmentPlan; use App\Models\Admin\Package; use App\Models\Admin\SetupPage; use App\Models\Frontend\Announcement; use App\Models\Frontend\AnnouncementCategory; use App\Models\Frontend\ContactRequest; use App\Models\Frontend\FrontendHeaderSection; use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Validator; use App\Providers\Admin\BasicSettingsProvider; use App\Providers\Admin\ExtensionProvider; class IndexController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $page_section = SetupPage::where('slug','home')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); $default = get_default_language_code(); return view('frontend.pages.index',compact('site_name','page_title','page_section','footer','default')); } public function aboutUs(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('About Us'); $page_section = SetupPage::where('slug','about-us')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.about-us',compact('site_name', 'page_title', 'page_section', 'footer')); } public function pricing(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Pricing'); $page_section = SetupPage::where('slug','pricing')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.pricing',compact('site_name','page_title', 'page_section', 'footer')); } public function blog(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Announcement'); $page_section = SetupPage::where('slug','announcement')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.blog',compact('site_name','page_title', 'page_section', 'footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function blogDetail(BasicSettingsProvider $basic_settings, $id) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $blog_categories = AnnouncementCategory::get(); $blog = Announcement::where('id', $id)->first(); $recent_blogs = Announcement::latest()->get(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.blog-details', compact('site_name', 'page_title', 'blog_categories', 'blog', 'recent_blogs', 'footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function categoryBlog(BasicSettingsProvider $basic_settings, $id) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $blog_categories = AnnouncementCategory::get(); $blogs = Announcement::where('announcement_category_id', $id)->latest()->get(); $recent_blogs = Announcement::latest()->get(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.category-blog', compact('site_name', 'page_title', 'blog_categories', 'blogs', 'recent_blogs', 'footer')); } public function service(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Services'); $page_section = SetupPage::where('slug','services')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.service',compact('site_name','page_title','page_section','footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function contact(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Help'); $contact_slug = Str::slug(SiteSectionConst::CONTACT_US_SECTION); $contact = SiteSections::getData($contact_slug)->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.contact', compact('site_name', 'page_title', 'contact','footer')); } public function subscribe(Request $request) { $extension = ExtensionProvider::get()->where('slug', ExtensionConst::GOOGLE_RECAPTCHA_SLUG)->first(); $captcha_rules = 'nullable'; if ($extension && $extension->status == true) { $captcha_rules = 'required|string|g_recaptcha_verify'; } $validator = Validator::make($request->all(),[ 'email' => "required|string|email|max:255|unique:subscribes", 'g-recaptcha-response' => $captcha_rules, ]); if($validator->fails()) return redirect('/#subscribe-form')->withErrors($validator)->withInput(); $validated = $validator->validated(); try{ Subscribe::create([ 'email' => $validated['email'], 'created_at' => now(), ]); }catch(Exception $e) { return redirect('/#subscribe-form')->with(['error' => ['Failed to subscribe. Try again']]); } return redirect(url()->previous() .'/#subscribe-form')->with(['success' => ['Subscription successful!']]); } public function contactMessageSend(Request $request) { $extension = ExtensionProvider::get()->where('slug', ExtensionConst::GOOGLE_RECAPTCHA_SLUG)->first(); $captcha_rules = 'nullable'; if ($extension && $extension->status == true) { $captcha_rules = 'required|string|g_recaptcha_verify'; } $validated = Validator::make($request->all(),[ 'name' => "required|string|max:255", 'email' => "required|email|string|max:255", 'message' => "required|string|max:5000", 'g-recaptcha-response' => $captcha_rules, ])->validate(); try{ ContactRequest::create($validated); }catch(Exception $e) { return back()->with(['error' => ['Failed to send message. Please Try again']]); } return back()->with(['success' => ['Message send successfully!']]); } public function usefulLink($slug) { $useful_link = UsefulLink::where("slug",$slug)->first(); if(!$useful_link) abort(404); $basic_settings = BasicSettingsProvider::get(); $app_local = get_default_language_code(); $page_title = $useful_link->title?->language?->$app_local?->title ?? $basic_settings->site_name; // return view('frontend.pages.useful-link',compact('page_title','useful_link')); } public function languageSwitch(Request $request) { $code = $request->target; $language = Language::where("code",$code)->first(); if(!$language) { return back()->with(['error' => ['Oops! Language Not Found!']]); } Session::put('local',$code); Session::put('local_dir',$language->dir); return back()->with(['success' => ['Language Switch to ' . $language->name ]]); } public function usefulPage($slug){ $page = UsefulLink::where('slug', $slug)->where('status', 1)->first(); $basic_settings = BasicSettings::first(); $site_name = $basic_settings->site_name; $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); if(empty($page)){ abort(404); } return view('frontend.pages.usefull_pages',compact('page',"site_name",'footer')); } public function boutique(){ $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); $page_title = "Julie Store and Boutique"; return view("frontend.pages.boutique", compact("page_title", "footer")); } public function headerPage($parent_id){ $selected_lan = get_default_language_code(); $system_default = LanguageConst::NOT_REMOVABLE; $parent = FrontendHeaderSection::where('id',$parent_id)->where('status',1)->first(); if( $parent == null) return back()->with(['error' => [__("The page content is currently empty.")]]); $page_content = $parent->singlePageContent($parent->id); $faq_content = $parent->singleFaqContent($parent->id); $page_title = $parent->title?->language?->$selected_lan?->title ?? $parent->title?->language?->$system_default?->title; $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); return view('frontend.pages.header-section',compact('page_title','parent','page_content','faq_content','footer')); } public function boutiqueProduct($id){ $product = DB::table('jsb_products')->where('id',$id)->where('is_active',1)->first(); if(!$product) abort(404); $images = DB::table('jsb_product_images')->where('product_id',$id)->get(); $variants = DB::table('jsb_product_variants')->where('product_id',$id)->get(); $sizes = $variants->pluck('size')->unique()->filter()->values(); $colors = $variants->pluck('color')->unique()->filter()->values(); return view('frontend.pages.boutique-product', compact('product','images','variants','sizes','colors')); } public function boutiqueCart(){ $cart = session('jsb_cart',[]); $items = []; $total = 0; foreach($cart as $key=>$item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $image = DB::table('jsb_product_images')->where('product_id',$product->id)->where('is_main',1)->first(); $items[] = [ 'key' => $key, 'product' => $product, 'image' => $image, 'variant' => $item['variant'] ?? null, 'quantity' => $item['quantity'], 'subtotal' => $product->price * $item['quantity'], ]; $total += $product->price * $item['quantity']; } } return view('frontend.pages.boutique-cart', compact('items','total')); } public function boutiqueCartAdd(Request $request){ $product = DB::table('jsb_products')->find($request->product_id); if(!$product) return back()->with('error','Produit introuvable'); $cart = session('jsb_cart',[]); $key = $request->product_id.'-'.($request->variant_id ?? '0'); if(isset($cart[$key])){ $cart[$key]['quantity'] += $request->quantity ?? 1; } else { $cart[$key] = [ 'product_id' => $request->product_id, 'variant_id' => $request->variant_id, 'variant' => $request->variant_info, 'quantity' => $request->quantity ?? 1, ]; } session()->put('jsb_cart', $cart); session()->save(); return redirect()->route('frontend.boutique.cart')->with('success','Produit ajouté au panier!'); } public function boutiqueCartRemove(Request $request){ $cart = session('jsb_cart',[]); unset($cart[$request->key]); session()->put('jsb_cart', $cart); session()->save(); return back()->with('success','Produit retiré du panier.'); } public function boutiqueCartQty(Request $request){ $cart = session('jsb_cart',[]); if(isset($cart[$request->key])){ $cart[$request->key]['quantity'] = max(1, intval($request->quantity)); } session()->put('jsb_cart', $cart); session()->save(); return back(); } public function boutiqueCheckout(){ $cart = session('jsb_cart',[]); if(empty($cart)) return redirect()->route('frontend.boutique.cart'); if(!auth()->check()) return redirect()->route('user.login')->with('error','Connectez-vous pour commander.'); $items = []; $subtotal = 0; foreach($cart as $key=>$item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $image = DB::table('jsb_product_images')->where('product_id',$product->id)->where('is_main',1)->first(); $items[] = ['product'=>$product,'image'=>$image,'variant'=>$item['variant']??null,'quantity'=>$item['quantity'],'subtotal'=>$product->price*$item['quantity']]; $subtotal += $product->price * $item['quantity']; } } $zones = DB::table('jsb_delivery_zones')->where('is_active',1)->orderBy('city')->get(); $user = auth()->user(); $wallet = DB::table('user_wallets')->where('user_id',$user->id)->first(); $balance = $wallet->balance ?? 0; return view('frontend.pages.boutique-checkout', compact('items','subtotal','zones','user','balance')); } public function boutiqueCheckoutConfirm(Request $request){ if(!auth()->check()) return redirect()->route('user.login'); $cart = session('jsb_cart',[]); if(empty($cart)) return redirect()->route('frontend.boutique'); $request->validate([ 'delivery_city' => 'required|string', 'delivery_address' => 'required|string', 'delivery_phone' => 'required|string', ]); $user = auth()->user(); $wallet = DB::table('user_wallets')->where('user_id',$user->id)->first(); $balance = $wallet->balance ?? 0; $zone = DB::table('jsb_delivery_zones')->where('city',$request->delivery_city)->first(); $delivery_amount = $zone ? $zone->price : 0; $subtotal = 0; $items_data = []; foreach($cart as $item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $subtotal += $product->price * $item['quantity']; $items_data[] = ['product'=>$product,'item'=>$item]; } } $total = $subtotal + $delivery_amount; $commission_pct = DB::table('jsb_settings')->where('key','commission_percent')->first()->value ?? 5; $commission = $subtotal * $commission_pct / 100; $cherline_amount = $subtotal - $commission + $delivery_amount; if($balance < $total){ return back()->with('error','Solde insuffisant. Votre solde: $'.number_format($balance,2).' — Total: $'.number_format($total,2)); } // Debit balance DB::table('user_wallets')->where('user_id',$user->id)->decrement('balance', $total); // Create order $ref = 'JSB-'.strtoupper(substr(md5(time().$user->id),0,8)); $order_id = DB::table('jsb_orders')->insertGetId([ 'order_ref' => $ref, 'user_id' => $user->id, 'total_amount' => $total, 'delivery_amount' => $delivery_amount, 'commission_amount' => $commission, 'cherline_amount' => $cherline_amount, 'delivery_city' => $request->delivery_city, 'delivery_address' => $request->delivery_address, 'delivery_phone' => $request->delivery_phone, 'status' => 'pending', 'notes' => $request->notes, 'created_at' => now(), 'updated_at' => now(), ]); foreach($items_data as $data){ DB::table('jsb_order_items')->insert([ 'order_id' => $order_id, 'product_id' => $data['product']->id, 'product_name' => $data['product']->name, 'variant_info' => $data['item']['variant'] ?? null, 'quantity' => $data['item']['quantity'], 'unit_price' => $data['product']->price, 'created_at' => now(), 'updated_at' => now(), ]); // Update stock DB::table('jsb_product_variants')->where('product_id',$data['product']->id)->decrement('stock', $data['item']['quantity']); } // Transfer to Cherline $cherline_id = DB::table('jsb_settings')->where('key','cherline_user_id')->first()->value ?? 21; DB::table('user_wallets')->where('user_id',$cherline_id)->increment('balance', $cherline_amount); session()->forget('jsb_cart'); // Voye email konfirmasyon try { $order_obj = DB::table('jsb_orders')->where('order_ref',$ref)->first(); $items_email = []; foreach($items_data as $data) { $obj = (object)[ 'product_name' => $data['product']->name, 'variant_info' => $data['item']['variant'] ?? null, 'quantity' => $data['item']['quantity'], 'unit_price' => $data['product']->price, 'image_path' => DB::table('jsb_product_images')->where('product_id',$data['product']->id)->where('is_main',1)->value('image_path'), ]; $items_email[] = $obj; } Mail::to($user->email)->send(new OrderNotification($order_obj, $items_email, 'pending')); } catch(\Exception $e) { \Illuminate\Support\Facades\Log::error('Order email error: '.$e->getMessage()); } return redirect()->route('frontend.boutique.order.success', $ref); } public function boutiqueOrderSuccess($ref){ $order = DB::table('jsb_orders')->where('order_ref',$ref)->first(); if(!$order) abort(404); $items = DB::table('jsb_order_items')->where('order_id',$order->id)->get(); return view('frontend.pages.boutique-order-success', compact('order','items')); } public function boutiqueMyOrders(){ if(!auth()->check()) return redirect()->route('user.login'); $orders = DB::table('jsb_orders')->where('user_id',auth()->id())->orderBy('created_at','desc')->get(); return view('frontend.pages.boutique-my-orders', compact('orders')); } public function boutiquePage($slug){ $page = DB::table('jsb_pages')->where('slug',$slug)->first(); if(!$page) abort(404); return view('frontend.pages.boutique-page', compact('page')); } public function boutiqueTracking(){ $order = null; $items = []; if(request('ref')) { $order = DB::table('jsb_orders')->where('order_ref', request('ref'))->first(); if($order) { $items_raw = DB::table('jsb_order_items')->where('order_id',$order->id)->get(); foreach($items_raw as $item) { $img = DB::table('jsb_product_images')->where('product_id',$item->product_id)->where('is_main',1)->first(); $item->image_path = $img->image_path ?? null; $items[] = $item; } } } return view('frontend.pages.boutique-tracking', compact('order','items')); } public function boutiqueChatMessage(Request $request) { DB::table('jsb_chat_messages')->insert([ 'option_chosen' => $request->option ?? null, 'message' => $request->message ?? '', 'user_id' => auth()->id() ?? null, 'ip' => $request->ip(), 'created_at' => now(), ]); return response()->json(['status'=>'ok']); } } use App\Constants\ExtensionConst; use Illuminate\Support\Facades\DB; use App\Constants\LanguageConst; use Exception; use Illuminate\Support\Str; use Illuminate\Http\Request; use App\Models\Admin\Language; use App\Models\Admin\UsefulLink; use App\Models\Admin\SiteSections; use App\Models\Frontend\Subscribe; use App\Constants\SiteSectionConst; use App\Http\Controllers\Controller; use App\Models\Admin\AppSettings; use App\Models\Admin\BasicSettings; use App\Models\Admin\InvestmentPlan; use App\Models\Admin\Package; use App\Models\Admin\SetupPage; use App\Models\Frontend\Announcement; use App\Models\Frontend\AnnouncementCategory; use App\Models\Frontend\ContactRequest; use App\Models\Frontend\FrontendHeaderSection; use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Validator; use App\Providers\Admin\BasicSettingsProvider; use App\Providers\Admin\ExtensionProvider; class IndexController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $page_section = SetupPage::where('slug','home')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); $default = get_default_language_code(); return view('frontend.pages.index',compact('site_name','page_title','page_section','footer','default')); } public function aboutUs(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('About Us'); $page_section = SetupPage::where('slug','about-us')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.about-us',compact('site_name', 'page_title', 'page_section', 'footer')); } public function pricing(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Pricing'); $page_section = SetupPage::where('slug','pricing')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.pricing',compact('site_name','page_title', 'page_section', 'footer')); } public function blog(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Announcement'); $page_section = SetupPage::where('slug','announcement')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.blog',compact('site_name','page_title', 'page_section', 'footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function blogDetail(BasicSettingsProvider $basic_settings, $id) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $blog_categories = AnnouncementCategory::get(); $blog = Announcement::where('id', $id)->first(); $recent_blogs = Announcement::latest()->get(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.blog-details', compact('site_name', 'page_title', 'blog_categories', 'blog', 'recent_blogs', 'footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function categoryBlog(BasicSettingsProvider $basic_settings, $id) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $blog_categories = AnnouncementCategory::get(); $blogs = Announcement::where('announcement_category_id', $id)->latest()->get(); $recent_blogs = Announcement::latest()->get(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.category-blog', compact('site_name', 'page_title', 'blog_categories', 'blogs', 'recent_blogs', 'footer')); } public function service(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Services'); $page_section = SetupPage::where('slug','services')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.service',compact('site_name','page_title','page_section','footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function contact(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Help'); $contact_slug = Str::slug(SiteSectionConst::CONTACT_US_SECTION); $contact = SiteSections::getData($contact_slug)->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.contact', compact('site_name', 'page_title', 'contact','footer')); } public function subscribe(Request $request) { $extension = ExtensionProvider::get()->where('slug', ExtensionConst::GOOGLE_RECAPTCHA_SLUG)->first(); $captcha_rules = 'nullable'; if ($extension && $extension->status == true) { $captcha_rules = 'required|string|g_recaptcha_verify'; } $validator = Validator::make($request->all(),[ 'email' => "required|string|email|max:255|unique:subscribes", 'g-recaptcha-response' => $captcha_rules, ]); if($validator->fails()) return redirect('/#subscribe-form')->withErrors($validator)->withInput(); $validated = $validator->validated(); try{ Subscribe::create([ 'email' => $validated['email'], 'created_at' => now(), ]); }catch(Exception $e) { return redirect('/#subscribe-form')->with(['error' => ['Failed to subscribe. Try again']]); } return redirect(url()->previous() .'/#subscribe-form')->with(['success' => ['Subscription successful!']]); } public function contactMessageSend(Request $request) { $extension = ExtensionProvider::get()->where('slug', ExtensionConst::GOOGLE_RECAPTCHA_SLUG)->first(); $captcha_rules = 'nullable'; if ($extension && $extension->status == true) { $captcha_rules = 'required|string|g_recaptcha_verify'; } $validated = Validator::make($request->all(),[ 'name' => "required|string|max:255", 'email' => "required|email|string|max:255", 'message' => "required|string|max:5000", 'g-recaptcha-response' => $captcha_rules, ])->validate(); try{ ContactRequest::create($validated); }catch(Exception $e) { return back()->with(['error' => ['Failed to send message. Please Try again']]); } return back()->with(['success' => ['Message send successfully!']]); } public function usefulLink($slug) { $useful_link = UsefulLink::where("slug",$slug)->first(); if(!$useful_link) abort(404); $basic_settings = BasicSettingsProvider::get(); $app_local = get_default_language_code(); $page_title = $useful_link->title?->language?->$app_local?->title ?? $basic_settings->site_name; // return view('frontend.pages.useful-link',compact('page_title','useful_link')); } public function languageSwitch(Request $request) { $code = $request->target; $language = Language::where("code",$code)->first(); if(!$language) { return back()->with(['error' => ['Oops! Language Not Found!']]); } Session::put('local',$code); Session::put('local_dir',$language->dir); return back()->with(['success' => ['Language Switch to ' . $language->name ]]); } public function usefulPage($slug){ $page = UsefulLink::where('slug', $slug)->where('status', 1)->first(); $basic_settings = BasicSettings::first(); $site_name = $basic_settings->site_name; $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); if(empty($page)){ abort(404); } return view('frontend.pages.usefull_pages',compact('page',"site_name",'footer')); } public function boutique(){ $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); $page_title = "Julie Store and Boutique"; return view("frontend.pages.boutique", compact("page_title", "footer")); } public function headerPage($parent_id){ $selected_lan = get_default_language_code(); $system_default = LanguageConst::NOT_REMOVABLE; $parent = FrontendHeaderSection::where('id',$parent_id)->where('status',1)->first(); if( $parent == null) return back()->with(['error' => [__("The page content is currently empty.")]]); $page_content = $parent->singlePageContent($parent->id); $faq_content = $parent->singleFaqContent($parent->id); $page_title = $parent->title?->language?->$selected_lan?->title ?? $parent->title?->language?->$system_default?->title; $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); return view('frontend.pages.header-section',compact('page_title','parent','page_content','faq_content','footer')); } public function boutiqueProduct($id){ $product = DB::table('jsb_products')->where('id',$id)->where('is_active',1)->first(); if(!$product) abort(404); $images = DB::table('jsb_product_images')->where('product_id',$id)->get(); $variants = DB::table('jsb_product_variants')->where('product_id',$id)->get(); $sizes = $variants->pluck('size')->unique()->filter()->values(); $colors = $variants->pluck('color')->unique()->filter()->values(); return view('frontend.pages.boutique-product', compact('product','images','variants','sizes','colors')); } public function boutiqueCart(){ $cart = session('jsb_cart',[]); $items = []; $total = 0; foreach($cart as $key=>$item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $image = DB::table('jsb_product_images')->where('product_id',$product->id)->where('is_main',1)->first(); $items[] = [ 'key' => $key, 'product' => $product, 'image' => $image, 'variant' => $item['variant'] ?? null, 'quantity' => $item['quantity'], 'subtotal' => $product->price * $item['quantity'], ]; $total += $product->price * $item['quantity']; } } return view('frontend.pages.boutique-cart', compact('items','total')); } public function boutiqueCartAdd(Request $request){ $product = DB::table('jsb_products')->find($request->product_id); if(!$product) return back()->with('error','Produit introuvable'); $cart = session('jsb_cart',[]); $key = $request->product_id.'-'.($request->variant_id ?? '0'); if(isset($cart[$key])){ $cart[$key]['quantity'] += $request->quantity ?? 1; } else { $cart[$key] = [ 'product_id' => $request->product_id, 'variant_id' => $request->variant_id, 'variant' => $request->variant_info, 'quantity' => $request->quantity ?? 1, ]; } session()->put('jsb_cart', $cart); session()->save(); return redirect()->route('frontend.boutique.cart')->with('success','Produit ajouté au panier!'); } public function boutiqueCartRemove(Request $request){ $cart = session('jsb_cart',[]); unset($cart[$request->key]); session()->put('jsb_cart', $cart); session()->save(); return back()->with('success','Produit retiré du panier.'); } public function boutiqueCartQty(Request $request){ $cart = session('jsb_cart',[]); if(isset($cart[$request->key])){ $cart[$request->key]['quantity'] = max(1, intval($request->quantity)); } session()->put('jsb_cart', $cart); session()->save(); return back(); } public function boutiqueCheckout(){ $cart = session('jsb_cart',[]); if(empty($cart)) return redirect()->route('frontend.boutique.cart'); if(!auth()->check()) return redirect()->route('user.login')->with('error','Connectez-vous pour commander.'); $items = []; $subtotal = 0; foreach($cart as $key=>$item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $image = DB::table('jsb_product_images')->where('product_id',$product->id)->where('is_main',1)->first(); $items[] = ['product'=>$product,'image'=>$image,'variant'=>$item['variant']??null,'quantity'=>$item['quantity'],'subtotal'=>$product->price*$item['quantity']]; $subtotal += $product->price * $item['quantity']; } } $zones = DB::table('jsb_delivery_zones')->where('is_active',1)->orderBy('city')->get(); $user = auth()->user(); $wallet = DB::table('user_wallets')->where('user_id',$user->id)->first(); $balance = $wallet->balance ?? 0; return view('frontend.pages.boutique-checkout', compact('items','subtotal','zones','user','balance')); } public function boutiqueCheckoutConfirm(Request $request){ if(!auth()->check()) return redirect()->route('user.login'); $cart = session('jsb_cart',[]); if(empty($cart)) return redirect()->route('frontend.boutique'); $request->validate([ 'delivery_city' => 'required|string', 'delivery_address' => 'required|string', 'delivery_phone' => 'required|string', ]); $user = auth()->user(); $wallet = DB::table('user_wallets')->where('user_id',$user->id)->first(); $balance = $wallet->balance ?? 0; $zone = DB::table('jsb_delivery_zones')->where('city',$request->delivery_city)->first(); $delivery_amount = $zone ? $zone->price : 0; $subtotal = 0; $items_data = []; foreach($cart as $item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $subtotal += $product->price * $item['quantity']; $items_data[] = ['product'=>$product,'item'=>$item]; } } $total = $subtotal + $delivery_amount; $commission_pct = DB::table('jsb_settings')->where('key','commission_percent')->first()->value ?? 5; $commission = $subtotal * $commission_pct / 100; $cherline_amount = $subtotal - $commission + $delivery_amount; if($balance < $total){ return back()->with('error','Solde insuffisant. Votre solde: $'.number_format($balance,2).' — Total: $'.number_format($total,2)); } // Debit balance DB::table('user_wallets')->where('user_id',$user->id)->decrement('balance', $total); // Create order $ref = 'JSB-'.strtoupper(substr(md5(time().$user->id),0,8)); $order_id = DB::table('jsb_orders')->insertGetId([ 'order_ref' => $ref, 'user_id' => $user->id, 'total_amount' => $total, 'delivery_amount' => $delivery_amount, 'commission_amount' => $commission, 'cherline_amount' => $cherline_amount, 'delivery_city' => $request->delivery_city, 'delivery_address' => $request->delivery_address, 'delivery_phone' => $request->delivery_phone, 'status' => 'pending', 'notes' => $request->notes, 'created_at' => now(), 'updated_at' => now(), ]); foreach($items_data as $data){ DB::table('jsb_order_items')->insert([ 'order_id' => $order_id, 'product_id' => $data['product']->id, 'product_name' => $data['product']->name, 'variant_info' => $data['item']['variant'] ?? null, 'quantity' => $data['item']['quantity'], 'unit_price' => $data['product']->price, 'created_at' => now(), 'updated_at' => now(), ]); // Update stock DB::table('jsb_product_variants')->where('product_id',$data['product']->id)->decrement('stock', $data['item']['quantity']); } // Transfer to Cherline $cherline_id = DB::table('jsb_settings')->where('key','cherline_user_id')->first()->value ?? 21; DB::table('user_wallets')->where('user_id',$cherline_id)->increment('balance', $cherline_amount); session()->forget('jsb_cart'); // Voye email konfirmasyon try { $order_obj = DB::table('jsb_orders')->where('order_ref',$ref)->first(); $items_email = []; foreach($items_data as $data) { $obj = (object)[ 'product_name' => $data['product']->name, 'variant_info' => $data['item']['variant'] ?? null, 'quantity' => $data['item']['quantity'], 'unit_price' => $data['product']->price, 'image_path' => DB::table('jsb_product_images')->where('product_id',$data['product']->id)->where('is_main',1)->value('image_path'), ]; $items_email[] = $obj; } Mail::to($user->email)->send(new OrderNotification($order_obj, $items_email, 'pending')); } catch(\Exception $e) { \Illuminate\Support\Facades\Log::error('Order email error: '.$e->getMessage()); } return redirect()->route('frontend.boutique.order.success', $ref); } public function boutiqueOrderSuccess($ref){ $order = DB::table('jsb_orders')->where('order_ref',$ref)->first(); if(!$order) abort(404); $items = DB::table('jsb_order_items')->where('order_id',$order->id)->get(); return view('frontend.pages.boutique-order-success', compact('order','items')); } public function boutiqueMyOrders(){ if(!auth()->check()) return redirect()->route('user.login'); $orders = DB::table('jsb_orders')->where('user_id',auth()->id())->orderBy('created_at','desc')->get(); return view('frontend.pages.boutique-my-orders', compact('orders')); } public function boutiquePage($slug){ $page = DB::table('jsb_pages')->where('slug',$slug)->first(); if(!$page) abort(404); return view('frontend.pages.boutique-page', compact('page')); } public function boutiqueTracking(){ $order = null; $items = []; if(request('ref')) { $order = DB::table('jsb_orders')->where('order_ref', request('ref'))->first(); if($order) { $items_raw = DB::table('jsb_order_items')->where('order_id',$order->id)->get(); foreach($items_raw as $item) { $img = DB::table('jsb_product_images')->where('product_id',$item->product_id)->where('is_main',1)->first(); $item->image_path = $img->image_path ?? null; $items[] = $item; } } } return view('frontend.pages.boutique-tracking', compact('order','items')); } public function boutiqueChatMessage(Request $request) { DB::table('jsb_chat_messages')->insert([ 'option_chosen' => $request->option ?? null, 'message' => $request->message ?? '', 'user_id' => auth()->id() ?? null, 'ip' => $request->ip(), 'created_at' => now(), ]); return response()->json(['status'=>'ok']); } } use App\Constants\ExtensionConst; use Illuminate\Support\Facades\DB; use App\Constants\LanguageConst; use Exception; use Illuminate\Support\Str; use Illuminate\Http\Request; use App\Models\Admin\Language; use App\Models\Admin\UsefulLink; use App\Models\Admin\SiteSections; use App\Models\Frontend\Subscribe; use App\Constants\SiteSectionConst; use App\Http\Controllers\Controller; use App\Models\Admin\AppSettings; use App\Models\Admin\BasicSettings; use App\Models\Admin\InvestmentPlan; use App\Models\Admin\Package; use App\Models\Admin\SetupPage; use App\Models\Frontend\Announcement; use App\Models\Frontend\AnnouncementCategory; use App\Models\Frontend\ContactRequest; use App\Models\Frontend\FrontendHeaderSection; use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Validator; use App\Providers\Admin\BasicSettingsProvider; use App\Providers\Admin\ExtensionProvider; class IndexController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $page_section = SetupPage::where('slug','home')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); $default = get_default_language_code(); return view('frontend.pages.index',compact('site_name','page_title','page_section','footer','default')); } public function aboutUs(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('About Us'); $page_section = SetupPage::where('slug','about-us')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.about-us',compact('site_name', 'page_title', 'page_section', 'footer')); } public function pricing(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Pricing'); $page_section = SetupPage::where('slug','pricing')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.pricing',compact('site_name','page_title', 'page_section', 'footer')); } public function blog(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Announcement'); $page_section = SetupPage::where('slug','announcement')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.blog',compact('site_name','page_title', 'page_section', 'footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function blogDetail(BasicSettingsProvider $basic_settings, $id) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $blog_categories = AnnouncementCategory::get(); $blog = Announcement::where('id', $id)->first(); $recent_blogs = Announcement::latest()->get(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.blog-details', compact('site_name', 'page_title', 'blog_categories', 'blog', 'recent_blogs', 'footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function categoryBlog(BasicSettingsProvider $basic_settings, $id) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $blog_categories = AnnouncementCategory::get(); $blogs = Announcement::where('announcement_category_id', $id)->latest()->get(); $recent_blogs = Announcement::latest()->get(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.category-blog', compact('site_name', 'page_title', 'blog_categories', 'blogs', 'recent_blogs', 'footer')); } public function service(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Services'); $page_section = SetupPage::where('slug','services')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.service',compact('site_name','page_title','page_section','footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function contact(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Help'); $contact_slug = Str::slug(SiteSectionConst::CONTACT_US_SECTION); $contact = SiteSections::getData($contact_slug)->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.contact', compact('site_name', 'page_title', 'contact','footer')); } public function subscribe(Request $request) { $extension = ExtensionProvider::get()->where('slug', ExtensionConst::GOOGLE_RECAPTCHA_SLUG)->first(); $captcha_rules = 'nullable'; if ($extension && $extension->status == true) { $captcha_rules = 'required|string|g_recaptcha_verify'; } $validator = Validator::make($request->all(),[ 'email' => "required|string|email|max:255|unique:subscribes", 'g-recaptcha-response' => $captcha_rules, ]); if($validator->fails()) return redirect('/#subscribe-form')->withErrors($validator)->withInput(); $validated = $validator->validated(); try{ Subscribe::create([ 'email' => $validated['email'], 'created_at' => now(), ]); }catch(Exception $e) { return redirect('/#subscribe-form')->with(['error' => ['Failed to subscribe. Try again']]); } return redirect(url()->previous() .'/#subscribe-form')->with(['success' => ['Subscription successful!']]); } public function contactMessageSend(Request $request) { $extension = ExtensionProvider::get()->where('slug', ExtensionConst::GOOGLE_RECAPTCHA_SLUG)->first(); $captcha_rules = 'nullable'; if ($extension && $extension->status == true) { $captcha_rules = 'required|string|g_recaptcha_verify'; } $validated = Validator::make($request->all(),[ 'name' => "required|string|max:255", 'email' => "required|email|string|max:255", 'message' => "required|string|max:5000", 'g-recaptcha-response' => $captcha_rules, ])->validate(); try{ ContactRequest::create($validated); }catch(Exception $e) { return back()->with(['error' => ['Failed to send message. Please Try again']]); } return back()->with(['success' => ['Message send successfully!']]); } public function usefulLink($slug) { $useful_link = UsefulLink::where("slug",$slug)->first(); if(!$useful_link) abort(404); $basic_settings = BasicSettingsProvider::get(); $app_local = get_default_language_code(); $page_title = $useful_link->title?->language?->$app_local?->title ?? $basic_settings->site_name; // return view('frontend.pages.useful-link',compact('page_title','useful_link')); } public function languageSwitch(Request $request) { $code = $request->target; $language = Language::where("code",$code)->first(); if(!$language) { return back()->with(['error' => ['Oops! Language Not Found!']]); } Session::put('local',$code); Session::put('local_dir',$language->dir); return back()->with(['success' => ['Language Switch to ' . $language->name ]]); } public function usefulPage($slug){ $page = UsefulLink::where('slug', $slug)->where('status', 1)->first(); $basic_settings = BasicSettings::first(); $site_name = $basic_settings->site_name; $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); if(empty($page)){ abort(404); } return view('frontend.pages.usefull_pages',compact('page',"site_name",'footer')); } public function boutique(){ $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); $page_title = "Julie Store and Boutique"; return view("frontend.pages.boutique", compact("page_title", "footer")); } public function headerPage($parent_id){ $selected_lan = get_default_language_code(); $system_default = LanguageConst::NOT_REMOVABLE; $parent = FrontendHeaderSection::where('id',$parent_id)->where('status',1)->first(); if( $parent == null) return back()->with(['error' => [__("The page content is currently empty.")]]); $page_content = $parent->singlePageContent($parent->id); $faq_content = $parent->singleFaqContent($parent->id); $page_title = $parent->title?->language?->$selected_lan?->title ?? $parent->title?->language?->$system_default?->title; $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); return view('frontend.pages.header-section',compact('page_title','parent','page_content','faq_content','footer')); } public function boutiqueProduct($id){ $product = DB::table('jsb_products')->where('id',$id)->where('is_active',1)->first(); if(!$product) abort(404); $images = DB::table('jsb_product_images')->where('product_id',$id)->get(); $variants = DB::table('jsb_product_variants')->where('product_id',$id)->get(); $sizes = $variants->pluck('size')->unique()->filter()->values(); $colors = $variants->pluck('color')->unique()->filter()->values(); return view('frontend.pages.boutique-product', compact('product','images','variants','sizes','colors')); } public function boutiqueCart(){ $cart = session('jsb_cart',[]); $items = []; $total = 0; foreach($cart as $key=>$item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $image = DB::table('jsb_product_images')->where('product_id',$product->id)->where('is_main',1)->first(); $items[] = [ 'key' => $key, 'product' => $product, 'image' => $image, 'variant' => $item['variant'] ?? null, 'quantity' => $item['quantity'], 'subtotal' => $product->price * $item['quantity'], ]; $total += $product->price * $item['quantity']; } } return view('frontend.pages.boutique-cart', compact('items','total')); } public function boutiqueCartAdd(Request $request){ $product = DB::table('jsb_products')->find($request->product_id); if(!$product) return back()->with('error','Produit introuvable'); $cart = session('jsb_cart',[]); $key = $request->product_id.'-'.($request->variant_id ?? '0'); if(isset($cart[$key])){ $cart[$key]['quantity'] += $request->quantity ?? 1; } else { $cart[$key] = [ 'product_id' => $request->product_id, 'variant_id' => $request->variant_id, 'variant' => $request->variant_info, 'quantity' => $request->quantity ?? 1, ]; } session()->put('jsb_cart', $cart); session()->save(); return redirect()->route('frontend.boutique.cart')->with('success','Produit ajouté au panier!'); } public function boutiqueCartRemove(Request $request){ $cart = session('jsb_cart',[]); unset($cart[$request->key]); session()->put('jsb_cart', $cart); session()->save(); return back()->with('success','Produit retiré du panier.'); } public function boutiqueCartQty(Request $request){ $cart = session('jsb_cart',[]); if(isset($cart[$request->key])){ $cart[$request->key]['quantity'] = max(1, intval($request->quantity)); } session()->put('jsb_cart', $cart); session()->save(); return back(); } public function boutiqueCheckout(){ $cart = session('jsb_cart',[]); if(empty($cart)) return redirect()->route('frontend.boutique.cart'); if(!auth()->check()) return redirect()->route('user.login')->with('error','Connectez-vous pour commander.'); $items = []; $subtotal = 0; foreach($cart as $key=>$item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $image = DB::table('jsb_product_images')->where('product_id',$product->id)->where('is_main',1)->first(); $items[] = ['product'=>$product,'image'=>$image,'variant'=>$item['variant']??null,'quantity'=>$item['quantity'],'subtotal'=>$product->price*$item['quantity']]; $subtotal += $product->price * $item['quantity']; } } $zones = DB::table('jsb_delivery_zones')->where('is_active',1)->orderBy('city')->get(); $user = auth()->user(); $wallet = DB::table('user_wallets')->where('user_id',$user->id)->first(); $balance = $wallet->balance ?? 0; return view('frontend.pages.boutique-checkout', compact('items','subtotal','zones','user','balance')); } public function boutiqueCheckoutConfirm(Request $request){ if(!auth()->check()) return redirect()->route('user.login'); $cart = session('jsb_cart',[]); if(empty($cart)) return redirect()->route('frontend.boutique'); $request->validate([ 'delivery_city' => 'required|string', 'delivery_address' => 'required|string', 'delivery_phone' => 'required|string', ]); $user = auth()->user(); $wallet = DB::table('user_wallets')->where('user_id',$user->id)->first(); $balance = $wallet->balance ?? 0; $zone = DB::table('jsb_delivery_zones')->where('city',$request->delivery_city)->first(); $delivery_amount = $zone ? $zone->price : 0; $subtotal = 0; $items_data = []; foreach($cart as $item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $subtotal += $product->price * $item['quantity']; $items_data[] = ['product'=>$product,'item'=>$item]; } } $total = $subtotal + $delivery_amount; $commission_pct = DB::table('jsb_settings')->where('key','commission_percent')->first()->value ?? 5; $commission = $subtotal * $commission_pct / 100; $cherline_amount = $subtotal - $commission + $delivery_amount; if($balance < $total){ return back()->with('error','Solde insuffisant. Votre solde: $'.number_format($balance,2).' — Total: $'.number_format($total,2)); } // Debit balance DB::table('user_wallets')->where('user_id',$user->id)->decrement('balance', $total); // Create order $ref = 'JSB-'.strtoupper(substr(md5(time().$user->id),0,8)); $order_id = DB::table('jsb_orders')->insertGetId([ 'order_ref' => $ref, 'user_id' => $user->id, 'total_amount' => $total, 'delivery_amount' => $delivery_amount, 'commission_amount' => $commission, 'cherline_amount' => $cherline_amount, 'delivery_city' => $request->delivery_city, 'delivery_address' => $request->delivery_address, 'delivery_phone' => $request->delivery_phone, 'status' => 'pending', 'notes' => $request->notes, 'created_at' => now(), 'updated_at' => now(), ]); foreach($items_data as $data){ DB::table('jsb_order_items')->insert([ 'order_id' => $order_id, 'product_id' => $data['product']->id, 'product_name' => $data['product']->name, 'variant_info' => $data['item']['variant'] ?? null, 'quantity' => $data['item']['quantity'], 'unit_price' => $data['product']->price, 'created_at' => now(), 'updated_at' => now(), ]); // Update stock DB::table('jsb_product_variants')->where('product_id',$data['product']->id)->decrement('stock', $data['item']['quantity']); } // Transfer to Cherline $cherline_id = DB::table('jsb_settings')->where('key','cherline_user_id')->first()->value ?? 21; DB::table('user_wallets')->where('user_id',$cherline_id)->increment('balance', $cherline_amount); session()->forget('jsb_cart'); // Voye email konfirmasyon try { $order_obj = DB::table('jsb_orders')->where('order_ref',$ref)->first(); $items_email = []; foreach($items_data as $data) { $obj = (object)[ 'product_name' => $data['product']->name, 'variant_info' => $data['item']['variant'] ?? null, 'quantity' => $data['item']['quantity'], 'unit_price' => $data['product']->price, 'image_path' => DB::table('jsb_product_images')->where('product_id',$data['product']->id)->where('is_main',1)->value('image_path'), ]; $items_email[] = $obj; } Mail::to($user->email)->send(new OrderNotification($order_obj, $items_email, 'pending')); } catch(\Exception $e) { \Illuminate\Support\Facades\Log::error('Order email error: '.$e->getMessage()); } return redirect()->route('frontend.boutique.order.success', $ref); } public function boutiqueOrderSuccess($ref){ $order = DB::table('jsb_orders')->where('order_ref',$ref)->first(); if(!$order) abort(404); $items = DB::table('jsb_order_items')->where('order_id',$order->id)->get(); return view('frontend.pages.boutique-order-success', compact('order','items')); } public function boutiqueMyOrders(){ if(!auth()->check()) return redirect()->route('user.login'); $orders = DB::table('jsb_orders')->where('user_id',auth()->id())->orderBy('created_at','desc')->get(); return view('frontend.pages.boutique-my-orders', compact('orders')); } public function boutiquePage($slug){ $page = DB::table('jsb_pages')->where('slug',$slug)->first(); if(!$page) abort(404); return view('frontend.pages.boutique-page', compact('page')); } public function boutiqueTracking(){ $order = null; $items = []; if(request('ref')) { $order = DB::table('jsb_orders')->where('order_ref', request('ref'))->first(); if($order) { $items_raw = DB::table('jsb_order_items')->where('order_id',$order->id)->get(); foreach($items_raw as $item) { $img = DB::table('jsb_product_images')->where('product_id',$item->product_id)->where('is_main',1)->first(); $item->image_path = $img->image_path ?? null; $items[] = $item; } } } return view('frontend.pages.boutique-tracking', compact('order','items')); } public function boutiqueChatMessage(Request $request) { DB::table('jsb_chat_messages')->insert([ 'option_chosen' => $request->option ?? null, 'message' => $request->message ?? '', 'user_id' => auth()->id() ?? null, 'ip' => $request->ip(), 'created_at' => now(), ]); return response()->json(['status'=>'ok']); } } use App\Constants\ExtensionConst; use Illuminate\Support\Facades\DB; use App\Constants\LanguageConst; use Exception; use Illuminate\Support\Str; use Illuminate\Http\Request; use App\Models\Admin\Language; use App\Models\Admin\UsefulLink; use App\Models\Admin\SiteSections; use App\Models\Frontend\Subscribe; use App\Constants\SiteSectionConst; use App\Http\Controllers\Controller; use App\Models\Admin\AppSettings; use App\Models\Admin\BasicSettings; use App\Models\Admin\InvestmentPlan; use App\Models\Admin\Package; use App\Models\Admin\SetupPage; use App\Models\Frontend\Announcement; use App\Models\Frontend\AnnouncementCategory; use App\Models\Frontend\ContactRequest; use App\Models\Frontend\FrontendHeaderSection; use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Validator; use App\Providers\Admin\BasicSettingsProvider; use App\Providers\Admin\ExtensionProvider; class IndexController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $page_section = SetupPage::where('slug','home')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); $default = get_default_language_code(); return view('frontend.pages.index',compact('site_name','page_title','page_section','footer','default')); } public function aboutUs(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('About Us'); $page_section = SetupPage::where('slug','about-us')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.about-us',compact('site_name', 'page_title', 'page_section', 'footer')); } public function pricing(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Pricing'); $page_section = SetupPage::where('slug','pricing')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.pricing',compact('site_name','page_title', 'page_section', 'footer')); } public function blog(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Announcement'); $page_section = SetupPage::where('slug','announcement')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.blog',compact('site_name','page_title', 'page_section', 'footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function blogDetail(BasicSettingsProvider $basic_settings, $id) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $blog_categories = AnnouncementCategory::get(); $blog = Announcement::where('id', $id)->first(); $recent_blogs = Announcement::latest()->get(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.blog-details', compact('site_name', 'page_title', 'blog_categories', 'blog', 'recent_blogs', 'footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function categoryBlog(BasicSettingsProvider $basic_settings, $id) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $blog_categories = AnnouncementCategory::get(); $blogs = Announcement::where('announcement_category_id', $id)->latest()->get(); $recent_blogs = Announcement::latest()->get(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.category-blog', compact('site_name', 'page_title', 'blog_categories', 'blogs', 'recent_blogs', 'footer')); } public function service(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Services'); $page_section = SetupPage::where('slug','services')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.service',compact('site_name','page_title','page_section','footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function contact(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Help'); $contact_slug = Str::slug(SiteSectionConst::CONTACT_US_SECTION); $contact = SiteSections::getData($contact_slug)->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.contact', compact('site_name', 'page_title', 'contact','footer')); } public function subscribe(Request $request) { $extension = ExtensionProvider::get()->where('slug', ExtensionConst::GOOGLE_RECAPTCHA_SLUG)->first(); $captcha_rules = 'nullable'; if ($extension && $extension->status == true) { $captcha_rules = 'required|string|g_recaptcha_verify'; } $validator = Validator::make($request->all(),[ 'email' => "required|string|email|max:255|unique:subscribes", 'g-recaptcha-response' => $captcha_rules, ]); if($validator->fails()) return redirect('/#subscribe-form')->withErrors($validator)->withInput(); $validated = $validator->validated(); try{ Subscribe::create([ 'email' => $validated['email'], 'created_at' => now(), ]); }catch(Exception $e) { return redirect('/#subscribe-form')->with(['error' => ['Failed to subscribe. Try again']]); } return redirect(url()->previous() .'/#subscribe-form')->with(['success' => ['Subscription successful!']]); } public function contactMessageSend(Request $request) { $extension = ExtensionProvider::get()->where('slug', ExtensionConst::GOOGLE_RECAPTCHA_SLUG)->first(); $captcha_rules = 'nullable'; if ($extension && $extension->status == true) { $captcha_rules = 'required|string|g_recaptcha_verify'; } $validated = Validator::make($request->all(),[ 'name' => "required|string|max:255", 'email' => "required|email|string|max:255", 'message' => "required|string|max:5000", 'g-recaptcha-response' => $captcha_rules, ])->validate(); try{ ContactRequest::create($validated); }catch(Exception $e) { return back()->with(['error' => ['Failed to send message. Please Try again']]); } return back()->with(['success' => ['Message send successfully!']]); } public function usefulLink($slug) { $useful_link = UsefulLink::where("slug",$slug)->first(); if(!$useful_link) abort(404); $basic_settings = BasicSettingsProvider::get(); $app_local = get_default_language_code(); $page_title = $useful_link->title?->language?->$app_local?->title ?? $basic_settings->site_name; // return view('frontend.pages.useful-link',compact('page_title','useful_link')); } public function languageSwitch(Request $request) { $code = $request->target; $language = Language::where("code",$code)->first(); if(!$language) { return back()->with(['error' => ['Oops! Language Not Found!']]); } Session::put('local',$code); Session::put('local_dir',$language->dir); return back()->with(['success' => ['Language Switch to ' . $language->name ]]); } public function usefulPage($slug){ $page = UsefulLink::where('slug', $slug)->where('status', 1)->first(); $basic_settings = BasicSettings::first(); $site_name = $basic_settings->site_name; $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); if(empty($page)){ abort(404); } return view('frontend.pages.usefull_pages',compact('page',"site_name",'footer')); } public function boutique(){ $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); $page_title = "Julie Store and Boutique"; return view("frontend.pages.boutique", compact("page_title", "footer")); } public function headerPage($parent_id){ $selected_lan = get_default_language_code(); $system_default = LanguageConst::NOT_REMOVABLE; $parent = FrontendHeaderSection::where('id',$parent_id)->where('status',1)->first(); if( $parent == null) return back()->with(['error' => [__("The page content is currently empty.")]]); $page_content = $parent->singlePageContent($parent->id); $faq_content = $parent->singleFaqContent($parent->id); $page_title = $parent->title?->language?->$selected_lan?->title ?? $parent->title?->language?->$system_default?->title; $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); return view('frontend.pages.header-section',compact('page_title','parent','page_content','faq_content','footer')); } public function boutiqueProduct($id){ $product = DB::table('jsb_products')->where('id',$id)->where('is_active',1)->first(); if(!$product) abort(404); $images = DB::table('jsb_product_images')->where('product_id',$id)->get(); $variants = DB::table('jsb_product_variants')->where('product_id',$id)->get(); $sizes = $variants->pluck('size')->unique()->filter()->values(); $colors = $variants->pluck('color')->unique()->filter()->values(); return view('frontend.pages.boutique-product', compact('product','images','variants','sizes','colors')); } public function boutiqueCart(){ $cart = session('jsb_cart',[]); $items = []; $total = 0; foreach($cart as $key=>$item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $image = DB::table('jsb_product_images')->where('product_id',$product->id)->where('is_main',1)->first(); $items[] = [ 'key' => $key, 'product' => $product, 'image' => $image, 'variant' => $item['variant'] ?? null, 'quantity' => $item['quantity'], 'subtotal' => $product->price * $item['quantity'], ]; $total += $product->price * $item['quantity']; } } return view('frontend.pages.boutique-cart', compact('items','total')); } public function boutiqueCartAdd(Request $request){ $product = DB::table('jsb_products')->find($request->product_id); if(!$product) return back()->with('error','Produit introuvable'); $cart = session('jsb_cart',[]); $key = $request->product_id.'-'.($request->variant_id ?? '0'); if(isset($cart[$key])){ $cart[$key]['quantity'] += $request->quantity ?? 1; } else { $cart[$key] = [ 'product_id' => $request->product_id, 'variant_id' => $request->variant_id, 'variant' => $request->variant_info, 'quantity' => $request->quantity ?? 1, ]; } session()->put('jsb_cart', $cart); session()->save(); return redirect()->route('frontend.boutique.cart')->with('success','Produit ajouté au panier!'); } public function boutiqueCartRemove(Request $request){ $cart = session('jsb_cart',[]); unset($cart[$request->key]); session()->put('jsb_cart', $cart); session()->save(); return back()->with('success','Produit retiré du panier.'); } public function boutiqueCartQty(Request $request){ $cart = session('jsb_cart',[]); if(isset($cart[$request->key])){ $cart[$request->key]['quantity'] = max(1, intval($request->quantity)); } session()->put('jsb_cart', $cart); session()->save(); return back(); } public function boutiqueCheckout(){ $cart = session('jsb_cart',[]); if(empty($cart)) return redirect()->route('frontend.boutique.cart'); if(!auth()->check()) return redirect()->route('user.login')->with('error','Connectez-vous pour commander.'); $items = []; $subtotal = 0; foreach($cart as $key=>$item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $image = DB::table('jsb_product_images')->where('product_id',$product->id)->where('is_main',1)->first(); $items[] = ['product'=>$product,'image'=>$image,'variant'=>$item['variant']??null,'quantity'=>$item['quantity'],'subtotal'=>$product->price*$item['quantity']]; $subtotal += $product->price * $item['quantity']; } } $zones = DB::table('jsb_delivery_zones')->where('is_active',1)->orderBy('city')->get(); $user = auth()->user(); $wallet = DB::table('user_wallets')->where('user_id',$user->id)->first(); $balance = $wallet->balance ?? 0; return view('frontend.pages.boutique-checkout', compact('items','subtotal','zones','user','balance')); } public function boutiqueCheckoutConfirm(Request $request){ if(!auth()->check()) return redirect()->route('user.login'); $cart = session('jsb_cart',[]); if(empty($cart)) return redirect()->route('frontend.boutique'); $request->validate([ 'delivery_city' => 'required|string', 'delivery_address' => 'required|string', 'delivery_phone' => 'required|string', ]); $user = auth()->user(); $wallet = DB::table('user_wallets')->where('user_id',$user->id)->first(); $balance = $wallet->balance ?? 0; $zone = DB::table('jsb_delivery_zones')->where('city',$request->delivery_city)->first(); $delivery_amount = $zone ? $zone->price : 0; $subtotal = 0; $items_data = []; foreach($cart as $item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $subtotal += $product->price * $item['quantity']; $items_data[] = ['product'=>$product,'item'=>$item]; } } $total = $subtotal + $delivery_amount; $commission_pct = DB::table('jsb_settings')->where('key','commission_percent')->first()->value ?? 5; $commission = $subtotal * $commission_pct / 100; $cherline_amount = $subtotal - $commission + $delivery_amount; if($balance < $total){ return back()->with('error','Solde insuffisant. Votre solde: $'.number_format($balance,2).' — Total: $'.number_format($total,2)); } // Debit balance DB::table('user_wallets')->where('user_id',$user->id)->decrement('balance', $total); // Create order $ref = 'JSB-'.strtoupper(substr(md5(time().$user->id),0,8)); $order_id = DB::table('jsb_orders')->insertGetId([ 'order_ref' => $ref, 'user_id' => $user->id, 'total_amount' => $total, 'delivery_amount' => $delivery_amount, 'commission_amount' => $commission, 'cherline_amount' => $cherline_amount, 'delivery_city' => $request->delivery_city, 'delivery_address' => $request->delivery_address, 'delivery_phone' => $request->delivery_phone, 'status' => 'pending', 'notes' => $request->notes, 'created_at' => now(), 'updated_at' => now(), ]); foreach($items_data as $data){ DB::table('jsb_order_items')->insert([ 'order_id' => $order_id, 'product_id' => $data['product']->id, 'product_name' => $data['product']->name, 'variant_info' => $data['item']['variant'] ?? null, 'quantity' => $data['item']['quantity'], 'unit_price' => $data['product']->price, 'created_at' => now(), 'updated_at' => now(), ]); // Update stock DB::table('jsb_product_variants')->where('product_id',$data['product']->id)->decrement('stock', $data['item']['quantity']); } // Transfer to Cherline $cherline_id = DB::table('jsb_settings')->where('key','cherline_user_id')->first()->value ?? 21; DB::table('user_wallets')->where('user_id',$cherline_id)->increment('balance', $cherline_amount); session()->forget('jsb_cart'); // Voye email konfirmasyon try { $order_obj = DB::table('jsb_orders')->where('order_ref',$ref)->first(); $items_email = []; foreach($items_data as $data) { $obj = (object)[ 'product_name' => $data['product']->name, 'variant_info' => $data['item']['variant'] ?? null, 'quantity' => $data['item']['quantity'], 'unit_price' => $data['product']->price, 'image_path' => DB::table('jsb_product_images')->where('product_id',$data['product']->id)->where('is_main',1)->value('image_path'), ]; $items_email[] = $obj; } Mail::to($user->email)->send(new OrderNotification($order_obj, $items_email, 'pending')); } catch(\Exception $e) { \Illuminate\Support\Facades\Log::error('Order email error: '.$e->getMessage()); } return redirect()->route('frontend.boutique.order.success', $ref); } public function boutiqueOrderSuccess($ref){ $order = DB::table('jsb_orders')->where('order_ref',$ref)->first(); if(!$order) abort(404); $items = DB::table('jsb_order_items')->where('order_id',$order->id)->get(); return view('frontend.pages.boutique-order-success', compact('order','items')); } public function boutiqueMyOrders(){ if(!auth()->check()) return redirect()->route('user.login'); $orders = DB::table('jsb_orders')->where('user_id',auth()->id())->orderBy('created_at','desc')->get(); return view('frontend.pages.boutique-my-orders', compact('orders')); } public function boutiquePage($slug){ $page = DB::table('jsb_pages')->where('slug',$slug)->first(); if(!$page) abort(404); return view('frontend.pages.boutique-page', compact('page')); } public function boutiqueTracking(){ $order = null; $items = []; if(request('ref')) { $order = DB::table('jsb_orders')->where('order_ref', request('ref'))->first(); if($order) { $items_raw = DB::table('jsb_order_items')->where('order_id',$order->id)->get(); foreach($items_raw as $item) { $img = DB::table('jsb_product_images')->where('product_id',$item->product_id)->where('is_main',1)->first(); $item->image_path = $img->image_path ?? null; $items[] = $item; } } } return view('frontend.pages.boutique-tracking', compact('order','items')); } public function boutiqueChatMessage(Request $request) { DB::table('jsb_chat_messages')->insert([ 'option_chosen' => $request->option ?? null, 'message' => $request->message ?? '', 'user_id' => auth()->id() ?? null, 'ip' => $request->ip(), 'created_at' => now(), ]); return response()->json(['status'=>'ok']); } } use App\Constants\ExtensionConst; use Illuminate\Support\Facades\DB; use App\Constants\LanguageConst; use Exception; use Illuminate\Support\Str; use Illuminate\Http\Request; use App\Models\Admin\Language; use App\Models\Admin\UsefulLink; use App\Models\Admin\SiteSections; use App\Models\Frontend\Subscribe; use App\Constants\SiteSectionConst; use App\Http\Controllers\Controller; use App\Models\Admin\AppSettings; use App\Models\Admin\BasicSettings; use App\Models\Admin\InvestmentPlan; use App\Models\Admin\Package; use App\Models\Admin\SetupPage; use App\Models\Frontend\Announcement; use App\Models\Frontend\AnnouncementCategory; use App\Models\Frontend\ContactRequest; use App\Models\Frontend\FrontendHeaderSection; use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Validator; use App\Providers\Admin\BasicSettingsProvider; use App\Providers\Admin\ExtensionProvider; class IndexController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $page_section = SetupPage::where('slug','home')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); $default = get_default_language_code(); return view('frontend.pages.index',compact('site_name','page_title','page_section','footer','default')); } public function aboutUs(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('About Us'); $page_section = SetupPage::where('slug','about-us')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.about-us',compact('site_name', 'page_title', 'page_section', 'footer')); } public function pricing(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Pricing'); $page_section = SetupPage::where('slug','pricing')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.pricing',compact('site_name','page_title', 'page_section', 'footer')); } public function blog(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Announcement'); $page_section = SetupPage::where('slug','announcement')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.blog',compact('site_name','page_title', 'page_section', 'footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function blogDetail(BasicSettingsProvider $basic_settings, $id) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $blog_categories = AnnouncementCategory::get(); $blog = Announcement::where('id', $id)->first(); $recent_blogs = Announcement::latest()->get(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.blog-details', compact('site_name', 'page_title', 'blog_categories', 'blog', 'recent_blogs', 'footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function categoryBlog(BasicSettingsProvider $basic_settings, $id) { $site_name = $basic_settings->get()?->site_name; $page_title = $basic_settings->get()?->site_name . " | " . $basic_settings->get()?->site_title; $blog_categories = AnnouncementCategory::get(); $blogs = Announcement::where('announcement_category_id', $id)->latest()->get(); $recent_blogs = Announcement::latest()->get(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.category-blog', compact('site_name', 'page_title', 'blog_categories', 'blogs', 'recent_blogs', 'footer')); } public function service(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Services'); $page_section = SetupPage::where('slug','services')->with(['sections' => function($q){ $q->where('status',true); }])->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.service',compact('site_name','page_title','page_section','footer')); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function contact(BasicSettingsProvider $basic_settings) { $site_name = $basic_settings->get()?->site_name; $page_title = __('Help'); $contact_slug = Str::slug(SiteSectionConst::CONTACT_US_SECTION); $contact = SiteSections::getData($contact_slug)->first(); $footer_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($footer_slug)->first(); return view('frontend.pages.contact', compact('site_name', 'page_title', 'contact','footer')); } public function subscribe(Request $request) { $extension = ExtensionProvider::get()->where('slug', ExtensionConst::GOOGLE_RECAPTCHA_SLUG)->first(); $captcha_rules = 'nullable'; if ($extension && $extension->status == true) { $captcha_rules = 'required|string|g_recaptcha_verify'; } $validator = Validator::make($request->all(),[ 'email' => "required|string|email|max:255|unique:subscribes", 'g-recaptcha-response' => $captcha_rules, ]); if($validator->fails()) return redirect('/#subscribe-form')->withErrors($validator)->withInput(); $validated = $validator->validated(); try{ Subscribe::create([ 'email' => $validated['email'], 'created_at' => now(), ]); }catch(Exception $e) { return redirect('/#subscribe-form')->with(['error' => ['Failed to subscribe. Try again']]); } return redirect(url()->previous() .'/#subscribe-form')->with(['success' => ['Subscription successful!']]); } public function contactMessageSend(Request $request) { $extension = ExtensionProvider::get()->where('slug', ExtensionConst::GOOGLE_RECAPTCHA_SLUG)->first(); $captcha_rules = 'nullable'; if ($extension && $extension->status == true) { $captcha_rules = 'required|string|g_recaptcha_verify'; } $validated = Validator::make($request->all(),[ 'name' => "required|string|max:255", 'email' => "required|email|string|max:255", 'message' => "required|string|max:5000", 'g-recaptcha-response' => $captcha_rules, ])->validate(); try{ ContactRequest::create($validated); }catch(Exception $e) { return back()->with(['error' => ['Failed to send message. Please Try again']]); } return back()->with(['success' => ['Message send successfully!']]); } public function usefulLink($slug) { $useful_link = UsefulLink::where("slug",$slug)->first(); if(!$useful_link) abort(404); $basic_settings = BasicSettingsProvider::get(); $app_local = get_default_language_code(); $page_title = $useful_link->title?->language?->$app_local?->title ?? $basic_settings->site_name; // return view('frontend.pages.useful-link',compact('page_title','useful_link')); } public function languageSwitch(Request $request) { $code = $request->target; $language = Language::where("code",$code)->first(); if(!$language) { return back()->with(['error' => ['Oops! Language Not Found!']]); } Session::put('local',$code); Session::put('local_dir',$language->dir); return back()->with(['success' => ['Language Switch to ' . $language->name ]]); } public function usefulPage($slug){ $page = UsefulLink::where('slug', $slug)->where('status', 1)->first(); $basic_settings = BasicSettings::first(); $site_name = $basic_settings->site_name; $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); if(empty($page)){ abort(404); } return view('frontend.pages.usefull_pages',compact('page',"site_name",'footer')); } public function boutique(){ $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); $page_title = "Julie Store and Boutique"; return view("frontend.pages.boutique", compact("page_title", "footer")); } public function headerPage($parent_id){ $selected_lan = get_default_language_code(); $system_default = LanguageConst::NOT_REMOVABLE; $parent = FrontendHeaderSection::where('id',$parent_id)->where('status',1)->first(); if( $parent == null) return back()->with(['error' => [__("The page content is currently empty.")]]); $page_content = $parent->singlePageContent($parent->id); $faq_content = $parent->singleFaqContent($parent->id); $page_title = $parent->title?->language?->$selected_lan?->title ?? $parent->title?->language?->$system_default?->title; $section_slug = Str::slug(SiteSectionConst::FOOTER_SECTION); $footer = SiteSections::getData($section_slug)->first(); return view('frontend.pages.header-section',compact('page_title','parent','page_content','faq_content','footer')); } public function boutiqueProduct($id){ $product = DB::table('jsb_products')->where('id',$id)->where('is_active',1)->first(); if(!$product) abort(404); $images = DB::table('jsb_product_images')->where('product_id',$id)->get(); $variants = DB::table('jsb_product_variants')->where('product_id',$id)->get(); $sizes = $variants->pluck('size')->unique()->filter()->values(); $colors = $variants->pluck('color')->unique()->filter()->values(); return view('frontend.pages.boutique-product', compact('product','images','variants','sizes','colors')); } public function boutiqueCart(){ $cart = session('jsb_cart',[]); $items = []; $total = 0; foreach($cart as $key=>$item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $image = DB::table('jsb_product_images')->where('product_id',$product->id)->where('is_main',1)->first(); $items[] = [ 'key' => $key, 'product' => $product, 'image' => $image, 'variant' => $item['variant'] ?? null, 'quantity' => $item['quantity'], 'subtotal' => $product->price * $item['quantity'], ]; $total += $product->price * $item['quantity']; } } return view('frontend.pages.boutique-cart', compact('items','total')); } public function boutiqueCartAdd(Request $request){ $product = DB::table('jsb_products')->find($request->product_id); if(!$product) return back()->with('error','Produit introuvable'); $cart = session('jsb_cart',[]); $key = $request->product_id.'-'.($request->variant_id ?? '0'); if(isset($cart[$key])){ $cart[$key]['quantity'] += $request->quantity ?? 1; } else { $cart[$key] = [ 'product_id' => $request->product_id, 'variant_id' => $request->variant_id, 'variant' => $request->variant_info, 'quantity' => $request->quantity ?? 1, ]; } session()->put('jsb_cart', $cart); session()->save(); return redirect()->route('frontend.boutique.cart')->with('success','Produit ajouté au panier!'); } public function boutiqueCartRemove(Request $request){ $cart = session('jsb_cart',[]); unset($cart[$request->key]); session()->put('jsb_cart', $cart); session()->save(); return back()->with('success','Produit retiré du panier.'); } public function boutiqueCartQty(Request $request){ $cart = session('jsb_cart',[]); if(isset($cart[$request->key])){ $cart[$request->key]['quantity'] = max(1, intval($request->quantity)); } session()->put('jsb_cart', $cart); session()->save(); return back(); } public function boutiqueCheckout(){ $cart = session('jsb_cart',[]); if(empty($cart)) return redirect()->route('frontend.boutique.cart'); if(!auth()->check()) return redirect()->route('user.login')->with('error','Connectez-vous pour commander.'); $items = []; $subtotal = 0; foreach($cart as $key=>$item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $image = DB::table('jsb_product_images')->where('product_id',$product->id)->where('is_main',1)->first(); $items[] = ['product'=>$product,'image'=>$image,'variant'=>$item['variant']??null,'quantity'=>$item['quantity'],'subtotal'=>$product->price*$item['quantity']]; $subtotal += $product->price * $item['quantity']; } } $zones = DB::table('jsb_delivery_zones')->where('is_active',1)->orderBy('city')->get(); $user = auth()->user(); $wallet = DB::table('user_wallets')->where('user_id',$user->id)->first(); $balance = $wallet->balance ?? 0; return view('frontend.pages.boutique-checkout', compact('items','subtotal','zones','user','balance')); } public function boutiqueCheckoutConfirm(Request $request){ if(!auth()->check()) return redirect()->route('user.login'); $cart = session('jsb_cart',[]); if(empty($cart)) return redirect()->route('frontend.boutique'); $request->validate([ 'delivery_city' => 'required|string', 'delivery_address' => 'required|string', 'delivery_phone' => 'required|string', ]); $user = auth()->user(); $wallet = DB::table('user_wallets')->where('user_id',$user->id)->first(); $balance = $wallet->balance ?? 0; $zone = DB::table('jsb_delivery_zones')->where('city',$request->delivery_city)->first(); $delivery_amount = $zone ? $zone->price : 0; $subtotal = 0; $items_data = []; foreach($cart as $item){ $product = DB::table('jsb_products')->find($item['product_id']); if($product){ $subtotal += $product->price * $item['quantity']; $items_data[] = ['product'=>$product,'item'=>$item]; } } $total = $subtotal + $delivery_amount; $commission_pct = DB::table('jsb_settings')->where('key','commission_percent')->first()->value ?? 5; $commission = $subtotal * $commission_pct / 100; $cherline_amount = $subtotal - $commission + $delivery_amount; if($balance < $total){ return back()->with('error','Solde insuffisant. Votre solde: $'.number_format($balance,2).' — Total: $'.number_format($total,2)); } // Debit balance DB::table('user_wallets')->where('user_id',$user->id)->decrement('balance', $total); // Create order $ref = 'JSB-'.strtoupper(substr(md5(time().$user->id),0,8)); $order_id = DB::table('jsb_orders')->insertGetId([ 'order_ref' => $ref, 'user_id' => $user->id, 'total_amount' => $total, 'delivery_amount' => $delivery_amount, 'commission_amount' => $commission, 'cherline_amount' => $cherline_amount, 'delivery_city' => $request->delivery_city, 'delivery_address' => $request->delivery_address, 'delivery_phone' => $request->delivery_phone, 'status' => 'pending', 'notes' => $request->notes, 'created_at' => now(), 'updated_at' => now(), ]); foreach($items_data as $data){ DB::table('jsb_order_items')->insert([ 'order_id' => $order_id, 'product_id' => $data['product']->id, 'product_name' => $data['product']->name, 'variant_info' => $data['item']['variant'] ?? null, 'quantity' => $data['item']['quantity'], 'unit_price' => $data['product']->price, 'created_at' => now(), 'updated_at' => now(), ]); // Update stock DB::table('jsb_product_variants')->where('product_id',$data['product']->id)->decrement('stock', $data['item']['quantity']); } // Transfer to Cherline $cherline_id = DB::table('jsb_settings')->where('key','cherline_user_id')->first()->value ?? 21; DB::table('user_wallets')->where('user_id',$cherline_id)->increment('balance', $cherline_amount); session()->forget('jsb_cart'); // Voye email konfirmasyon try { $order_obj = DB::table('jsb_orders')->where('order_ref',$ref)->first(); $items_email = []; foreach($items_data as $data) { $obj = (object)[ 'product_name' => $data['product']->name, 'variant_info' => $data['item']['variant'] ?? null, 'quantity' => $data['item']['quantity'], 'unit_price' => $data['product']->price, 'image_path' => DB::table('jsb_product_images')->where('product_id',$data['product']->id)->where('is_main',1)->value('image_path'), ]; $items_email[] = $obj; } Mail::to($user->email)->send(new OrderNotification($order_obj, $items_email, 'pending')); } catch(\Exception $e) { \Illuminate\Support\Facades\Log::error('Order email error: '.$e->getMessage()); } return redirect()->route('frontend.boutique.order.success', $ref); } public function boutiqueOrderSuccess($ref){ $order = DB::table('jsb_orders')->where('order_ref',$ref)->first(); if(!$order) abort(404); $items = DB::table('jsb_order_items')->where('order_id',$order->id)->get(); return view('frontend.pages.boutique-order-success', compact('order','items')); } public function boutiqueMyOrders(){ if(!auth()->check()) return redirect()->route('user.login'); $orders = DB::table('jsb_orders')->where('user_id',auth()->id())->orderBy('created_at','desc')->get(); return view('frontend.pages.boutique-my-orders', compact('orders')); } public function boutiquePage($slug){ $page = DB::table('jsb_pages')->where('slug',$slug)->first(); if(!$page) abort(404); return view('frontend.pages.boutique-page', compact('page')); } public function boutiqueTracking(){ $order = null; $items = []; if(request('ref')) { $order = DB::table('jsb_orders')->where('order_ref', request('ref'))->first(); if($order) { $items_raw = DB::table('jsb_order_items')->where('order_id',$order->id)->get(); foreach($items_raw as $item) { $img = DB::table('jsb_product_images')->where('product_id',$item->product_id)->where('is_main',1)->first(); $item->image_path = $img->image_path ?? null; $items[] = $item; } } } return view('frontend.pages.boutique-tracking', compact('order','items')); } public function boutiqueChatMessage(Request $request) { DB::table('jsb_chat_messages')->insert([ 'option_chosen' => $request->option ?? null, 'message' => $request->message ?? '', 'user_id' => auth()->id() ?? null, 'ip' => $request->ip(), 'created_at' => now(), ]); return response()->json(['status'=>'ok']); } }
Nous travaillons à résoudre le problème. Veuillez réessayer dans quelques instants.
Retour à l'accueil