diff --git a/ecommerce-app/.php-cs-fixer.cache b/ecommerce-app/.php-cs-fixer.cache deleted file mode 100644 index 47e2503..0000000 --- a/ecommerce-app/.php-cs-fixer.cache +++ /dev/null @@ -1 +0,0 @@ -{"php":"8.3.10","version":"3.62.0","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"at_least_single_space"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_parentheses":true,"no_blank_lines_after_class_opening":true,"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"none"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"visibility_required":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true},"hashes":{"app\/Models\/.conform.9853146.User.php":"bc1538aaed8591593d86e02815931d41","app\/Models\/.conform.6820527.User.php":"bc1538aaed8591593d86e02815931d41","app\/Http\/Controllers\/.conform.6165636.OrderController.php":"0b6747da62538a3ff7b76ed381414b87","routes\/.conform.5881455.web.php":"fc64346f9a93f8f08762cdf8cc8466d2","routes\/.conform.3894420.web.php":"156b7c7ae7d4c373f3a541cb3e9dda15","routes\/.conform.8828963.web.php":"d7ac384b91e47be6b4d46aadcb95c061","app\/Http\/Controllers\/.conform.6864870.OrderController.php":"f781a55bf3cc806e75563f0eab26c508","app\/Http\/Controllers\/.conform.3033050.OrderController.php":"2f23952d193f05737fb4bd438fb077e3","app\/Http\/Controllers\/.conform.2834601.OrderController.php":"a8bdb01fc5b0b801eaef88fb2f2e69f8","app\/Http\/Controllers\/.conform.5849433.OrderController.php":"212c1456a8c8ab4c9368972e4bf52b3f","app\/Http\/Controllers\/.conform.7198244.OrderController.php":"a676ae95336948929fdd66af777a5d3b","app\/Http\/Controllers\/.conform.1436568.OrderController.php":"57115e400710e351ebb0e1474cb626f3","app\/Http\/Controllers\/.conform.4367839.OrderController.php":"bc81ed8d0e759cb5f7822f8beb542046","app\/Http\/Controllers\/.conform.6776074.OrderController.php":"1abda04eef01f13f0a83a9894f5b7c07","app\/Http\/Controllers\/.conform.5621647.OrderController.php":"c508451fcdb3e260e8532257030fa981","app\/Http\/Controllers\/.conform.1442478.OrderController.php":"c2fb8fb5f33af2b189131f9b103b9904","app\/Http\/Controllers\/.conform.2686714.OrderController.php":"cd30222fff23e41dde79fd7084fc518e","app\/Http\/Controllers\/.conform.1537969.OrderController.php":"2e2afb56a2d6fc086c83845a9f9a6e6d","app\/Http\/Controllers\/.conform.3666033.OrderController.php":"56f7fd366fc62446ff464ecb0affea6c","app\/Http\/Controllers\/.conform.1656608.OrderController.php":"6f5b91f634c0940f1ffb84d6e4c7641a","app\/Http\/Controllers\/.conform.7211151.OrderController.php":"d79a928236db7e914263280d7f34008e","app\/Http\/Controllers\/.conform.4267640.OrderController.php":"3dd373b2178599b6ee317a67428f1010","app\/Http\/Controllers\/.conform.3105764.OrderController.php":"8c3a2f2a46786c9d09b18e30cfb96f39","app\/Http\/Controllers\/.conform.5809353.OrderController.php":"4848b40cbd9891cc98706cb41ae418b3","app\/Http\/Controllers\/.conform.2486456.OrderController.php":"90e2bccfa0095430ad666721f01cfce1","app\/Http\/Controllers\/.conform.9056095.OrderController.php":"90e2bccfa0095430ad666721f01cfce1","routes\/.conform.1852918.web.php":"bcdc551f0c6b3f61167fbd1fd80f65bb","app\/Http\/Controllers\/.conform.8588431.OrderController.php":"03fc9855c293ce73cc799b30b3866423","routes\/.conform.6361561.web.php":"dfbad35aa3444bdc2bba1c2611bc5b7d","routes\/.conform.2388953.web.php":"70312e214e39455bce683a2057cc1a0a","app\/Http\/Controllers\/Auth\/.conform.7451693.RegisteredUserController.php":"e8180ef887ab76c4f1bc69d3a9c473dc","app\/Models\/.conform.7960440.Product.php":"cd72e92a48c7ddb40d310ffd4e6b1046","app\/Models\/.conform.4008488.ShoppingCart.php":"568bf1d699801bf35196319041734866","app\/Models\/.conform.5919377.ShoppingCartItem.php":"0972f98e9c5805504be8bf72fde0094b","app\/Models\/.conform.1817367.ShoppingCart.php":"242e61063d0d064772e5e8d7cc677ad2","app\/Models\/.conform.1197315.ShoppingCart.php":"242e61063d0d064772e5e8d7cc677ad2","app\/Models\/.conform.4061518.ShoppingCart.php":"0aa104604c22a1f1ff59b29292b38445","app\/Models\/.conform.1523459.ShoppingCart.php":"242e61063d0d064772e5e8d7cc677ad2"}} \ No newline at end of file diff --git a/ecommerce-app/app/Http/Controllers/Auth/AuthenticatedSessionController.php b/ecommerce-app/app/Http/Controllers/Auth/AuthenticatedSessionController.php index db1bed1..765dec6 100644 --- a/ecommerce-app/app/Http/Controllers/Auth/AuthenticatedSessionController.php +++ b/ecommerce-app/app/Http/Controllers/Auth/AuthenticatedSessionController.php @@ -28,7 +28,7 @@ public function store(LoginRequest $request): RedirectResponse $request->session()->regenerate(); - return redirect()->intended(route('dashboard.index', absolute: false)); + return redirect()->intended(route('home.index', absolute: false)); } /** diff --git a/ecommerce-app/app/Http/Controllers/Auth/RegisteredUserController.php b/ecommerce-app/app/Http/Controllers/Auth/RegisteredUserController.php index 079ede4..25be419 100644 --- a/ecommerce-app/app/Http/Controllers/Auth/RegisteredUserController.php +++ b/ecommerce-app/app/Http/Controllers/Auth/RegisteredUserController.php @@ -44,13 +44,11 @@ public function store(RegisterRequest $request): RedirectResponse $user->telephone = $request->telephone; $user->is_admin = false; - /* if ($request->hasFile('photo')) { $avatar = new ImageController(); $imageUrl = $avatar->storeImage($request, 'profile'); $user->photo = $imageUrl; } - */ $user->save(); diff --git a/ecommerce-app/app/Http/Controllers/CartController.php b/ecommerce-app/app/Http/Controllers/CartController.php index 18066be..501e43b 100644 --- a/ecommerce-app/app/Http/Controllers/CartController.php +++ b/ecommerce-app/app/Http/Controllers/CartController.php @@ -56,21 +56,6 @@ public function show() $products = Product::with('userReviews')->withAvg('userReviews', 'rating')->withCount('userReviews')->take(3)->get()->sortByDesc(['trendRating']); - /* - if (session("card_id")) { - $cart = ShoppingCart::find(session("card_id")); - $cart_items = $cart->shoppingCartItems()->orderBy("id", "desc")->get()->all(); - //$order_items = $cart->products()->orderBy("id", "desc")->get()->all(); - - return view("cart", ["cart" => $cart, "cart_items" => $cart_items]); - } else { - $cart = $this->store(); - $cart_items = $cart->shoppingCartItems()->orderBy("id", "desc")->get()->all(); - - return view("cart", ["cart" => $cart, "cart_items" => $cart_items]); - } - */ - return view("cart", ["cart" => $cart, "cart_items" => $cart_items, "trend_items" => $products]); } diff --git a/ecommerce-app/app/Http/Controllers/CategoryController.php b/ecommerce-app/app/Http/Controllers/CategoryController.php index 4df754f..14c2b1e 100644 --- a/ecommerce-app/app/Http/Controllers/CategoryController.php +++ b/ecommerce-app/app/Http/Controllers/CategoryController.php @@ -2,9 +2,8 @@ namespace App\Http\Controllers; -use Illuminate\Http\Request; use App\Models\ProductCategory; -use App\Http\Requests\CategoryRequest; +use Illuminate\Http\Request; class CategoryController extends Controller { @@ -13,6 +12,12 @@ class CategoryController extends Controller // $categories = ProductCategory::all(); // return view('admin.categories.index',compact('categories')); // } + public function index() + { + $categories = ProductCategory::all(); + + return view('admin.categories.index', compact('categories')); + } public function create() { @@ -32,7 +37,8 @@ public function store(CategoryRequest $request) public function edit($id) { $category = ProductCategory::findOrFail($id); - return view('admin.categories.edit',compact('category')); + + return view('admin.categories.edit', compact('category')); } public function update(CategoryRequest $request, $id) @@ -43,8 +49,8 @@ public function update(CategoryRequest $request, $id) $category->update($validated); - return redirect()->route('/admin') - ->with('success','Category updated successfully'); + return redirect()->route('categories.index') + ->with('success', 'Category updated successfully'); } public function destroy($id) @@ -52,7 +58,7 @@ public function destroy($id) $category = ProductCategory::findOrFail($id); $category->delete(); - return redirect()->route('/admin') - ->with('success','Category deleted successfully'); + return redirect()->route('categories.index') + ->with('success', 'Category deleted successfully'); } } diff --git a/ecommerce-app/app/Http/Controllers/DashboardController.php b/ecommerce-app/app/Http/Controllers/DashboardController.php index 051a0c3..181f3a3 100644 --- a/ecommerce-app/app/Http/Controllers/DashboardController.php +++ b/ecommerce-app/app/Http/Controllers/DashboardController.php @@ -1,109 +1,109 @@ withAvg('userReviews', 'rating') - ->withCount('userReviews'); - $trendingProducts = Product::with('userReviews') - ->withAvg('userReviews', 'rating') - ->withCount('userReviews') - ->get() - ->sortByDesc('user_reviews_avg_rating') // Sort by average rating (highest first) - ->take(6); // Limit the trending products to 6 items - $categories = ProductCategory::withCount('products')->get(); - $sort = $request->input('sort'); - switch ($sort) { - case 'az': - $query->orderBy('name', 'ASC'); - break; - case 'za': - $query->orderBy('name', 'DESC'); - break; - case 'low-high': - $query->orderBy('price', 'ASC'); - break; - case 'high-low': - $query->orderBy('price', 'DESC'); - break; - case 'rating-low-high': - $query->orderBy('user_reviews_avg_rating', 'asc'); - break; - case 'rating-high-low': - $query->orderBy('user_reviews_avg_rating', 'desc'); - break; - } - $filterCategories = $request->input('categories'); - if ($filterCategories && is_array($filterCategories)) { - $query->whereIn('product_category_id', $filterCategories); - } - - $search = $request->input('search'); - - - - - // Filter by category - - if ($search) - { - $query->where('name', 'LIKE', '%' . $search . '%'); - } - - - // them truong rating khi lay data sp - // case $sortRating === 'low-high': - // $query->orderBy('rating', 'asc'); - // break; - // case $sortRating === 'high-low': - // $query->orderBy('rating', 'desc'); - // break; - - - $products = $query->paginate(15);; - $recentlyViewedProducts = collect(); - if (Auth::check()) { - $recentlyViewedProducts = ViewedProduct::where('user_id', Auth::id()) - ->with('product') - ->orderBy('viewed_at', 'desc') - ->take(5) - ->get(); - } - return view('dashboard', [ - 'products' => $products, - 'categories' => $categories, - 'recentlyViewedProducts' => $recentlyViewedProducts, - 'trendingProducts' => $trendingProducts, - ]); + $query = Product::with('category') + ->withAvg('userReviews', 'rating') + ->withCount('userReviews'); + $trendingProducts = Product::with('userReviews') + ->withAvg('userReviews', 'rating') + ->withCount('userReviews') + ->get() + ->sortByDesc('user_reviews_avg_rating') // Sort by average rating (highest first) + ->take(6); // Limit the trending products to 6 items + $categories = ProductCategory::withCount('products')->get(); + $sort = $request->input('sort'); + switch ($sort) { + case 'az': + $query->orderBy('name', 'ASC'); + break; + case 'za': + $query->orderBy('name', 'DESC'); + break; + case 'low-high': + $query->orderBy('price', 'ASC'); + break; + case 'high-low': + $query->orderBy('price', 'DESC'); + break; + case 'rating-low-high': + $query->orderBy('user_reviews_avg_rating', 'asc'); + break; + case 'rating-high-low': + $query->orderBy('user_reviews_avg_rating', 'desc'); + break; } + $filterCategories = $request->input('categories'); + if ($filterCategories && is_array($filterCategories)) { + $query->whereIn('product_category_id', $filterCategories); + } + + $search = $request->input('search'); - public function search(Request $request) - { - $search = $request->input('search'); - if ($search) - { - $products = DB::table('products')->where('name', $search)->get(); - return view('dashboard', [ - 'products' => $products, - ]); - } - $products = Product::all(); + + // Filter by category + + if ($search) { + $query->where('name', 'LIKE', '%' . $search . '%'); + } + + + // them truong rating khi lay data sp + // case $sortRating === 'low-high': + // $query->orderBy('rating', 'asc'); + // break; + // case $sortRating === 'high-low': + // $query->orderBy('rating', 'desc'); + // break; + + + $products = $query->paginate(15); + ; + $recentlyViewedProducts = collect(); + if (Auth::check()) { + $recentlyViewedProducts = ViewedProduct::where('user_id', Auth::id()) + ->with('product') + ->orderBy('viewed_at', 'desc') + ->take(5) + ->get(); + } + return view('dashboard', [ + 'products' => $products, + 'categories' => $categories, + 'recentlyViewedProducts' => $recentlyViewedProducts, + 'trendingProducts' => $trendingProducts, + ]); + } + + public function search(Request $request) + { + $search = $request->input('search'); + + if ($search) { + $products = DB::table('products')->where('name', $search)->get(); return view('dashboard', [ 'products' => $products, ]); } + + $products = Product::all(); + return view('dashboard', [ + 'products' => $products, + ]); } +} + diff --git a/ecommerce-app/app/Http/Controllers/GoogleAuthController.php b/ecommerce-app/app/Http/Controllers/GoogleAuthController.php new file mode 100644 index 0000000..1ed6f28 --- /dev/null +++ b/ecommerce-app/app/Http/Controllers/GoogleAuthController.php @@ -0,0 +1,49 @@ +redirect(); + } + + public function callbackGoogle() + { + try { + $google_user = Socialite::driver('google')->user(); + $user = User::where('google_id', $google_user->getId())->first(); + + if (!$user) { + $new_user = User::create([ + 'username' => $google_user->getName(), + 'password' => Hash::make('123456789'), + 'first_name' => "", + 'last_name' => "", + 'email' => $google_user->getEmail(), + 'google_id' => $google_user->getId(), + 'telephone' => "", + ]); + + Auth::login($new_user); + + return redirect()->intended('dashboard'); + } else { + Auth::login($user); + + return redirect()->intended('dashboard'); + } + } catch (\Throwable $th) { + dd("Something went wrong!" . $th->getMessage()); + } + } +} diff --git a/ecommerce-app/app/Http/Controllers/HomeController.php b/ecommerce-app/app/Http/Controllers/HomeController.php index 073252f..1d1a419 100644 --- a/ecommerce-app/app/Http/Controllers/HomeController.php +++ b/ecommerce-app/app/Http/Controllers/HomeController.php @@ -3,23 +3,21 @@ namespace App\Http\Controllers; use App\Models\Product; -use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class HomeController extends Controller { - function __construct() - { + public function __construct() {} - } - public function index() { $products = Product::with('userReviews') ->withAvg('userReviews', 'rating') ->withCount('userReviews') - ->get() - ->sortByDesc(['trendRating']); + // ->orderByDesc(['trendRating']) + ->paginate(20); + + // dd($products->toArray()); return view('home', [ 'user' => Auth::user(), diff --git a/ecommerce-app/app/Http/Controllers/OrderController.php b/ecommerce-app/app/Http/Controllers/OrderController.php index 607edf7..86d405f 100644 --- a/ecommerce-app/app/Http/Controllers/OrderController.php +++ b/ecommerce-app/app/Http/Controllers/OrderController.php @@ -2,12 +2,71 @@ namespace App\Http\Controllers; +use App\Models\OrderDetail; +use App\Models\OrderItem; +use App\Models\OrderStatus; +use App\Models\User; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; use Illuminate\View\View; +use Symfony\Component\HttpFoundation\RedirectResponse; class OrderController extends Controller { public function index(): View { - return view('orders.index'); + // TODO: Replace this with the authenticated user + // $user = Auth::user(); + $user = User::all()->random(); + $orderItems = $user->shoppingCarts->first()->shoppingCartItems; + $defaultAddress = $user->userAddresses->where('is_default', true)->first()->address; + + $totalPrice = $orderItems->sum(function ($item) { + return $item->product->price * $item->qty; + }); + + return view('components.orders.index', compact('user', 'orderItems', 'defaultAddress', 'totalPrice')); + } + + public function store(Request $request): RedirectResponse + { + $orderDetail = null; + + DB::transaction(function () use ($request, &$orderDetail) { + // dd(request()->all()); + $orderStatus = OrderStatus::create([ + 'status' => 'Pending', + ]); + + $orderDetail = OrderDetail::create([ + 'user_id' => $request->user_id, + 'address_id' => $request->address_id, + 'order_date' => $request->order_date, + 'order_total' => $request->order_total, + 'order_status_id' => $orderStatus->id, + ]); + + foreach ($request->order_items as $item) { + OrderItem::create([ + 'order_detail_id' => $orderDetail->id, + 'product_id' => $item['product_id'], + 'qty' => $item['qty'], + 'price' => $item['price'], + ]); + } + }); + + return redirect()->route('orders.confirmation', ['order_id' => $orderDetail->id]); + } + + public function showConfirmation($order_id): View + { + $orderDetail = OrderDetail::with(['user', 'address'])->findOrFail($order_id); + + return view('components.orders.confirmation', [ + 'orderDetail' => $orderDetail, + 'user' => $orderDetail->user, + 'address' => $orderDetail->address, + ]); } } diff --git a/ecommerce-app/app/Http/Controllers/ProductController.php b/ecommerce-app/app/Http/Controllers/ProductController.php index 47727ef..a78a1c1 100644 --- a/ecommerce-app/app/Http/Controllers/ProductController.php +++ b/ecommerce-app/app/Http/Controllers/ProductController.php @@ -2,30 +2,29 @@ namespace App\Http\Controllers; -use Illuminate\Http\Request; -use App\Models\Product; use App\Http\Requests\ProductRequest; +use App\Models\Product; use App\Models\ProductCategory; use App\Models\UserReview; -use App\Models\ViewedProduct; -use Illuminate\Support\Facades\Auth; +use Illuminate\Http\Request; class ProductController extends Controller { - // public function index() - // { - // $products = Product::all(); - // return view('admin.products.index', compact('products')); - // } + public function index() + { + $products = Product::all(); + + return view('admin.crud.products', compact('products')); + } public function show(Product $product) { - $userReviews = UserReview::withWhereHas('orderItem', function ($query) use ($product){ + $userReviews = UserReview::withWhereHas('orderItem', function ($query) use ($product) { $query->where('product_id', $product->id); })->get(); $userReviewCount = $userReviews->count(); $userReviewAverage = $userReviews->avg('rating'); - + return view('products.show', [ 'product' => $product, 'userReviews' => $userReviews, @@ -37,45 +36,51 @@ public function show(Product $product) public function create() { $categories = ProductCategory::all(); - return view('admin.products.create', compact('categories')); - } - - public function store(ProductRequest $request) - { - $product = new Product($request->validated()); - - if ($request->hasFile('image')) { - $product->image = $request->file('image')->store('products', 'public'); - } - $product->save(); - return redirect()->route('/admin') - ->with('success', 'Product created successfully.'); + return view('admin.products.create', compact('categories')); } public function edit(Product $product) { $categories = ProductCategory::all(); + return view('admin.products.edit', compact('product')); } public function update(ProductRequest $request, Product $product) { - $product->update($request->validated()); + Product::where('id', $product->id) + ->update([ + 'name' => $request->name, + // 'description' => $request->description, + 'price' => $request->price, + 'image_url' => $request->image_url, + 'qty_in_stock' => $request->qty_in_stock, + ]); - if ($request->hasFile('image')) { - $product->image = $request->file('image')->store('products', 'public'); - } + return redirect(route('admin.products.index')); + } + + public function store(Request $request) + { + $product = new Product(); + + $product->name = $request->name; + $product->description = $request->description; + $product->price = $request->price; + $product->image_url = $request->image_url; + $product->qty_in_stock = $request->qty_in_stock; + $product->product_category_id = '8ce2ad96-0604-4c5a-8bee-bdd91462d580'; $product->save(); - return redirect()->route('/admin') - ->with('success', 'Product updated successfully.'); + + return redirect(route('admin.products.index')); } public function destroy(Product $product) { $product->delete(); - return redirect()->route('/admin') - ->with('success', 'Product deleted successfully.'); + + return redirect(route('admin.products.index')); } } diff --git a/ecommerce-app/app/Http/Controllers/ProfileController.php b/ecommerce-app/app/Http/Controllers/ProfileController.php index 790ab2f..c60516d 100644 --- a/ecommerce-app/app/Http/Controllers/ProfileController.php +++ b/ecommerce-app/app/Http/Controllers/ProfileController.php @@ -6,11 +6,11 @@ use App\Http\Requests\ProfileUpdateRequest; -use Illuminate\Http\RedirectResponse; +use Illuminate\View\View; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Illuminate\Http\RedirectResponse; use Illuminate\Support\Facades\Redirect; -use Illuminate\View\View; class ProfileController extends Controller { @@ -30,16 +30,15 @@ public function edit(Request $request): View public function update(ProfileUpdateRequest $request): RedirectResponse { $user = User::find($request->user()->id); - $user->name = $request->name; + $user->first_name = $request->first_name; + $user->last_name = $request->last_name; $user->email = $request->email; - /* if ($request->hasFile('photo')) { $avatar = new ImageController(); $imageUrl = $avatar->storeImage($request, 'profile'); $user->photo = $imageUrl; } - */ $user->save(); diff --git a/ecommerce-app/app/Http/Controllers/UserController.php b/ecommerce-app/app/Http/Controllers/UserController.php index 3ffe64c..094620e 100644 --- a/ecommerce-app/app/Http/Controllers/UserController.php +++ b/ecommerce-app/app/Http/Controllers/UserController.php @@ -3,9 +3,7 @@ namespace App\Http\Controllers; use App\Models\User; -use App\Http\Controllers\Controller; use Illuminate\Http\Request; -use Illuminate\Support\Str; use Illuminate\Support\Facades\Hash; class UserController extends Controller @@ -13,12 +11,76 @@ class UserController extends Controller /** * Display a listing of the resource. */ - // public function index() - // { - // return view('users.index', [ - // 'users' => User::all(), - // ]); - // } + public function index() + { + return view('admin.crud.users', [ + 'users' => User::all(), + ]); + } + + public function exportCSV() + { + $filename = 'user-data.csv'; + + $headers = [ + 'Content-Type' => 'text/csv', + 'Content-Disposition' => "attachment; filename=\"$filename\"", + 'Pragma' => 'no-cache', + 'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0', + 'Expires' => '0', + ]; + + return response()->stream(function () { + $handle = fopen('php://output', 'w'); + + // Add CSV headers + fputcsv($handle, [ + 'First Name', + 'Last Name', + 'Email', + 'Phone Number', + 'Address', + ]); + + // Fetch and process data in chunks + User::query()->chunk(25, function ($users) use ($handle) { + + foreach ($users as $user) { + $addresses = $this->getAddresses($user); + $data = [ + $user->first_name ?? '', + $user->last_name ?? '', + $user->email ?? '', + $user->telephone ?? '', + $addresses, + ]; + // Write data to a CSV file. + fputcsv($handle, $data); + } + }); + + // Close CSV file handle + fclose($handle); + }, 200, $headers); + } + + private function getAddresses($user) + { + if (! isset($user->userAddresses)) { + return []; + } + + return $user->userAddresses->map(function ($address) { + return implode(', ', array_filter([ + $address->address->address_line1 ?? '', + $address->address->address_line2 ?? '', + $address->address->city ?? '', + $address->address->state ?? '', + $address->address->country->country_name ?? '', + $address->address->postal_code ?? '', + ])); + })->implode('; '); + } /** * Show the form for creating a new resource. @@ -33,8 +95,7 @@ public function create() */ public function store(Request $request) { - $user = new User; - $user->id = Str::uuid(); + $user = new User(); $user->first_name = $request->first_name; $user->last_name = $request->last_name; $user->username = $request->username; @@ -42,8 +103,11 @@ public function store(Request $request) $user->password = Hash::make($request->password); $user->telephone = $request->telephone; $user->is_admin = false; + $user->email_verified_at = now(); + $user->remember_token = fake()->randomNumber(8); $user->save(); - return redirect('/admin'); + + return redirect(route('admin.users.index')); } /** @@ -67,14 +131,27 @@ public function edit(User $user) */ public function update(Request $request, User $user) { - User::where('id', $user->id) + User::query()->where('id', $user->id) ->update([ 'first_name' => $request->first_name, 'last_name' => $request->last_name, 'username' => $request->username, + 'email' => $request->email, 'telephone' => $request->telephone, + 'password' => Hash::make($request->new_password), + ]); + + return redirect(route('admin.users.index')); + } + + public function toggleStatus(User $user) + { + User::query()->where('id', $user->id) + ->update([ + 'is_active' => ! ($user->is_active), ]); - return redirect('/admin'); + + return redirect(route('admin.users.index')); } /** @@ -84,6 +161,6 @@ public function destroy(User $user) { $user->delete(); - return redirect('/admin'); + return redirect(route('admin.users.index')); } } diff --git a/ecommerce-app/app/Http/Middleware/CheckAdmin.php b/ecommerce-app/app/Http/Middleware/CheckAdmin.php index f52fd60..68bd71e 100644 --- a/ecommerce-app/app/Http/Middleware/CheckAdmin.php +++ b/ecommerce-app/app/Http/Middleware/CheckAdmin.php @@ -4,6 +4,7 @@ use Closure; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; use Symfony\Component\HttpFoundation\Response; class CheckAdmin @@ -15,12 +16,12 @@ class CheckAdmin */ public function handle(Request $request, Closure $next): Response { - $user = auth()->user(); + $user = Auth::user(); if ($user && $user->is_admin) { return $next($request); } - abort(401); + abort(403, 'Unauthorized action.'); } } diff --git a/ecommerce-app/app/Http/Requests/ProductRequest.php b/ecommerce-app/app/Http/Requests/ProductRequest.php index 4fd35d6..f9898b0 100644 --- a/ecommerce-app/app/Http/Requests/ProductRequest.php +++ b/ecommerce-app/app/Http/Requests/ProductRequest.php @@ -2,6 +2,7 @@ namespace App\Http\Requests; +use Illuminate\Contracts\Validation\ValidationRule; use Illuminate\Foundation\Http\FormRequest; class ProductRequest extends FormRequest @@ -17,38 +18,39 @@ public function authorize(): bool /** * Get the validation rules that apply to the request. * - * @return array|string> + * @return array|string> */ - public function rules(): array - { - return [ - 'name' => 'required|string|max:255', - 'description' => 'required|string', - 'image' => 'required|url', - 'qty_in_stock' => 'required|integer|min:0', - 'category_id' => 'required|exists:product_categories,id', - 'price' => 'required|numeric|min:0', - ]; - } +// public function rules(): array +// { +// return [ +// 'name' => 'required|string|max:255', +// 'description' => 'required|string', +// 'image_url' => 'required|url', +// 'qty_in_stock' => 'required|integer|min:0', +//// 'category_id' => 'required|exists:product_categories,id', +// 'price' => 'required|numeric|min:0', +// ]; +// } +// +// public function messages(): array +// { +// return [ +// 'name.required' => 'The name field is required.', +// 'name.max' => 'The name field must not exceed 255 characters.', +// 'name.string' => 'The name field must be a string.', +// 'description.required' => 'The description field is required.', +// 'description.string' => 'The description field must be a string.', +// 'image.required' => 'The image field is required.', +// 'image.url' => 'The image field must be a valid URL.', +// 'qty_in_stock.required' => 'The quantity in stock field is required.', +// 'qty_in_stock.integer' => 'The quantity in stock field must be an integer.', +// 'qty_in_stock.min' => 'The quantity in stock field must be at least 0.', +// 'category_id.exists' => 'The selected category is invalid.', +// 'category_id.required' => 'The category field is required.', +// 'price.required' => 'The price field is required.', +// 'price.numeric' => 'The price field must be a number.', +// 'price.min' => 'The price field must be at least 0.', +// ]; +// } - public function messages(): array - { - return [ - 'name.required' => 'The name field is required.', - 'name.max' => 'The name field must not exceed 255 characters.', - 'name.string' => 'The name field must be a string.', - 'description.required' => 'The description field is required.', - 'description.string' => 'The description field must be a string.', - 'image.required' => 'The image field is required.', - 'image.url' => 'The image field must be a valid URL.', - 'qty_in_stock.required' => 'The quantity in stock field is required.', - 'qty_in_stock.integer' => 'The quantity in stock field must be an integer.', - 'qty_in_stock.min' => 'The quantity in stock field must be at least 0.', - 'category_id.exists' => 'The selected category is invalid.', - 'category_id.required' => 'The category field is required.', - 'price.required' => 'The price field is required.', - 'price.numeric' => 'The price field must be a number.', - 'price.min' => 'The price field must be at least 0.', - ]; - } } diff --git a/ecommerce-app/app/Http/Requests/ProfileUpdateRequest.php b/ecommerce-app/app/Http/Requests/ProfileUpdateRequest.php index 93b0022..287b951 100644 --- a/ecommerce-app/app/Http/Requests/ProfileUpdateRequest.php +++ b/ecommerce-app/app/Http/Requests/ProfileUpdateRequest.php @@ -11,12 +11,13 @@ class ProfileUpdateRequest extends FormRequest /** * Get the validation rules that apply to the request. * - * @return array + * @return array|string> */ public function rules(): array { return [ - 'name' => ['required', 'string', 'max:255'], + 'first_name' => ['required', 'string', 'max:255'], + 'last_name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'lowercase', 'email', 'max:255', Rule::unique(User::class)->ignore($this->user()->id)], ]; } diff --git a/ecommerce-app/app/Models/Address.php b/ecommerce-app/app/Models/Address.php index 216c604..7aef03d 100644 --- a/ecommerce-app/app/Models/Address.php +++ b/ecommerce-app/app/Models/Address.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Support\Str; class Address extends Model @@ -20,4 +21,9 @@ public static function booted(): void $address->id = Str::uuid(); }); } + + public function country(): HasOne + { + return $this->hasOne(Country::class); + } } diff --git a/ecommerce-app/app/Models/OrderDetail.php b/ecommerce-app/app/Models/OrderDetail.php index 03954af..91f0c2f 100644 --- a/ecommerce-app/app/Models/OrderDetail.php +++ b/ecommerce-app/app/Models/OrderDetail.php @@ -5,9 +5,8 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; -use Illuminate\Support\Str; use Illuminate\Database\Eloquent\Relations\HasMany; -use Illuminate\Database\Eloquent\Relations\HasManyThrough; +use Illuminate\Support\Str; class OrderDetail extends Model { @@ -17,16 +16,18 @@ class OrderDetail extends Model protected $keyType = 'string'; + protected $guarded = []; + + protected $casts = [ + 'id' => 'string', + ]; + public static function booted(): void { static::creating(function (OrderDetail $orderDetail) { $orderDetail->id = Str::uuid(); }); } - - protected $casts = [ - 'id' => 'string' - ]; public function orderItems(): HasMany { @@ -34,12 +35,17 @@ public function orderItems(): HasMany } public function status(): BelongsTo - { + { return $this->belongsTo(OrderStatus::class, 'order_status_id'); } - public function user(): BelongsTo + public function user() + { + return $this->belongsTo(User::class); + } + + public function address() { - return $this->belongsTo(User::class, 'user_id'); + return $this->belongsTo(Address::class); } } diff --git a/ecommerce-app/app/Models/OrderItem.php b/ecommerce-app/app/Models/OrderItem.php index 2537f73..1858192 100644 --- a/ecommerce-app/app/Models/OrderItem.php +++ b/ecommerce-app/app/Models/OrderItem.php @@ -12,6 +12,8 @@ class OrderItem extends Model { use HasFactory; + protected $guarded = []; + public function userReview(): HasOne { return $this->hasOne(UserReview::class); diff --git a/ecommerce-app/app/Models/OrderStatus.php b/ecommerce-app/app/Models/OrderStatus.php index d229ac8..2af928c 100644 --- a/ecommerce-app/app/Models/OrderStatus.php +++ b/ecommerce-app/app/Models/OrderStatus.php @@ -15,6 +15,8 @@ class OrderStatus extends Model protected $keyType = 'string'; + protected $guarded = []; + public static function booted(): void { static::creating(function (OrderStatus $orderStatus) { diff --git a/ecommerce-app/app/Models/Product.php b/ecommerce-app/app/Models/Product.php index bba1498..9f8e5c8 100644 --- a/ecommerce-app/app/Models/Product.php +++ b/ecommerce-app/app/Models/Product.php @@ -5,9 +5,10 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; -use Illuminate\Database\Eloquent\Model; + use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; + use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Illuminate\Support\Str; @@ -18,14 +19,7 @@ class Product extends Model public $incrementing = false; - protected $fillable = [ - 'name', - 'description', - 'image', - 'qty_in_stock', - 'category_id', - 'price', - ]; + protected $guarded = []; protected $keyType = 'string'; @@ -36,7 +30,7 @@ public static function booted(): void }); } - public function category(): BelongsTo + public function categories(): BelongsTo { return $this->belongsTo(ProductCategory::class, 'product_category_id'); } diff --git a/ecommerce-app/app/Models/ProductCategory.php b/ecommerce-app/app/Models/ProductCategory.php index b980ce6..3c76ab1 100644 --- a/ecommerce-app/app/Models/ProductCategory.php +++ b/ecommerce-app/app/Models/ProductCategory.php @@ -31,9 +31,4 @@ public static function booted(): void $productCategory->id = Str::uuid(); }); } - - public function products(): HasMany - { - return $this->hasMany(Product::class,'product_category_id'); - } } diff --git a/ecommerce-app/app/Models/ShoppingCart.php b/ecommerce-app/app/Models/ShoppingCart.php index 1ea8bca..dbbf142 100644 --- a/ecommerce-app/app/Models/ShoppingCart.php +++ b/ecommerce-app/app/Models/ShoppingCart.php @@ -2,12 +2,11 @@ namespace App\Models; -use Illuminate\Support\Str; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; - use Illuminate\Database\Eloquent\Relations\HasMany; -use Illuminate\Database\Eloquent\Relations\BelongsToMany; +use Illuminate\Support\Str; + class ShoppingCart extends Model { @@ -38,5 +37,3 @@ public static function booted(): void }); } } - - diff --git a/ecommerce-app/app/Models/ShoppingCartItem.php b/ecommerce-app/app/Models/ShoppingCartItem.php index 13241fd..88bfb7c 100644 --- a/ecommerce-app/app/Models/ShoppingCartItem.php +++ b/ecommerce-app/app/Models/ShoppingCartItem.php @@ -2,12 +2,10 @@ namespace App\Models; -use Illuminate\Support\Str; - -use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; - +use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Support\Str; class ShoppingCartItem extends Model { @@ -24,17 +22,15 @@ public function cart(): BelongsTo return $this->belongsTo(ShoppingCart::class, 'shopping_cart_id'); } - public function product(): Product - { - return $this->belongsTo(Product::class, 'product_id')->first(); - } - public static function booted(): void { static::creating(function (ShoppingCartItem $shoppingCartItem) { $shoppingCartItem->id = Str::uuid(); }); } -} - + public function product(): BelongsTo + { + return $this->belongsTo(Product::class); + } +} diff --git a/ecommerce-app/app/Models/UserAddress.php b/ecommerce-app/app/Models/UserAddress.php index 40fc5a7..0d59715 100644 --- a/ecommerce-app/app/Models/UserAddress.php +++ b/ecommerce-app/app/Models/UserAddress.php @@ -28,4 +28,9 @@ public function users(): BelongsTo { return $this->belongsTo(User::class); } + + public function address(): BelongsTo + { + return $this->belongsTo(Address::class); + } } diff --git a/ecommerce-app/app/Providers/AppServiceProvider.php b/ecommerce-app/app/Providers/AppServiceProvider.php index c3b0493..c6123a7 100644 --- a/ecommerce-app/app/Providers/AppServiceProvider.php +++ b/ecommerce-app/app/Providers/AppServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use Illuminate\Database\Eloquent\Model; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -19,7 +20,6 @@ public function register(): void */ public function boot(): void { - // - + // Model::preventLazyLoading(); } } diff --git a/ecommerce-app/composer.json b/ecommerce-app/composer.json index 06b375c..086f98a 100644 --- a/ecommerce-app/composer.json +++ b/ecommerce-app/composer.json @@ -7,9 +7,10 @@ "require": { "php": "^8.2", "laravel/framework": "^11.9", - "laravel/tinker": "^2.9", "resend/resend-php": "^0.13.0", - "symfony/mailgun-mailer": "^7.1" + "symfony/mailgun-mailer": "^7.1", + "laravel/socialite": "^5.16", + "laravel/tinker": "^2.9" }, "require-dev": { "barryvdh/laravel-debugbar": "^3.13", diff --git a/ecommerce-app/composer.lock b/ecommerce-app/composer.lock index f806921..6df4714 100644 --- a/ecommerce-app/composer.lock +++ b/ecommerce-app/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3c942aa3b639c635630a53d46220c4ef", + "content-hash": "521ccf077a17f584a466f7c06430aa62", "packages": [ { "name": "brick/math", @@ -506,6 +506,69 @@ ], "time": "2023-10-06T06:47:41+00:00" }, + { + "name": "firebase/php-jwt", + "version": "v6.10.1", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "500501c2ce893c824c801da135d02661199f60c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/500501c2ce893c824c801da135d02661199f60c5", + "reference": "500501c2ce893c824c801da135d02661199f60c5", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.4", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^2.0||^3.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.10.1" + }, + "time": "2024-05-18T18:05:11+00:00" + }, { "name": "fruitcake/php-cors", "version": "v1.3.0", @@ -1375,6 +1438,78 @@ }, "time": "2024-08-02T07:48:17+00:00" }, + { + "name": "laravel/socialite", + "version": "v5.16.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/socialite.git", + "reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/socialite/zipball/40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf", + "reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf", + "shasum": "" + }, + "require": { + "ext-json": "*", + "firebase/php-jwt": "^6.4", + "guzzlehttp/guzzle": "^6.0|^7.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "league/oauth1-client": "^1.10.1", + "php": "^7.2|^8.0", + "phpseclib/phpseclib": "^3.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0|^8.0|^9.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.0|^9.3|^10.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Socialite\\SocialiteServiceProvider" + ], + "aliases": { + "Socialite": "Laravel\\Socialite\\Facades\\Socialite" + } + } + }, + "autoload": { + "psr-4": { + "Laravel\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.", + "homepage": "https://laravel.com", + "keywords": [ + "laravel", + "oauth" + ], + "support": { + "issues": "https://github.com/laravel/socialite/issues", + "source": "https://github.com/laravel/socialite" + }, + "time": "2024-09-03T09:46:57+00:00" + }, { "name": "laravel/tinker", "version": "v2.9.0", @@ -1817,6 +1952,82 @@ ], "time": "2024-01-28T23:22:08+00:00" }, + { + "name": "league/oauth1-client", + "version": "v1.10.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth1-client.git", + "reference": "d6365b901b5c287dd41f143033315e2f777e1167" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/d6365b901b5c287dd41f143033315e2f777e1167", + "reference": "d6365b901b5c287dd41f143033315e2f777e1167", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "guzzlehttp/psr7": "^1.7|^2.0", + "php": ">=7.1||>=8.0" + }, + "require-dev": { + "ext-simplexml": "*", + "friendsofphp/php-cs-fixer": "^2.17", + "mockery/mockery": "^1.3.3", + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5||9.5" + }, + "suggest": { + "ext-simplexml": "For decoding XML-based responses." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev", + "dev-develop": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth1\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Corlett", + "email": "bencorlett@me.com", + "homepage": "http://www.webcomm.com.au", + "role": "Developer" + } + ], + "description": "OAuth 1.0 Client Library", + "keywords": [ + "Authentication", + "SSO", + "authorization", + "bitbucket", + "identity", + "idp", + "oauth", + "oauth1", + "single sign on", + "trello", + "tumblr", + "twitter" + ], + "support": { + "issues": "https://github.com/thephpleague/oauth1-client/issues", + "source": "https://github.com/thephpleague/oauth1-client/tree/v1.10.1" + }, + "time": "2022-04-15T14:02:14+00:00" + }, { "name": "monolog/monolog", "version": "3.7.0", @@ -2318,6 +2529,123 @@ ], "time": "2024-03-06T16:17:14+00:00" }, + { + "name": "paragonie/constant_time_encoding", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "df1e7fde177501eee2037dd159cf04f5f301a512" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/df1e7fde177501eee2037dd159cf04f5f301a512", + "reference": "df1e7fde177501eee2037dd159cf04f5f301a512", + "shasum": "" + }, + "require": { + "php": "^8" + }, + "require-dev": { + "phpunit/phpunit": "^9", + "vimeo/psalm": "^4|^5" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2024-05-08T12:36:18+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.3", @@ -2393,6 +2721,116 @@ ], "time": "2024-07-20T21:41:07+00:00" }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.41", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "621c73f7dcb310b61de34d1da4c4204e8ace6ceb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/621c73f7dcb310b61de34d1da4c4204e8ace6ceb", + "reference": "621c73f7dcb310b61de34d1da4c4204e8ace6ceb", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2|^3", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.41" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2024-08-12T00:13:54+00:00" + }, { "name": "psr/clock", "version": "1.0.0", @@ -5681,7 +6119,53 @@ ], "packages-dev": [ { - "name": "barryvdh/laravel-debugbar", + "name": "archtechx/enums", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/archtechx/enums.git", + "reference": "37326d5e26cdfcc2810f4664cdd625ea4fd528d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/archtechx/enums/zipball/37326d5e26cdfcc2810f4664cdd625ea4fd528d7", + "reference": "37326d5e26cdfcc2810f4664cdd625ea4fd528d7", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "larastan/larastan": "^2.4", + "orchestra/testbench": "^8.0", + "pestphp/pest": "^2.0", + "pestphp/pest-plugin-laravel": "^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "ArchTech\\Enums\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Samuel Štancl", + "email": "samuel@archte.ch" + } + ], + "description": "Helpers for making PHP enums more lovable.", + "support": { + "issues": "https://github.com/archtechx/enums/issues", + "source": "https://github.com/archtechx/enums/tree/v1.1.0" + }, + "time": "2024-07-15T14:28:34+00:00" + }, + { + "name": "barryvdh/laravel-debugbar", "version": "v3.13.5", "source": { "type": "git", @@ -5858,6 +6342,239 @@ ], "time": "2024-02-20T07:24:02+00:00" }, + { + "name": "composer/class-map-generator", + "version": "1.3.4", + "source": { + "type": "git", + "url": "https://github.com/composer/class-map-generator.git", + "reference": "b1b3fd0b4eaf3ddf3ee230bc340bf3fff454a1a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/b1b3fd0b4eaf3ddf3ee230bc340bf3fff454a1a3", + "reference": "b1b3fd0b4eaf3ddf3ee230bc340bf3fff454a1a3", + "shasum": "" + }, + "require": { + "composer/pcre": "^2.1 || ^3.1", + "php": "^7.2 || ^8.0", + "symfony/finder": "^4.4 || ^5.3 || ^6 || ^7" + }, + "require-dev": { + "phpstan/phpstan": "^1.6", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/filesystem": "^5.4 || ^6", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\ClassMapGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Utilities to scan PHP code and generate class maps.", + "keywords": [ + "classmap" + ], + "support": { + "issues": "https://github.com/composer/class-map-generator/issues", + "source": "https://github.com/composer/class-map-generator/tree/1.3.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-06-12T14:13:04+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.1", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.11.10", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.1" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-08-27T18:44:43+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6", + "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-07-12T11:35:52+00:00" + }, { "name": "doctrine/deprecations", "version": "1.1.3", @@ -5906,45 +6623,1277 @@ "time": "2024-01-30T19:34:25+00:00" }, { - "name": "fakerphp/faker", - "version": "v1.23.1", + "name": "dragon-code/contracts", + "version": "2.23.0", "source": { "type": "git", - "url": "https://github.com/FakerPHP/Faker.git", - "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b" + "url": "https://github.com/TheDragonCode/contracts.git", + "reference": "44dbad923f152e0dc2699fbac2d33b65dd6a8f7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b", - "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b", + "url": "https://api.github.com/repos/TheDragonCode/contracts/zipball/44dbad923f152e0dc2699fbac2d33b65dd6a8f7d", + "reference": "44dbad923f152e0dc2699fbac2d33b65dd6a8f7d", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-message": "^1.0.1 || ^2.0", + "symfony/http-kernel": "^4.0 || ^5.0 || ^6.0 || ^7.0", + "symfony/polyfill-php80": "^1.23" + }, + "conflict": { + "andrey-helldar/contracts": "*" + }, + "require-dev": { + "illuminate/database": "^10.0 || ^11.0", + "phpdocumentor/reflection-docblock": "^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "DragonCode\\Contracts\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro", + "homepage": "https://dragon-code.pro" + } + ], + "description": "A set of contracts for any project", + "keywords": [ + "contracts", + "interfaces" + ], + "support": { + "source": "https://github.com/TheDragonCode/contracts" + }, + "funding": [ + { + "url": "https://boosty.to/dragon-code", + "type": "boosty" + }, + { + "url": "https://www.donationalerts.com/r/dragon_code", + "type": "donationalerts" + }, + { + "url": "https://yoomoney.ru/to/410012608840929", + "type": "yoomoney" + } + ], + "time": "2024-03-11T20:15:12+00:00" + }, + { + "name": "dragon-code/pretty-array", + "version": "v4.1.0", + "source": { + "type": "git", + "url": "https://github.com/TheDragonCode/pretty-array.git", + "reference": "6c84e2454491b414efbd37985c322712cdf9012f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TheDragonCode/pretty-array/zipball/6c84e2454491b414efbd37985c322712cdf9012f", + "reference": "6c84e2454491b414efbd37985c322712cdf9012f", + "shasum": "" + }, + "require": { + "dragon-code/contracts": "^2.20", + "dragon-code/support": "^6.11.2", + "ext-dom": "*", + "ext-mbstring": "*", + "php": "^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^10.2" + }, + "suggest": { + "symfony/thanks": "Give thanks (in the form of a GitHub) to your fellow PHP package maintainers" + }, + "type": "library", + "autoload": { + "psr-4": { + "DragonCode\\PrettyArray\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro", + "homepage": "https://github.com/andrey-helldar" + } + ], + "description": "Simple conversion of an array to a pretty view", + "keywords": [ + "andrey helldar", + "array", + "dragon", + "dragon code", + "pretty", + "pretty array" + ], + "support": { + "issues": "https://github.com/TheDragonCode/pretty-array/issues", + "source": "https://github.com/TheDragonCode/pretty-array" + }, + "funding": [ + { + "url": "https://boosty.to/dragon-code", + "type": "boosty" + }, + { + "url": "https://github.com/sponsors/TheDragonCode", + "type": "github" + }, + { + "url": "https://opencollective.com/dragon-code", + "type": "open_collective" + }, + { + "url": "https://yoomoney.ru/to/410012608840929", + "type": "yoomoney" + } + ], + "time": "2023-06-02T11:37:44+00:00" + }, + { + "name": "dragon-code/support", + "version": "6.15.0", + "source": { + "type": "git", + "url": "https://github.com/TheDragonCode/support.git", + "reference": "087d7baaa963cdbb24e901dc27e10cdc31c2529c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TheDragonCode/support/zipball/087d7baaa963cdbb24e901dc27e10cdc31c2529c", + "reference": "087d7baaa963cdbb24e901dc27e10cdc31c2529c", + "shasum": "" + }, + "require": { + "dragon-code/contracts": "^2.22.0", + "ext-bcmath": "*", + "ext-ctype": "*", + "ext-dom": "*", + "ext-json": "*", + "ext-mbstring": "*", + "php": "^8.1", + "psr/http-message": "^1.0.1 || ^2.0", + "symfony/polyfill-php81": "^1.25", + "voku/portable-ascii": "^1.4.8 || ^2.0.1" + }, + "conflict": { + "andrey-helldar/support": "*" + }, + "require-dev": { + "illuminate/contracts": "^9.0 || ^10.0 || ^11.0", + "phpunit/phpunit": "^9.6 || ^11.0", + "symfony/var-dumper": "^6.0 || ^7.0" + }, + "suggest": { + "dragon-code/laravel-support": "Various helper files for the Laravel and Lumen frameworks", + "symfony/thanks": "Give thanks (in the form of a GitHub) to your fellow PHP package maintainers" + }, + "type": "library", + "extra": { + "dragon-code": { + "docs-generator": { + "preview": { + "brand": "php", + "vendor": "The Dragon Code" + } + } + } + }, + "autoload": { + "psr-4": { + "DragonCode\\Support\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro", + "homepage": "https://dragon-code.pro" + } + ], + "description": "Support package is a collection of helpers and tools for any project.", + "keywords": [ + "dragon", + "dragon-code", + "framework", + "helper", + "helpers", + "laravel", + "php", + "support", + "symfony", + "yii", + "yii2" + ], + "support": { + "issues": "https://github.com/TheDragonCode/support/issues", + "source": "https://github.com/TheDragonCode/support" + }, + "funding": [ + { + "url": "https://boosty.to/dragon-code", + "type": "boosty" + }, + { + "url": "https://www.donationalerts.com/r/dragon_code", + "type": "donationalerts" + }, + { + "url": "https://yoomoney.ru/to/410012608840929", + "type": "yoomoney" + } + ], + "time": "2024-09-07T13:27:37+00:00" + }, + { + "name": "fakerphp/faker", + "version": "v1.23.1", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b", + "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "phpunit/phpunit": "^9.5.26", + "symfony/phpunit-bridge": "^5.4.16" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1" + }, + "time": "2024-01-02T13:46:09+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-02-07T09:43:46+00:00" + }, + { + "name": "filp/whoops", + "version": "2.15.4", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546", + "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546", + "shasum": "" + }, + "require": { + "php": "^5.5.9 || ^7.0 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^0.9 || ^1.0", + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.15.4" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2023-11-03T12:00:00+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + }, + "time": "2020-07-09T08:09:16+00:00" + }, + { + "name": "jean85/pretty-package-versions", + "version": "2.0.6", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/f9fdd29ad8e6d024f52678b570e5593759b550b4", + "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^7.5|^8.5|^9.4", + "vimeo/psalm": "^4.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A library to get pretty versions strings of installed dependencies", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.6" + }, + "time": "2024-03-08T09:58:59+00:00" + }, + { + "name": "laravel-lang/actions", + "version": "1.8.5", + "source": { + "type": "git", + "url": "https://github.com/Laravel-Lang/actions.git", + "reference": "bc59d4a92e13d35d07a45265552a830c47fbe878" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Laravel-Lang/actions/zipball/bc59d4a92e13d35d07a45265552a830c47fbe878", + "reference": "bc59d4a92e13d35d07a45265552a830c47fbe878", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel-lang/publisher": "^14.0 || ^15.0 || ^16.0", + "php": "^8.1" + }, + "require-dev": { + "laravel-lang/status-generator": "^2.3.1", + "phpunit/phpunit": "^10.0", + "symfony/var-dumper": "^6.3 || ^7.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "LaravelLang\\Actions\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "LaravelLang\\Actions\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro", + "homepage": "https://dragon-code.pro" + }, + { + "name": "Laravel Lang Team", + "homepage": "https://laravel-lang.com" + } + ], + "description": "Translation of buttons and other action elements", + "keywords": [ + "actions", + "buttons", + "lang", + "languages", + "laravel", + "translations" + ], + "support": { + "issues": "https://github.com/Laravel-Lang/actions/issues", + "source": "https://github.com/Laravel-Lang/actions/tree/1.8.5" + }, + "time": "2024-09-07T11:55:41+00:00" + }, + { + "name": "laravel-lang/attributes", + "version": "2.10.8", + "source": { + "type": "git", + "url": "https://github.com/Laravel-Lang/attributes.git", + "reference": "cf53eb18a47692045ac135e5be1e3fa979232504" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Laravel-Lang/attributes/zipball/cf53eb18a47692045ac135e5be1e3fa979232504", + "reference": "cf53eb18a47692045ac135e5be1e3fa979232504", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel-lang/publisher": "^14.0 || ^15.0 || ^16.0", + "php": "^8.1" + }, + "require-dev": { + "laravel-lang/status-generator": "^1.19 || ^2.0", + "phpunit/phpunit": "^10.0", + "symfony/var-dumper": "^6.0 || ^7.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "LaravelLang\\Attributes\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "LaravelLang\\Attributes\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro" + }, + { + "name": "Laravel-Lang Team", + "homepage": "https://github.com/Laravel-Lang" + } + ], + "description": "List of 126 languages for form field names", + "keywords": [ + "attributes", + "fields", + "form", + "lang", + "languages", + "laravel", + "messages", + "translations", + "validation" + ], + "support": { + "issues": "https://github.com/Laravel-Lang/attributes/issues", + "source": "https://github.com/Laravel-Lang/attributes/tree/2.10.8" + }, + "time": "2024-08-30T09:34:14+00:00" + }, + { + "name": "laravel-lang/common", + "version": "6.4.0", + "source": { + "type": "git", + "url": "https://github.com/Laravel-Lang/common.git", + "reference": "36c0270180f71420c1166c26f38dc25e1c8b7f64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Laravel-Lang/common/zipball/36c0270180f71420c1166c26f38dc25e1c8b7f64", + "reference": "36c0270180f71420c1166c26f38dc25e1c8b7f64", + "shasum": "" + }, + "require": { + "laravel-lang/actions": "^1.8.3", + "laravel-lang/attributes": "^2.10.7", + "laravel-lang/http-statuses": "^3.8.3", + "laravel-lang/json-fallback": "^2.1", + "laravel-lang/lang": "^13.12 || ^14.0 || ^15.5.1", + "laravel-lang/locales": "^2.8", + "laravel-lang/models": "^1.0", + "laravel-lang/publisher": "^16.4", + "laravel-lang/routes": "^1.0", + "php": "^8.1" + }, + "require-dev": { + "dragon-code/support": "^6.13", + "orchestra/testbench": "^8.17 || ^9.1.2", + "phpunit/phpunit": "^10.5.20", + "symfony/var-dumper": "^6.4 || ^7.1.1" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laravel-Lang Team", + "homepage": "https://github.com/Laravel-Lang" + }, + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro", + "homepage": "https://dragon-code.pro" + } + ], + "description": "Easily connect the necessary language packs to the application", + "keywords": [ + "Laravel-lang", + "actions", + "attribute", + "attributes", + "breeze", + "buttons", + "cashier", + "fortify", + "framework", + "http", + "http-status", + "http-status-code", + "i18n", + "jetstream", + "lang", + "language", + "languages", + "laravel", + "locale", + "locales", + "localization", + "localizations", + "nova", + "publisher", + "spark", + "translation", + "translations", + "ui" + ], + "support": { + "issues": "https://github.com/Laravel-Lang/common/issues", + "source": "https://github.com/Laravel-Lang/common" + }, + "time": "2024-07-06T16:48:35+00:00" + }, + { + "name": "laravel-lang/config", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/Laravel-Lang/config.git", + "reference": "67c9273a2e5487441a7034c2422bb1527200bce5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Laravel-Lang/config/zipball/67c9273a2e5487441a7034c2422bb1527200bce5", + "reference": "67c9273a2e5487441a7034c2422bb1527200bce5", + "shasum": "" + }, + "require": { + "archtechx/enums": "^1.0", + "illuminate/config": "^10.0 || ^11.0", + "illuminate/support": "^10.0 || ^11.0", + "laravel-lang/locale-list": "^1.4", + "php": "^8.1" + }, + "require-dev": { + "orchestra/testbench": "^8.23 || ^9.1", + "pestphp/pest": "^2.34" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "LaravelLang\\Config\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "LaravelLang\\Config\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro", + "homepage": "https://dragon-code.pro" + }, + { + "name": "Laravel-Lang Team", + "homepage": "https://laravel-lang.com" + } + ], + "description": "The Laravel-Lang config package", + "keywords": [ + "Laravel-lang", + "Settings", + "config", + "lang", + "languages", + "laravel", + "locale", + "locales", + "localization", + "localizations", + "translation", + "translations" + ], + "support": { + "issues": "https://github.com/Laravel-Lang/config/issues", + "source": "https://github.com/Laravel-Lang/config/tree/1.10.0" + }, + "time": "2024-09-07T11:28:53+00:00" + }, + { + "name": "laravel-lang/http-statuses", + "version": "3.8.4", + "source": { + "type": "git", + "url": "https://github.com/Laravel-Lang/http-statuses.git", + "reference": "0e8b1af2835f951f5587f6c635ea6b929f275415" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Laravel-Lang/http-statuses/zipball/0e8b1af2835f951f5587f6c635ea6b929f275415", + "reference": "0e8b1af2835f951f5587f6c635ea6b929f275415", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel-lang/publisher": "^14.1 || ^15.0 || ^16.0", + "php": "^8.1" + }, + "require-dev": { + "laravel-lang/status-generator": "^1.19 || ^2.0", + "phpunit/phpunit": "^10.0", + "symfony/var-dumper": "^6.0 || ^7.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "LaravelLang\\HttpStatuses\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "LaravelLang\\HttpStatuses\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro" + }, + { + "name": "Laravel-Lang Team", + "homepage": "https://github.com/Laravel-Lang" + } + ], + "description": "List of 126 languages for HTTP statuses", + "keywords": [ + "http", + "lang", + "languages", + "laravel", + "messages", + "status", + "translations" + ], + "support": { + "issues": "https://github.com/Laravel-Lang/http-statuses/issues", + "source": "https://github.com/Laravel-Lang/http-statuses/tree/3.8.4" + }, + "time": "2024-07-20T18:15:58+00:00" + }, + { + "name": "laravel-lang/json-fallback", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/Laravel-Lang/json-fallback.git", + "reference": "597865ffcef81b7e92227ea73ff3a9a3372fb91a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Laravel-Lang/json-fallback/zipball/597865ffcef81b7e92227ea73ff3a9a3372fb91a", + "reference": "597865ffcef81b7e92227ea73ff3a9a3372fb91a", + "shasum": "" + }, + "require": { + "illuminate/support": "^10.0 || ^11.0", + "illuminate/translation": "^10.0 || ^11.0", + "php": "^8.1" + }, + "require-dev": { + "orchestra/testbench": "^8.0 || ^9.0", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "LaravelLang\\JsonFallback\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro", + "homepage": "https://github.com/andrey-helldar" + }, + { + "name": "Felipe Dsdev", + "homepage": "https://github.com/felipe-dsdev" + } + ], + "description": "Adds support for fallback JSON string translation", + "support": { + "issues": "https://github.com/Laravel-Lang/json-fallback/issues", + "source": "https://github.com/Laravel-Lang/json-fallback/tree/2.1.0" + }, + "time": "2024-03-13T09:18:03+00:00" + }, + { + "name": "laravel-lang/lang", + "version": "15.7.3", + "source": { + "type": "git", + "url": "https://github.com/Laravel-Lang/lang.git", + "reference": "0877b8d0881cfe0881a4addd4e9319b736bd5c77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Laravel-Lang/lang/zipball/0877b8d0881cfe0881a4addd4e9319b736bd5c77", + "reference": "0877b8d0881cfe0881a4addd4e9319b736bd5c77", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel-lang/publisher": "^16.0", + "php": "^8.2" + }, + "conflict": { + "laravel/framework": "<11.0.7" + }, + "require-dev": { + "laravel-lang/status-generator": "^2.11", + "phpunit/phpunit": "^10.0", + "symfony/var-dumper": "^7.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "LaravelLang\\Lang\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "LaravelLang\\Lang\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laravel-Lang Team", + "homepage": "https://github.com/Laravel-Lang" + } + ], + "description": "List of 126 languages for Laravel Framework, Laravel Jetstream, Laravel Fortify, Laravel Breeze, Laravel Cashier, Laravel Nova, Laravel Spark and Laravel UI", + "keywords": [ + "lang", + "languages", + "laravel", + "lpm" + ], + "support": { + "issues": "https://github.com/Laravel-Lang/lang/issues", + "source": "https://github.com/Laravel-Lang/lang" + }, + "time": "2024-08-28T08:28:47+00:00" + }, + { + "name": "laravel-lang/locale-list", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/Laravel-Lang/locale-list.git", + "reference": "48b8e4304f8b1ad34456270d35d44ca0c3e6ea0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Laravel-Lang/locale-list/zipball/48b8e4304f8b1ad34456270d35d44ca0c3e6ea0d", + "reference": "48b8e4304f8b1ad34456270d35d44ca0c3e6ea0d", + "shasum": "" + }, + "require": { + "archtechx/enums": "^0.3.2 || ^1.0", + "php": "^8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "LaravelLang\\LocaleList\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro", + "homepage": "https://dragon-code.pro" + }, + { + "name": "Laravel-Lang Team", + "homepage": "https://laravel-lang.com" + } + ], + "description": "List of localizations available in Laravel Lang projects", + "keywords": [ + "Laravel-lang", + "lang", + "languages", + "laravel", + "locale", + "locales", + "localization", + "translation", + "translations" + ], + "support": { + "issues": "https://github.com/Laravel-Lang/locale-list/issues", + "source": "https://github.com/Laravel-Lang/locale-list" + }, + "time": "2024-06-01T00:24:42+00:00" + }, + { + "name": "laravel-lang/locales", + "version": "2.9.2", + "source": { + "type": "git", + "url": "https://github.com/Laravel-Lang/locales.git", + "reference": "e7914ccfb91432ebebacf46697b573a330d702c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Laravel-Lang/locales/zipball/e7914ccfb91432ebebacf46697b573a330d702c7", + "reference": "e7914ccfb91432ebebacf46697b573a330d702c7", + "shasum": "" + }, + "require": { + "archtechx/enums": "^0.3.2 || ^1.0", + "dragon-code/support": "^6.11.3", + "ext-json": "*", + "illuminate/collections": "^10.0 || ^11.0", + "laravel-lang/config": "^1.0.2", + "laravel-lang/locale-list": "^1.2", + "laravel-lang/native-country-names": "^1.3", + "laravel-lang/native-currency-names": "^1.3", + "laravel-lang/native-locale-names": "^2.2", + "php": "^8.1" + }, + "require-dev": { + "orchestra/testbench": "^8.0 || ^9.0", + "pestphp/pest": "^2.24.1", + "symfony/var-dumper": "^6.0 || ^7.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "LaravelLang\\Locales\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "LaravelLang\\Locales\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro" + }, + { + "name": "Laravel-Lang Team", + "homepage": "https://laravel-lang.com" + } + ], + "description": "Basic functionality for working with localizations", + "keywords": [ + "laravel", + "locale", + "locales", + "localization", + "translation", + "translations" + ], + "support": { + "issues": "https://github.com/Laravel-Lang/locales/issues", + "source": "https://github.com/Laravel-Lang/locales" + }, + "time": "2024-06-24T09:56:41+00:00" + }, + { + "name": "laravel-lang/models", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/Laravel-Lang/models.git", + "reference": "b46f5ff2990755c79ac408255e70b5c8a38063e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Laravel-Lang/models/zipball/b46f5ff2990755c79ac408255e70b5c8a38063e0", + "reference": "b46f5ff2990755c79ac408255e70b5c8a38063e0", + "shasum": "" + }, + "require": { + "composer/class-map-generator": "^1.3", + "dragon-code/support": "^6.13", + "illuminate/database": "^10.0 || ^11.0", + "illuminate/support": "^10.0 || ^11.0", + "laravel-lang/config": "^1.9", + "laravel-lang/locales": "^2.9.2", + "laravel/prompts": "^0.1.24", + "php": "^8.1" + }, + "require-dev": { + "orchestra/testbench": "^8.0 || ^9.0", + "pestphp/pest": "^2.34", + "pestphp/pest-plugin-laravel": "^2.4", + "symfony/var-dumper": "^6.0 || ^7.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "LaravelLang\\Models\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "LaravelLang\\Models\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro", + "homepage": "https://dragon-code.pro", + "role": "Maintainer" + }, + { + "name": "Andrey Sokolov", + "email": "walfireru@gmail.com", + "homepage": "https://github.com/Quiss", + "role": "Usability consultant" + }, + { + "name": "Laravel-Lang Team", + "homepage": "https://github.com/Laravel-Lang" + } + ], + "description": "Easy and fast way to localize models", + "keywords": [ + "database", + "l18n", + "languages", + "laravel", + "locales", + "localization", + "models", + "translate", + "translations" + ], + "support": { + "issues": "https://github.com/Laravel-Lang/models/issues", + "source": "https://github.com/Laravel-Lang/models" + }, + "time": "2024-08-31T15:47:28+00:00" + }, + { + "name": "laravel-lang/native-country-names", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/Laravel-Lang/native-country-names.git", + "reference": "cddca6627c8732770a2e2c11c921753b6d0adb66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Laravel-Lang/native-country-names/zipball/cddca6627c8732770a2e2c11c921753b6d0adb66", + "reference": "cddca6627c8732770a2e2c11c921753b6d0adb66", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0", - "psr/container": "^1.0 || ^2.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" - }, - "conflict": { - "fzaninotto/faker": "*" + "dragon-code/support": "^6.11", + "ext-json": "*", + "illuminate/collections": "^10.0 || ^11.0", + "php": "^8.1" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "doctrine/persistence": "^1.3 || ^2.0", - "ext-intl": "*", - "phpunit/phpunit": "^9.5.26", - "symfony/phpunit-bridge": "^5.4.16" - }, - "suggest": { - "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", - "ext-curl": "Required by Faker\\Provider\\Image to download images.", - "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", - "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", - "ext-mbstring": "Required for multibyte Unicode string functionality." + "illuminate/support": "^10.0 || ^11.0", + "laravel-lang/locale-list": "^1.2", + "pestphp/pest": "^2.24.3", + "punic/punic": "^3.8", + "symfony/console": "^6.3 || ^7.0", + "symfony/process": "^6.3 || ^7.0", + "symfony/var-dumper": "^6.3 || ^7.0", + "vlucas/phpdotenv": "^5.6" }, "type": "library", "autoload": { "psr-4": { - "Faker\\": "src/Faker/" + "LaravelLang\\NativeCountryNames\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -5953,53 +7902,70 @@ ], "authors": [ { - "name": "François Zaninotto" + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro" + }, + { + "name": "Laravel-Lang Team", + "homepage": "https://laravel-lang.com" } ], - "description": "Faker is a PHP library that generates fake data for you.", + "description": "The project contains native translations of country names", "keywords": [ - "data", - "faker", - "fixtures" + "Laravel-lang", + "countries", + "country", + "lang", + "languages", + "laravel", + "locale", + "locales", + "localization", + "territories", + "territory", + "translation", + "translations" ], "support": { - "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1" + "issues": "https://github.com/Laravel-Lang/native-country-names/issues", + "source": "https://github.com/Laravel-Lang/native-country-names" }, - "time": "2024-01-02T13:46:09+00:00" + "time": "2024-03-13T09:34:55+00:00" }, { - "name": "fidry/cpu-core-counter", - "version": "1.1.0", + "name": "laravel-lang/native-currency-names", + "version": "1.4.0", "source": { "type": "git", - "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" + "url": "https://github.com/Laravel-Lang/native-currency-names.git", + "reference": "2e0fbe039421ac753b4fd5256bd239147a0a88fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "url": "https://api.github.com/repos/Laravel-Lang/native-currency-names/zipball/2e0fbe039421ac753b4fd5256bd239147a0a88fe", + "reference": "2e0fbe039421ac753b4fd5256bd239147a0a88fe", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "dragon-code/support": "^6.11", + "ext-json": "*", + "illuminate/collections": "^10.0 || ^11.0", + "php": "^8.1" }, "require-dev": { - "fidry/makefile": "^0.2.0", - "fidry/php-cs-fixer-config": "^1.1.2", - "phpstan/extension-installer": "^1.2.0", - "phpstan/phpstan": "^1.9.2", - "phpstan/phpstan-deprecation-rules": "^1.0.0", - "phpstan/phpstan-phpunit": "^1.2.2", - "phpstan/phpstan-strict-rules": "^1.4.4", - "phpunit/phpunit": "^8.5.31 || ^9.5.26", - "webmozarts/strict-phpunit": "^7.5" + "illuminate/support": "^10.0 || ^11.0", + "laravel-lang/locale-list": "^1.2", + "pestphp/pest": "^2.24.3", + "punic/punic": "^3.8", + "symfony/console": "^6.3 || ^7.0", + "symfony/process": "^6.3 || ^7.0", + "symfony/var-dumper": "^6.3 || ^7.0", + "vlucas/phpdotenv": "^5.6" }, "type": "library", "autoload": { "psr-4": { - "Fidry\\CpuCoreCounter\\": "src/" + "LaravelLang\\NativeCurrencyNames\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -6008,63 +7974,65 @@ ], "authors": [ { - "name": "Théo FIDRY", - "email": "theo.fidry@gmail.com" + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro" + }, + { + "name": "Laravel-Lang Team", + "homepage": "https://laravel-lang.com" } ], - "description": "Tiny utility to get the number of CPU cores.", + "description": "The project contains native translations of currency names", "keywords": [ - "CPU", - "core" + "Laravel-lang", + "currency", + "lang", + "languages", + "laravel", + "locale", + "locales", + "localization", + "translation", + "translations" ], "support": { - "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" + "issues": "https://github.com/Laravel-Lang/native-currency-names/issues", + "source": "https://github.com/Laravel-Lang/native-currency-names" }, - "funding": [ - { - "url": "https://github.com/theofidry", - "type": "github" - } - ], - "time": "2024-02-07T09:43:46+00:00" + "time": "2024-03-13T09:40:02+00:00" }, { - "name": "filp/whoops", - "version": "2.15.4", + "name": "laravel-lang/native-locale-names", + "version": "2.3.0", "source": { "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546" + "url": "https://github.com/Laravel-Lang/native-locale-names.git", + "reference": "39ef3330938b74277456049bf386453109e4d05c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546", - "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546", + "url": "https://api.github.com/repos/Laravel-Lang/native-locale-names/zipball/39ef3330938b74277456049bf386453109e4d05c", + "reference": "39ef3330938b74277456049bf386453109e4d05c", "shasum": "" }, "require": { - "php": "^5.5.9 || ^7.0 || ^8.0", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" + "dragon-code/support": "^6.11", + "ext-json": "*", + "php": "^8.1" }, "require-dev": { - "mockery/mockery": "^0.9 || ^1.0", - "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" - }, - "suggest": { - "symfony/var-dumper": "Pretty print complex values better with var-dumper available", - "whoops/soap": "Formats errors as SOAP responses" + "illuminate/support": "^10.31 || ^11.0", + "laravel-lang/locale-list": "^1.2", + "pestphp/pest": "^2.24.3", + "punic/punic": "^3.8", + "symfony/console": "^6.3 || ^7.0", + "symfony/process": "^6.3 || ^7.0", + "symfony/var-dumper": "^6.3 || ^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, "autoload": { "psr-4": { - "Whoops\\": "src/Whoops/" + "LaravelLang\\NativeLocaleNames\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -6073,118 +8041,174 @@ ], "authors": [ { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro" + }, + { + "name": "Laravel-Lang Team", + "homepage": "https://laravel-lang.com" } ], - "description": "php error handling for cool kids", - "homepage": "https://filp.github.io/whoops/", + "description": "The project contains native translations of locale names", "keywords": [ - "error", - "exception", - "handling", - "library", - "throwable", - "whoops" + "Laravel-lang", + "lang", + "languages", + "laravel", + "locale", + "locales", + "localization", + "translation", + "translations" ], "support": { - "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.15.4" + "issues": "https://github.com/Laravel-Lang/native-locale-names/issues", + "source": "https://github.com/Laravel-Lang/native-locale-names" }, - "funding": [ - { - "url": "https://github.com/denis-sokolov", - "type": "github" - } - ], - "time": "2023-11-03T12:00:00+00:00" + "time": "2024-03-13T09:28:19+00:00" }, { - "name": "hamcrest/hamcrest-php", - "version": "v2.0.1", + "name": "laravel-lang/publisher", + "version": "16.4.0", "source": { "type": "git", - "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + "url": "https://github.com/Laravel-Lang/publisher.git", + "reference": "7812e7a07e6f2fdb7d258f3ab1d481d1cbf7f32c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "url": "https://api.github.com/repos/Laravel-Lang/publisher/zipball/7812e7a07e6f2fdb7d258f3ab1d481d1cbf7f32c", + "reference": "7812e7a07e6f2fdb7d258f3ab1d481d1cbf7f32c", "shasum": "" }, "require": { - "php": "^5.3|^7.0|^8.0" + "composer/semver": "^3.4", + "dragon-code/pretty-array": "^4.1", + "dragon-code/support": "^6.11.3", + "ext-json": "*", + "illuminate/collections": "^10.0 || ^11.0", + "illuminate/console": "^10.0 || ^11.0", + "illuminate/support": "^10.0 || ^11.0", + "laravel-lang/config": "^1.0", + "laravel-lang/locales": "^2.3", + "league/commonmark": "^2.4.1", + "league/config": "^1.2", + "php": "^8.1" }, - "replace": { - "cordoval/hamcrest-php": "*", - "davedevelopment/hamcrest-php": "*", - "kodova/hamcrest-php": "*" + "conflict": { + "laravel-lang/attributes": "<2.0", + "laravel-lang/http-statuses": "<3.0", + "laravel-lang/lang": "<11.0" }, "require-dev": { - "phpunit/php-file-iterator": "^1.4 || ^2.0", - "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + "laravel-lang/json-fallback": "^2.0", + "orchestra/testbench": "^8.14 || ^9.0", + "phpunit/phpunit": "^10.4.2", + "symfony/var-dumper": "^6.3.6 || ^7.0" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "2.1-dev" + "laravel": { + "providers": [ + "LaravelLang\\Publisher\\ServiceProvider" + ] } }, "autoload": { - "classmap": [ - "hamcrest" - ] + "psr-4": { + "LaravelLang\\Publisher\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "description": "This is the PHP port of Hamcrest Matchers", + "authors": [ + { + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro" + }, + { + "name": "Laravel-Lang Team", + "homepage": "https://laravel-lang.com" + } + ], + "description": "Publisher lang files for the Laravel and Lumen Frameworks, Jetstream, Fortify, Cashier, Spark and Nova from Laravel-Lang/lang", "keywords": [ - "test" + "Laravel-lang", + "breeze", + "cashier", + "fortify", + "framework", + "i18n", + "jetstream", + "lang", + "languages", + "laravel", + "locale", + "locales", + "localization", + "localizations", + "lpm", + "lumen", + "nova", + "publisher", + "spark", + "trans", + "translation", + "translations", + "validations" ], "support": { - "issues": "https://github.com/hamcrest/hamcrest-php/issues", - "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + "issues": "https://github.com/Laravel-Lang/publisher/issues", + "source": "https://github.com/Laravel-Lang/publisher" }, - "time": "2020-07-09T08:09:16+00:00" + "time": "2024-06-02T00:22:33+00:00" }, { - "name": "jean85/pretty-package-versions", - "version": "2.0.6", + "name": "laravel-lang/routes", + "version": "1.5.0", "source": { "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4" + "url": "https://github.com/Laravel-Lang/routes.git", + "reference": "addc4438fac481389e66e349ac3b93670aa4301b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/f9fdd29ad8e6d024f52678b570e5593759b550b4", - "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4", + "url": "https://api.github.com/repos/Laravel-Lang/routes/zipball/addc4438fac481389e66e349ac3b93670aa4301b", + "reference": "addc4438fac481389e66e349ac3b93670aa4301b", "shasum": "" }, "require": { - "composer-runtime-api": "^2.0.0", - "php": "^7.1|^8.0" + "dragon-code/support": "^6.13", + "illuminate/config": "^10.0 || ^11.0", + "illuminate/http": "^10.0 || ^11.0", + "illuminate/routing": "^10.0 || ^11.0", + "illuminate/support": "^10.0 || ^11.0", + "laravel-lang/config": "^1.6", + "laravel-lang/locales": "^2.8", + "php": "^8.1" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.2", - "jean85/composer-provided-replaced-stub-package": "^1.0", - "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^7.5|^8.5|^9.4", - "vimeo/psalm": "^4.3" + "orchestra/testbench": "^8.23 || ^9.1", + "pestphp/pest": "^2.34", + "pestphp/pest-plugin-laravel": "^2.4", + "symfony/var-dumper": "^6.0 || ^7.0" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.x-dev" + "laravel": { + "providers": [ + "LaravelLang\\Routes\\ServiceProvider" + ] } }, "autoload": { + "files": [ + "helpers/functions.php" + ], "psr-4": { - "Jean85\\": "src/" + "LaravelLang\\Routes\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -6193,22 +8217,30 @@ ], "authors": [ { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" + "name": "Andrey Helldar", + "email": "helldar@dragon-code.pro", + "homepage": "https://dragon-code.pro" + }, + { + "name": "Laravel-Lang Team", + "homepage": "https://github.com/Laravel-Lang" } ], - "description": "A library to get pretty versions strings of installed dependencies", + "description": "Easy and fast way to localize routes", "keywords": [ - "composer", - "package", - "release", - "versions" + "l18n", + "languages", + "laravel", + "localization", + "routes", + "translate", + "translations" ], "support": { - "issues": "https://github.com/Jean85/pretty-package-versions/issues", - "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.6" + "issues": "https://github.com/Laravel-Lang/routes/issues", + "source": "https://github.com/Laravel-Lang/routes" }, - "time": "2024-03-08T09:58:59+00:00" + "time": "2024-07-10T10:28:26+00:00" }, { "name": "laravel/breeze", @@ -8708,6 +10740,82 @@ ], "time": "2023-02-07T11:34:05+00:00" }, + { + "name": "symfony/polyfill-php81", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, { "name": "symfony/yaml", "version": "v7.1.1", diff --git a/ecommerce-app/config/services.php b/ecommerce-app/config/services.php index a7f1316..8c064d8 100644 --- a/ecommerce-app/config/services.php +++ b/ecommerce-app/config/services.php @@ -37,5 +37,11 @@ 'resend' => [ 'key' => env('RESEND_KEY'), - ], + + 'google' => [ + 'client_id' => env('GOOGLE_CLIENT_ID'), + 'client_secret' => env('GOOGLE_CLIENT_SECRET'), + 'redirect' => 'http://127.0.0.1:8000/auth/google/call-back', + ], ]; + diff --git a/ecommerce-app/database/migrations/2024_08_22_000000_create_users_table.php b/ecommerce-app/database/migrations/2024_08_22_000000_create_users_table.php index ed3634d..e6e62cc 100644 --- a/ecommerce-app/database/migrations/2024_08_22_000000_create_users_table.php +++ b/ecommerce-app/database/migrations/2024_08_22_000000_create_users_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class() extends Migration{ +return new class extends Migration +{ /** * Run the migrations. */ @@ -33,7 +34,7 @@ public function up(): void Schema::create('sessions', function (Blueprint $table) { $table->string('id')->primary(); - $table->foreignId('user_id')->nullable()->index(); + $table->foreignUuid('user_id')->nullable()->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade')->index(); $table->string('ip_address', 45)->nullable(); $table->text('user_agent')->nullable(); $table->longText('payload'); diff --git a/ecommerce-app/database/migrations/2024_08_22_030000_create_products_table.php b/ecommerce-app/database/migrations/2024_08_22_030000_create_products_table.php index 5a22918..5408a74 100644 --- a/ecommerce-app/database/migrations/2024_08_22_030000_create_products_table.php +++ b/ecommerce-app/database/migrations/2024_08_22_030000_create_products_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class() extends Migration { /** * Run the migrations. */ @@ -16,9 +16,8 @@ public function up(): void $table->text('description')->nullable(); $table->string('image_url')->nullable(); $table->integer('qty_in_stock')->default(0); - $table->foreignUuid('product_category_id')->references('id')->on('product_categories')->onUpdate('cascade') - ->onDelete('cascade'); - + $table->foreignUuid('product_category_id')->references('id')->on('product_categories') + ->onUpdate('cascade')->onDelete('cascade'); $table->decimal('price', 10, 2); // Added price field $table->timestamps(); }); diff --git a/ecommerce-app/database/migrations/2024_08_22_040000_create_order_statuses_table.php b/ecommerce-app/database/migrations/2024_08_22_040000_create_order_statuses_table.php index 8de6bd1..1743f34 100644 --- a/ecommerce-app/database/migrations/2024_08_22_040000_create_order_statuses_table.php +++ b/ecommerce-app/database/migrations/2024_08_22_040000_create_order_statuses_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class() extends Migration { /** * Run the migrations. */ diff --git a/ecommerce-app/database/migrations/2024_08_22_050000_create_addresses_table.php b/ecommerce-app/database/migrations/2024_08_22_050000_create_addresses_table.php index fdcd1cc..0064e9a 100644 --- a/ecommerce-app/database/migrations/2024_08_22_050000_create_addresses_table.php +++ b/ecommerce-app/database/migrations/2024_08_22_050000_create_addresses_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class() extends Migration { /** * Run the migrations. */ @@ -19,7 +19,6 @@ public function up(): void $table->string('postal_code'); $table->foreignUuid('country_id')->references('id')->on('countries')->onUpdate('cascade') ->onDelete('cascade'); - $table->boolean('is_default')->default(false); $table->timestamps(); }); diff --git a/ecommerce-app/database/migrations/2024_08_22_060000_create_user_addresses_table.php b/ecommerce-app/database/migrations/2024_08_22_060000_create_user_addresses_table.php index a49bc2d..4718b19 100644 --- a/ecommerce-app/database/migrations/2024_08_22_060000_create_user_addresses_table.php +++ b/ecommerce-app/database/migrations/2024_08_22_060000_create_user_addresses_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class() extends Migration { /** * Run the migrations. */ @@ -17,7 +17,6 @@ public function up(): void $table->foreignUuid('address_id')->constrained()->onUpdate('cascade') ->onDelete('cascade'); - $table->boolean('is_default')->default(false); $table->timestamps(); }); diff --git a/ecommerce-app/database/migrations/2024_08_22_070000_create_shopping_cart_table.php b/ecommerce-app/database/migrations/2024_08_22_070000_create_shopping_cart_table.php index 336d856..d9b12eb 100644 --- a/ecommerce-app/database/migrations/2024_08_22_070000_create_shopping_cart_table.php +++ b/ecommerce-app/database/migrations/2024_08_22_070000_create_shopping_cart_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class() extends Migration { /** * Run the migrations. */ diff --git a/ecommerce-app/database/migrations/2024_08_22_080000_create_shopping_cart_items_table.php b/ecommerce-app/database/migrations/2024_08_22_080000_create_shopping_cart_items_table.php index 605b892..cb6b51f 100644 --- a/ecommerce-app/database/migrations/2024_08_22_080000_create_shopping_cart_items_table.php +++ b/ecommerce-app/database/migrations/2024_08_22_080000_create_shopping_cart_items_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class() extends Migration { /** * Run the migrations. */ @@ -17,7 +17,6 @@ public function up(): void $table->foreignUuid('product_id')->references('id')->on('products')->onUpdate('cascade') ->onDelete('cascade'); - $table->integer('qty')->default(0); $table->timestamps(); }); diff --git a/ecommerce-app/database/migrations/2024_08_22_090000_create_viewed_products_table.php b/ecommerce-app/database/migrations/2024_08_22_090000_create_viewed_products_table.php index eeedbf1..da13387 100644 --- a/ecommerce-app/database/migrations/2024_08_22_090000_create_viewed_products_table.php +++ b/ecommerce-app/database/migrations/2024_08_22_090000_create_viewed_products_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class() extends Migration { /** * Run the migrations. */ @@ -17,7 +17,6 @@ public function up(): void $table->foreignUuid('product_id')->references('id')->on('products')->onUpdate('cascade') ->onDelete('cascade'); - $table->timestamp('viewed_at')->useCurrent(); $table->timestamps(); }); diff --git a/ecommerce-app/database/migrations/2024_08_22_100000_create_order_details_table.php b/ecommerce-app/database/migrations/2024_08_22_100000_create_order_details_table.php index 7cb9f66..7d1c0ea 100644 --- a/ecommerce-app/database/migrations/2024_08_22_100000_create_order_details_table.php +++ b/ecommerce-app/database/migrations/2024_08_22_100000_create_order_details_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class() extends Migration { /** * Run the migrations. */ diff --git a/ecommerce-app/database/migrations/2024_08_22_110000_create_order_items_table.php b/ecommerce-app/database/migrations/2024_08_22_110000_create_order_items_table.php index d34f832..c12579f 100644 --- a/ecommerce-app/database/migrations/2024_08_22_110000_create_order_items_table.php +++ b/ecommerce-app/database/migrations/2024_08_22_110000_create_order_items_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class() extends Migration { /** * Run the migrations. */ diff --git a/ecommerce-app/database/migrations/2024_08_22_120000_create_user_review_table.php b/ecommerce-app/database/migrations/2024_08_22_120000_create_user_review_table.php index f80272e..3e71112 100644 --- a/ecommerce-app/database/migrations/2024_08_22_120000_create_user_review_table.php +++ b/ecommerce-app/database/migrations/2024_08_22_120000_create_user_review_table.php @@ -4,7 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class() extends Migration{ /** * Run the migrations. */ diff --git a/ecommerce-app/database/migrations/2024_09_09_044829_add_photo_for_user.php b/ecommerce-app/database/migrations/2024_09_09_044829_add_photo_for_user.php new file mode 100644 index 0000000..0f16b72 --- /dev/null +++ b/ecommerce-app/database/migrations/2024_09_09_044829_add_photo_for_user.php @@ -0,0 +1,27 @@ +string('photo')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('photo'); + }); + } +}; diff --git a/ecommerce-app/database/migrations/2024_09_10_042805_add_google_i_d_for_user.php b/ecommerce-app/database/migrations/2024_09_10_042805_add_google_i_d_for_user.php new file mode 100644 index 0000000..065e919 --- /dev/null +++ b/ecommerce-app/database/migrations/2024_09_10_042805_add_google_i_d_for_user.php @@ -0,0 +1,27 @@ +string('google_id')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('google_id'); + }); + } +}; diff --git a/ecommerce-app/database/seeders/DatabaseSeeder.php b/ecommerce-app/database/seeders/DatabaseSeeder.php index a2aaea8..14da7f4 100644 --- a/ecommerce-app/database/seeders/DatabaseSeeder.php +++ b/ecommerce-app/database/seeders/DatabaseSeeder.php @@ -28,7 +28,7 @@ public function run(): void $countries = Country::factory(10)->create(); // Seed Addresses and set a default address for each User - $users = User::factory(10)->create()->each(function ($user) use ($countries) { + User::factory(10)->create()->each(function ($user) use ($countries) { $addresses = Address::factory(rand(3, 5))->create([ 'country_id' => $countries->random()->id, @@ -83,7 +83,6 @@ public function run(): void 'user_id' => $user->id, 'product_id' => $products->random()->id, ]); - }); // Create parent categories diff --git a/ecommerce-app/package-lock.json b/ecommerce-app/package-lock.json index 475c466..9e51800 100644 --- a/ecommerce-app/package-lock.json +++ b/ecommerce-app/package-lock.json @@ -1,5 +1,5 @@ { - "name": "ecommerce-app", + "name": "html", "lockfileVersion": 3, "requires": true, "packages": { @@ -546,6 +546,8 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -555,6 +557,8 @@ "version": "15.2.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", @@ -579,6 +583,8 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -839,6 +845,14 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "license": "MIT" }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -1062,6 +1076,8 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -1213,6 +1229,8 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1314,7 +1332,9 @@ "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", @@ -1373,6 +1393,8 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/flowbite/-/flowbite-2.5.1.tgz", "integrity": "sha512-7jP1jy9c3QP7y+KU9lc8ueMkTyUdMDvRP+lteSWgY5TigSZjf9K1kqZxmqjhbx2gBnFQxMl1GAjVThCa8cEpKA==", + "dev": true, + "license": "MIT", "dependencies": { "@popperjs/core": "^2.9.3", "flowbite-datepicker": "^1.3.0", @@ -1383,6 +1405,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/flowbite-datepicker/-/flowbite-datepicker-1.3.0.tgz", "integrity": "sha512-CLVqzuoE2vkUvWYK/lJ6GzT0be5dlTbH3uuhVwyB67+PjqJWABm2wv68xhBf5BqjpBxvTSQ3mrmLHpPJ2tvrSQ==", + "dev": true, + "license": "MIT", "dependencies": { "@rollup/plugin-node-resolve": "^15.2.3", "flowbite": "^2.0.0" @@ -1542,6 +1566,8 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "license": "MIT", "dependencies": { "builtin-modules": "^3.3.0" }, @@ -1603,7 +1629,9 @@ "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true, + "license": "MIT" }, "node_modules/is-number": { "version": "7.0.0", @@ -2735,3 +2763,4 @@ } } } + diff --git a/ecommerce-app/resources/css/app.css b/ecommerce-app/resources/css/app.css index b5c61c9..e4882d5 100644 --- a/ecommerce-app/resources/css/app.css +++ b/ecommerce-app/resources/css/app.css @@ -1,3 +1,134 @@ @tailwind base; @tailwind components; @tailwind utilities; + +.cart__sidecontainer { + z-index: -9999; +} + +.cart__sidecontainer.show { + z-index: 99; +} + +.cart__sidebar { + position: fixed; + top: 0; + bottom: 0; + right: -449px; + width: 448px; + z-index: 99; + transition: right 1s; +} + +.cart__sidebar.show { + right: 0px; + z-index: 99; +} + +.gsi-material-button { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + -webkit-appearance: none; + background-color: WHITE; + background-image: none; + border: 1px solid #747775; + -webkit-border-radius: 4px; + border-radius: 4px; + -webkit-box-sizing: border-box; + box-sizing: border-box; + color: #1f1f1f; + cursor: pointer; + font-family: 'Roboto', arial, sans-serif; + font-size: 14px; + height: 40px; + letter-spacing: 0.25px; + outline: none; + overflow: hidden; + padding: 0 12px; + position: relative; + text-align: center; + -webkit-transition: background-color .218s, border-color .218s, box-shadow .218s; + transition: background-color .218s, border-color .218s, box-shadow .218s; + vertical-align: middle; + white-space: nowrap; + width: auto; + max-width: 400px; + min-width: min-content; +} + +.gsi-material-button .gsi-material-button-icon { + height: 20px; + margin-right: 12px; + min-width: 20px; + width: 20px; +} + +.gsi-material-button .gsi-material-button-content-wrapper { + -webkit-align-items: center; + align-items: center; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; + -webkit-flex-wrap: nowrap; + flex-wrap: nowrap; + height: 100%; + justify-content: space-between; + position: relative; + width: 100%; +} + +.gsi-material-button .gsi-material-button-contents { + -webkit-flex-grow: 1; + flex-grow: 1; + font-family: 'Roboto', arial, sans-serif; + font-weight: 500; + overflow: hidden; + text-overflow: ellipsis; + vertical-align: top; +} + +.gsi-material-button .gsi-material-button-state { + -webkit-transition: opacity .218s; + transition: opacity .218s; + bottom: 0; + left: 0; + opacity: 0; + position: absolute; + right: 0; + top: 0; +} + +.gsi-material-button:disabled { + cursor: default; + background-color: #ffffff61; + border-color: #1f1f1f1f; +} + +.gsi-material-button:disabled .gsi-material-button-contents { + opacity: 38%; +} + +.gsi-material-button:disabled .gsi-material-button-icon { + opacity: 38%; +} + +.gsi-material-button:not(:disabled):active .gsi-material-button-state, +.gsi-material-button:not(:disabled):focus .gsi-material-button-state { + background-color: #303030; + opacity: 12%; +} + +.gsi-material-button:not(:disabled):hover { + -webkit-box-shadow: 0 1px 2px 0 rgba(60, 64, 67, .30), 0 1px 3px 1px rgba(60, 64, 67, .15); + box-shadow: 0 1px 2px 0 rgba(60, 64, 67, .30), 0 1px 3px 1px rgba(60, 64, 67, .15); +} + +.gsi-material-button:not(:disabled):hover .gsi-material-button-state { + background-color: #303030; + opacity: 8%; +} + + + + diff --git a/ecommerce-app/resources/js/app.js b/ecommerce-app/resources/js/app.js index a8093be..c84e8e7 100644 --- a/ecommerce-app/resources/js/app.js +++ b/ecommerce-app/resources/js/app.js @@ -1,7 +1,22 @@ import './bootstrap'; +import 'flowbite'; import Alpine from 'alpinejs'; window.Alpine = Alpine; Alpine.start(); + +function sidebarOpen() { + document.getElementsByClassName('cart__sidebar')[0].classList.add('show'); + document.getElementsByClassName('cart__sidecontainer')[0].classList.add('show'); +} + +function sidebarClose() { + document.getElementsByClassName('cart__sidebar')[0].classList.remove('show'); + document.getElementsByClassName('cart__sidecontainer')[0].classList.remove('show'); +} + +window.sidebarOpen = sidebarOpen; +window.sidebarClose = sidebarClose; + diff --git a/ecommerce-app/resources/views/admin/crud/products.blade.php b/ecommerce-app/resources/views/admin/crud/products.blade.php new file mode 100644 index 0000000..081a536 --- /dev/null +++ b/ecommerce-app/resources/views/admin/crud/products.blade.php @@ -0,0 +1,465 @@ + +
+
+
+
+ +

All products

+
+
+ +
+ + + + + + Export + +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + @foreach ($products as $product) + + + + + + + + + + + + + + + + + + @endforeach + +
+
+ + +
+
+ Product Image + + Product Name + + Description + + Quantity in Stock + + Category + + Price + + Actions +
+
+ + +
+
+ + + {{ $product->name }} + + {{ $product->description }} + + {{ $product->qty_in_stock }} + + {{ $product->categories->name }} + + ${{ $product->price }} + + + +
+
+
+
+
+ + + + + + diff --git a/ecommerce-app/resources/views/admin/crud/users.blade.php b/ecommerce-app/resources/views/admin/crud/users.blade.php new file mode 100644 index 0000000..f4d7702 --- /dev/null +++ b/ecommerce-app/resources/views/admin/crud/users.blade.php @@ -0,0 +1,513 @@ + +
+
+
+
+ +

All users

+
+
+ +
+ + + + + + Export + +
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + @foreach ($users as $user) + + + + + + + + + + + + + + + @endforeach + +
+
+ + +
+
+ Name + + Telephone + + Status + + Actions +
+
+ + +
+
+
+ {{ $user->first_name . ' ' . $user->last_name }}
+
+ {{ $user->email }}
+
+ {{ $user->telephone }} +
+ + + + + + +
+ @csrf + @method('PUT') + + +
+
+
+ + +
+
+
+
+
+ + + + + + diff --git a/ecommerce-app/resources/views/admin/dashboard.blade.php b/ecommerce-app/resources/views/admin/dashboard.blade.php new file mode 100644 index 0000000..45d4c99 --- /dev/null +++ b/ecommerce-app/resources/views/admin/dashboard.blade.php @@ -0,0 +1 @@ + diff --git a/ecommerce-app/resources/views/auth/login.blade.php b/ecommerce-app/resources/views/auth/login.blade.php index 80e1b39..016504d 100644 --- a/ecommerce-app/resources/views/auth/login.blade.php +++ b/ecommerce-app/resources/views/auth/login.blade.php @@ -8,7 +8,8 @@
- +
@@ -16,10 +17,8 @@
- +
@@ -27,14 +26,17 @@
@if (Route::has('password.request')) - + {{ __('Forgot your password?') }} @endif @@ -44,4 +46,39 @@
+ + + + + diff --git a/ecommerce-app/resources/views/cart.blade.php b/ecommerce-app/resources/views/cart.blade.php index 844acdd..99a15f1 100644 --- a/ecommerce-app/resources/views/cart.blade.php +++ b/ecommerce-app/resources/views/cart.blade.php @@ -172,7 +172,7 @@ class="space-y-4 rounded-lg border border-gray-200 bg-white p-4 shadow-sm dark:b
- Proceed to Checkout diff --git a/ecommerce-app/resources/views/components/admin/layout.blade.php b/ecommerce-app/resources/views/components/admin/layout.blade.php new file mode 100644 index 0000000..aa45e6f --- /dev/null +++ b/ecommerce-app/resources/views/components/admin/layout.blade.php @@ -0,0 +1,28 @@ + + + + + + + Admin Dashboard + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + + + @include('components.admin.navbar-dashboard') + +
+
+
+ {{ $slot }} +
+
+ +
+ + + + + + diff --git a/ecommerce-app/resources/views/components/admin/navbar-dashboard.blade.php b/ecommerce-app/resources/views/components/admin/navbar-dashboard.blade.php new file mode 100644 index 0000000..b55833e --- /dev/null +++ b/ecommerce-app/resources/views/components/admin/navbar-dashboard.blade.php @@ -0,0 +1,183 @@ + + + + + diff --git a/ecommerce-app/resources/views/components/layout.blade.php b/ecommerce-app/resources/views/components/layout.blade.php new file mode 100644 index 0000000..b4460cd --- /dev/null +++ b/ecommerce-app/resources/views/components/layout.blade.php @@ -0,0 +1,363 @@ + + + + + + + + + + Soppe + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + + +
+ +
+ {{ $slot }} +
+
+ + + + + diff --git a/ecommerce-app/resources/views/components/orders/confirmation.blade.php b/ecommerce-app/resources/views/components/orders/confirmation.blade.php new file mode 100644 index 0000000..67997bf --- /dev/null +++ b/ecommerce-app/resources/views/components/orders/confirmation.blade.php @@ -0,0 +1,61 @@ +{{-- TODO: Breaking form into blade component --}} + + + + + + + Document + + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + +
+
+

Thanks for your order!

+

Your order {{ $orderDetail->id }} will be + processed + within 24 hours during working days. We will notify you by email once your order has been shipped.

+
+
+
Date
+
{{ $orderDetail->order_date }} +
+
+
+
Payment Method
+
COD
+
+
+
Name
+
+ {{ $user->first_name . ' ' . $user->last_name }}
+
+
+
Address
+
+ {{ $address->address_line1 . $address->address_line2 }}
+
+
+
Phone
+
+ {{ $user->telephone }}
+
+
+ +
+
+ + + + diff --git a/ecommerce-app/resources/views/components/orders/index.blade.php b/ecommerce-app/resources/views/components/orders/index.blade.php new file mode 100644 index 0000000..4cdbbf8 --- /dev/null +++ b/ecommerce-app/resources/views/components/orders/index.blade.php @@ -0,0 +1,125 @@ +{{-- TODO: Breaking form into blade component --}} + + + + + + + Document + + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + +
+
+ @csrf +
+

Order summary

+ +
+

Billing & Delivery information

+ +
+
+ {{ $user->first_name . ' ' . $user->last_name }} +
+
+ {{ $defaultAddress->address_line1 . ' ' . $defaultAddress->address_line2 . ' ' . $defaultAddress->city . ' ' . $defaultAddress->state . ' ' . $defaultAddress->postal_code }} +
+
+ + +
+ +
+
+ + @foreach ($orderItems as $orderItem) + + @endforeach +
+
+ +
+

Order summary

+ +
+
+
+
Original price
+
${{ $totalPrice }} +
+
+ +
+
Savings
+
-$000.00
+
+ +
+
Store Pickup
+
$00
+
+ +
+
Tax
+
$000
+
+
+ +
+
Total
+
${{ $totalPrice }}
+
+
+ +
+ + +
+ +
+ + + {{-- --}} + + + + + + + @foreach ($orderItems as $item) + + + + @endforeach + +
+
+
+
+
+
+ + + + diff --git a/ecommerce-app/resources/views/components/orders/order-item.blade.php b/ecommerce-app/resources/views/components/orders/order-item.blade.php new file mode 100644 index 0000000..41bd572 --- /dev/null +++ b/ecommerce-app/resources/views/components/orders/order-item.blade.php @@ -0,0 +1,21 @@ + + + + + + + + x{{ $orderItem->qty }} + + ${{ $orderItem->product->price * $orderItem->qty }} + + + diff --git a/ecommerce-app/resources/views/dashboard.blade.php b/ecommerce-app/resources/views/dashboard.blade.php index 2753f8e..df59467 100644 --- a/ecommerce-app/resources/views/dashboard.blade.php +++ b/ecommerce-app/resources/views/dashboard.blade.php @@ -5,16 +5,15 @@ Dashboard - + @vite('resources/css/app.css') - + @include('layouts.navigation') - @if (Session::has('error'))
@@ -84,11 +83,12 @@ class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm focus:ring-
+
--> @@ -268,7 +268,6 @@ class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm - @endforeach @@ -280,9 +279,6 @@ class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm - - -
@foreach ($products as $product) @@ -312,20 +308,24 @@ class="rounded-full border border-slate-300 p-2.5 text-center text-sm transition {{ $product->name }}

{{ $product->description }}

-

Category: {{ $product->category?->name }}

@for ($i = 0; $i < floor($product->user_reviews_avg_rating); $i++) - {{ number_format($product->user_reviews_avg_rating, 1) }} + {{ number_format($product->user_reviews_avg_rating, 1) }} ({{ $product->user_reviews_count }} reviews)
@@ -346,34 +346,83 @@ class="rounded-full border border-slate-300 p-2.5 text-center text-sm transition
- +
+ + + + + @include('layouts.footer') - + + + - - - - - - - + diff --git a/ecommerce-app/resources/views/home.blade.php b/ecommerce-app/resources/views/home.blade.php index 121065c..fa06d95 100644 --- a/ecommerce-app/resources/views/home.blade.php +++ b/ecommerce-app/resources/views/home.blade.php @@ -1,16 +1,6 @@ - - - - - - E-Commerce Home - @vite(['resources/css/app.css', 'resources/js/app.js']) - - - - - @include('layouts.navigation') - + + +
@@ -21,39 +11,1275 @@ @endforeach
- -
- -
- - +
+ @foreach ($products as $product) +
+ +
+
+ + Up to 35% off + +
+ + + + + +
+
+ + {{ $product->name }} + +
+
+ + + + + + + + + +
+ +

+ + {{ $product->user_reviews_avg_rating }} +

+ +

+ ({{ $product->user_reviews_count }})

+
+ +
    +
  • + +

    Fast Delivery

    +
  • + +
  • + +

    Best Price

    +
  • +
+ +
+

+ ${{ $product->price }}

+ + +
+
+
+ @endforeach +
+
+ {{ $products->links() }} +
+ + + + - - \ No newline at end of file + diff --git a/ecommerce-app/resources/views/layouts/admin.blade.php b/ecommerce-app/resources/views/layouts/admin.blade.php deleted file mode 100644 index d8f7f6a..0000000 --- a/ecommerce-app/resources/views/layouts/admin.blade.php +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Admin Dashboard - @yield('title') - @vite('resources/css/app.css') - - - - @include('layouts.adminNavigation') - -
-
- @yield('content') -
-
- - - - diff --git a/ecommerce-app/resources/views/layouts/footer.blade.php b/ecommerce-app/resources/views/layouts/footer.blade.php index f22919e..783e23a 100644 --- a/ecommerce-app/resources/views/layouts/footer.blade.php +++ b/ecommerce-app/resources/views/layouts/footer.blade.php @@ -219,4 +219,5 @@
- \ No newline at end of file + + diff --git a/ecommerce-app/resources/views/orders/index.blade.php b/ecommerce-app/resources/views/orders/index.blade.php deleted file mode 100644 index 86a7162..0000000 --- a/ecommerce-app/resources/views/orders/index.blade.php +++ /dev/null @@ -1,651 +0,0 @@ - - - - - - - Document - - - - -
-
-
-

Order summary

- -
-

Billing & Delivery information

- -
-
Individual
-
Bonnie Green - +1 234 - 567 - 890, San Francisco, California, United States, 3454, Scott Street
-
- - -
- -
-
- - @foreach ($orders as $order) - - - - - - - - - - @endforeach -
- - x2 - $799 -
-
- -
-

Order summary

- -
-
-
-
Original price
-
$6,592.00
-
- -
-
Savings
-
-$299.00
-
- -
-
Store Pickup
-
$99
-
- -
-
Tax
-
$799
-
-
- -
-
Total
-
$7,191.00
-
-
- -
- - -
- -
- - - -
-
-
-
-
-
- - - - - - diff --git a/ecommerce-app/resources/views/products/show.blade.php b/ecommerce-app/resources/views/products/show.blade.php index 41b8163..410fd3e 100644 --- a/ecommerce-app/resources/views/products/show.blade.php +++ b/ecommerce-app/resources/views/products/show.blade.php @@ -14,13 +14,12 @@ @include('layouts.navigation') - -
- -
- {{ $product->name }} -
+
+
+
+
+ image_url) }}" alt="{{ $product->image_url }}" /> +
@@ -50,72 +49,6 @@ class="text-gray-300 fill-current">
- - @auth -
-

Leave Your Feedback

-
- @csrf - @method('POST') -
- - -
-
- - -
-
- -
-
-
- @endauth - - -
-

Customer Feedback

- - @forelse ($userReviews as $userReview) -
-
- - @for ($i = 0; $i < floor($userReview['rating']); $i++) - - - - @endfor - @for ($i = $userReview['rating']; $i < 5; $i++) - - - - @endfor - Edit - Delete -
-

{{ $userReview['comment'] }}

-
- @empty -

No feedback available for this product.

- @endforelse -
- - - @include('layouts.footer') diff --git a/ecommerce-app/resources/views/profile/partials/update-profile-information-form.blade.php b/ecommerce-app/resources/views/profile/partials/update-profile-information-form.blade.php index 2df7390..6611de6 100644 --- a/ecommerce-app/resources/views/profile/partials/update-profile-information-form.blade.php +++ b/ecommerce-app/resources/views/profile/partials/update-profile-information-form.blade.php @@ -18,10 +18,16 @@ @method('patch')
- - - + + + +
+ +
+ + +
@@ -51,7 +57,7 @@ class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 da
- photo)}}" + photo) }}" class="card-img-top mt-4" alt="...">
@@ -65,4 +71,8 @@ class="text-sm text-gray-600 dark:text-gray-400">{{ __('Saved.') }}

@endif
-
\ No newline at end of file + + + + + diff --git a/ecommerce-app/routes/admin/dashboard.php b/ecommerce-app/routes/admin/dashboard.php new file mode 100644 index 0000000..472a3b7 --- /dev/null +++ b/ecommerce-app/routes/admin/dashboard.php @@ -0,0 +1,7 @@ +name('admin.dashboard'); diff --git a/ecommerce-app/routes/admin/products.php b/ecommerce-app/routes/admin/products.php new file mode 100644 index 0000000..6dd9313 --- /dev/null +++ b/ecommerce-app/routes/admin/products.php @@ -0,0 +1,11 @@ +name('admin.products.index'); +Route::get('/products/create', [ProductController::class, 'create'])->name('admin.products.create'); +Route::get('/products/{product}', [ProductController::class, 'show'])->name('admin.products.show'); +Route::get('/products/edit/{product}', [ProductController::class, 'edit'])->name('admin.products.edit'); +Route::post('/products', [ProductController::class, 'store'])->name('admin.products.store'); +Route::put('/products/{product}', [ProductController::class, 'update'])->name('admin.products.update'); +Route::delete('/products/{product}', [ProductController::class, 'destroy'])->name('admin.products.destroy'); diff --git a/ecommerce-app/routes/admin/users.php b/ecommerce-app/routes/admin/users.php new file mode 100644 index 0000000..a34199d --- /dev/null +++ b/ecommerce-app/routes/admin/users.php @@ -0,0 +1,14 @@ +name('admin.users.index'); +Route::get('/users/create', [UserController::class, 'create'])->name('admin.users.create'); +Route::get('/users/export-csv', [UserController::class, 'exportCSV'])->name('admin.users.export'); +Route::get('/users/{user}', [UserController::class, 'show'])->name('admin.users.show'); +Route::get('/users/edit/{user}', [UserController::class, 'edit'])->name('admin.users.edit'); +Route::post('/users', [UserController::class, 'store'])->name('admin.users.store'); +Route::put('/users/{user}', [UserController::class, 'update'])->name('admin.users.update'); +Route::put('/users/{user}/toggleStatus', [UserController::class, 'toggleStatus'])->name('admin.users.toggleStatus'); +Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('admin.users.destroy'); + diff --git a/ecommerce-app/routes/web.php b/ecommerce-app/routes/web.php index f2a9590..0876937 100644 --- a/ecommerce-app/routes/web.php +++ b/ecommerce-app/routes/web.php @@ -1,5 +1,6 @@ name('home.index'); Route::get('/orders', [OrderController::class, 'index'])->name('orders.index'); - +Route::post('/orders', [OrderController::class, 'store'])->name('orders.store'); +Route::get( + '/orders/confirmation/{order_id}', + [OrderController::class, 'showConfirmation'] +)->name('orders.confirmation'); Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard.index'); Route::get('send_email', [EmailController::class, 'store'])->name('email.store'); +require __DIR__.'/auth.php'; // Profile management routes Route::middleware('auth')->group(function () { Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); @@ -40,33 +55,12 @@ Route::get('/order-details', [OrderDetailController::class, 'index'])->name('order-details.index'); Route::get('/order-details/{orderDetail}', [OrderDetailController::class, 'show'])->name('order-details.show'); - + Route::get('/cart', [CartController::class, 'show'])->name('cart.show'); Route::post('/cart/add', [CartController::class, 'update'])->name('cart.update'); Route::delete('/cart/removeItem', [CartController::class, 'removeItem'])->name('cart.removeItem'); }); -Route::middleware(['auth', 'admin'])->group(function () { - Route::get('/users', [UserController::class, 'index'])->name('users.index'); - Route::get('/users/create', [UserController::class, 'create'])->name('users.create'); - Route::get('/users/{user}', [UserController::class, 'show'])->name('users.show'); - Route::get('/users/edit/{user}', [UserController::class, 'edit'])->name('users.edit'); - Route::post('/users', [UserController::class, 'store'])->name('users.store'); - Route::put('/users/{user}', [UserController::class, 'update'])->name('users.update'); - Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('users.destroy'); - - Route::get('/admin', function () { - // Dummy data for the admin view - $users = User::all(); - - $categories = ProductCategory::all(); - - $products = Product::all(); - - return view('admin', ['users' => $users, 'categories' => $categories, 'products' => $products]); - })->name('admin.dashboard'); -}); - Route::middleware(['auth', 'admin'])->prefix('admin')->group(function () { Route::get('/categories', [CategoryController::class, 'index'])->name('categories.index'); Route::get('/categories/create', [CategoryController::class, 'create'])->name('categories.create'); @@ -80,21 +74,69 @@ Route::get('/products/{product}/edit', [ProductController::class, 'edit'])->name('products.edit'); Route::put('/products/{product}', [ProductController::class, 'update'])->name('products.update'); Route::delete('/products/{product}', [ProductController::class, 'destroy'])->name('products.destroy'); + + require __DIR__.'/admin/dashboard.php'; }); -Route::middleware(['auth'])->group(function () { - Route::get('/review/create', [UserReviewController::class, 'create'])->name('review.create'); - Route::post('/review', [UserReviewController::class, 'store'])->name('review.store'); - Route::middleware([CheckOwner::class])->group(function () { - Route::get('review/edit/{id}', [UserReviewController::class, 'edit'])->name('review.edit'); - Route::put('/review/{id}', [UserReviewController::class, 'update'])->name('review.update'); - Route::delete('/review/{id}', [UserReviewController::class, 'destroy'])->name('review.destroy'); - }); +Route::middleware(['auth', 'admin'])->prefix('admin/crud')->group(function () { + require __DIR__.'/admin/users.php'; + // require __DIR__ . '/admin/categories.php'; + require __DIR__.'/admin/products.php'; }); +// Route::middleware(['auth', 'admin'])->group(function () { +// Route::get('/users', [UserController::class, 'index'])->name('users.index'); +// Route::get('/users/create', [UserController::class, 'create'])->name('users.create'); +// Route::get('/users/{user}', [UserController::class, 'show'])->name('users.show'); +// Route::get('/users/edit/{user}', [UserController::class, 'edit'])->name('users.edit'); +// Route::post('/users', [UserController::class, 'store'])->name('users.store'); +// Route::put('/users/{user}', [UserController::class, 'update'])->name('users.update'); +// Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('users.destroy'); +// +// Route::get('/admin', function () { +// // Dummy data for the admin view +// $users = User::all(); +// +// $categories = ProductCategory::all(); +// +// $products = Product::all(); +// +// return view('admin', ['users' => $users, 'categories' => $categories, 'products' => $products]); +// })->name('admin.dashboard'); +// }); Route::get('/products', [CategoryController::class, 'index'])->name('products.index'); Route::get('/products/{product}', [ProductController::class, 'show'])->name('products.show'); Route::get('/language/{lang}', [LanguageController::class, 'changeLanguage'])->name('locale'); +Route::get('auth/google', [GoogleAuthController::class, 'redirect'])->name('google-auth'); +Route::get('auth/google/call-back', [GoogleAuthController::class, 'callbackGoogle'])->name('google-callback'); +// Route::middleware(['auth', 'admin'])->prefix('admin')->group(function () { +// Route::get('/categories', [CategoryController::class, 'index'])->name('categories.index'); +// Route::get('/categories/create', [CategoryController::class, 'create'])->name('categories.create'); +// Route::post('/categories', [CategoryController::class, 'store'])->name('categories.store'); +// Route::get('/categories/{id}/edit', [CategoryController::class, 'edit'])->name('categories.edit'); +// Route::put('/categories/{id}', [CategoryController::class, 'update'])->name('categories.update'); +// Route::delete('/categories/{id}', [CategoryController::class, 'destroy'])->name('categories.destroy'); +// +// Route::get('/products/create', [CategoryController::class, 'create'])->name('products.create'); +// Route::post('/products', [CategoryController::class, 'store'])->name('products.store'); +// Route::get('/products/{product}/edit', [CategoryController::class, 'edit'])->name('products.edit'); +// Route::put('/products/{product}', [CategoryController::class, 'update'])->name('products.update'); +// Route::delete('/products/{product}', [CategoryController::class, 'destroy'])->name('products.destroy'); +// }); + +// Route::middleware(['auth'])->group(function () { +// Route::get('/review/create', [UserReviewController::class, 'create'])->name('review.create'); +// Route::post('/review', [UserReviewController::class, 'store'])->name('review.store'); +// Route::middleware([CheckOwner::class])->group(function () { +// Route::get('review/edit/{id}', [UserReviewController::class, 'edit'])->name('review.edit'); +// Route::put('/review/{id}', [UserReviewController::class, 'update'])->name('review.update'); +// Route::delete('/review/{id}', [UserReviewController::class, 'destroy'])->name('review.destroy'); +// }); +// }); +// +// Route::get('/products', [CategoryController::class, 'index'])->name('products.index'); +// Route::get('/products/{product}', [ProductController::class, 'show'])->name('products.show'); + +require __DIR__.'/auth.php'; -require __DIR__.'/auth.php'; \ No newline at end of file diff --git a/ecommerce-app/tailwind.config.js b/ecommerce-app/tailwind.config.js index c4e8bf5..7725710 100644 --- a/ecommerce-app/tailwind.config.js +++ b/ecommerce-app/tailwind.config.js @@ -3,30 +3,24 @@ import forms from '@tailwindcss/forms'; /** @type {import('tailwindcss').Config} */ export default { - darkMode: 'selector', + darkMode: 'class', content: [ + "./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php", + "./resources/views/**/*.blade.php", + "./storage/framework/views/*.php", + "./resources/**/*.blade.php", + "./resources/**/*.js", + "./node_modules/flowbite/**/*.js", './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php', - './storage/framework/views/*.php', - './resources/views/**/*.blade.php', ], theme: { extend: { + fontFamily: { sans: ['Figtree', ...defaultTheme.fontFamily.sans], }, - }, - }, - plugins: [forms], -}; -tailwind.config = { - darkMode: 'class', - theme: { - extend: { - colors: { - primary: { "50": "#eff6ff", "100": "#dbeafe", "200": "#bfdbfe", "300": "#93c5fd", "400": "#60a5fa", "500": "#3b82f6", "600": "#2563eb", "700": "#1d4ed8", "800": "#1e40af", "900": "#1e3a8a", "950": "#172554" } - } }, fontFamily: { 'body': [ @@ -64,5 +58,10 @@ tailwind.config = { 'Noto Color Emoji' ] } - } -} \ No newline at end of file + }, + + + plugins: [forms, 'flowbite/plugin'], + +}; +