Compare commits
12 commits
Author | SHA1 | Date | |
---|---|---|---|
|
5349f0578e | ||
|
39feadab32 | ||
|
e21fa78f15 | ||
|
9fcdd131c8 | ||
|
6b34c59d73 | ||
|
e5c047cf6e | ||
|
f46280eb2b | ||
|
9b9bd4ff7b | ||
|
46e1fa8aee | ||
|
09d737dfab | ||
|
3c6d22573e | ||
|
724fd76ffb |
38 changed files with 593 additions and 229 deletions
1
.envrc
1
.envrc
|
@ -1 +1,2 @@
|
||||||
use nix
|
use nix
|
||||||
|
layout php
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"php":"8.0.13","version":"3.0.0","indent":" ","lineEnding":"\n","rules":{"blank_line_after_opening_tag":true,"braces":{"allow_single_line_anonymous_class_with_empty_body":true},"compact_nullable_typehint":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_braces":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_blank_line_before_namespace":true,"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"visibility_required":{"elements":["const","method","property"]},"blank_line_after_namespace":true,"class_definition":true,"constant_case":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":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_import_per_statement":true,"single_line_after_imports":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true},"hashes":{"\/run\/user\/1000\/neoformat\/product.blade.php":1493321553}}
|
{"php":"8.0.13","version":"3.0.0","indent":" ","lineEnding":"\n","rules":{"blank_line_after_opening_tag":true,"braces":{"allow_single_line_anonymous_class_with_empty_body":true},"compact_nullable_typehint":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"new_with_braces":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_blank_line_before_namespace":true,"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"visibility_required":{"elements":["const","method","property"]},"blank_line_after_namespace":true,"class_definition":true,"constant_case":true,"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":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_import_per_statement":true,"single_line_after_imports":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true},"hashes":{"\/run\/user\/1000\/neoformat\/product.blade.php":1493321553,"\/tmp\/neoformat\/user.blade.php":2134171036,"\/tmp\/neoformat\/edit.blade.php":2692964585,"\/tmp\/neoformat\/ProductController.php":4228240463,"\/tmp\/neoformat\/DatabaseSeeder.php":3199248297,"\/tmp\/neoformat\/category.blade.php":2623876730,"\/tmp\/neoformat\/CategoryController.php":4271583155}}
|
32
app/Faker/CategoryNameProvider.php
Normal file
32
app/Faker/CategoryNameProvider.php
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Faker;
|
||||||
|
|
||||||
|
use Faker\Provider\Base;
|
||||||
|
|
||||||
|
class CategoryNameProvider extends Base
|
||||||
|
{
|
||||||
|
protected static $categories = [
|
||||||
|
"żywioły",
|
||||||
|
"wody",
|
||||||
|
"pierwiastki",
|
||||||
|
"racje",
|
||||||
|
"plastik",
|
||||||
|
"naturalne",
|
||||||
|
"rzeczywiste",
|
||||||
|
"A|B",
|
||||||
|
"moduły node",
|
||||||
|
"kontenery",
|
||||||
|
"filmy",
|
||||||
|
"bajki",
|
||||||
|
"maszyny",
|
||||||
|
"challenge",
|
||||||
|
"śmieci",
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
public function categoryName(): string
|
||||||
|
{
|
||||||
|
return static::randomElement(static::$categories);
|
||||||
|
}
|
||||||
|
}
|
|
@ -72,7 +72,7 @@ class ProductNameProvider extends Base
|
||||||
"drugs",
|
"drugs",
|
||||||
"pizza",
|
"pizza",
|
||||||
"teacher",
|
"teacher",
|
||||||
"love",
|
"love ❤️",
|
||||||
"computer"
|
"computer"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ use Exception;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
|
|
||||||
class CartController extends Controller
|
class CartController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -19,14 +20,24 @@ class CartController extends Controller
|
||||||
*/
|
*/
|
||||||
public function show()
|
public function show()
|
||||||
{
|
{
|
||||||
throw new Exception("UNIMPLEMENTED");
|
$user = Auth::user();
|
||||||
//return view("product/view", ["product" => $product]);
|
if (!$user) {
|
||||||
|
throw new AccessDeniedHttpException("Not logged in");
|
||||||
|
}
|
||||||
|
return view("cart", ["user" => $user]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addToCart(Product $product)
|
public function addToCart(Product $product, Request $request)
|
||||||
{
|
{
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
$user->cart()->syncWithoutDetaching([$product->uuid]);
|
$user->cart()->syncWithoutDetaching([$product->uuid]);
|
||||||
|
$quantity = $request->validate([
|
||||||
|
'quantity' => 'numeric|min:1'
|
||||||
|
])["quantity"] ?? 1;
|
||||||
|
|
||||||
|
$pivot = $user->cart()->findOrFail($product->uuid)->pivot;
|
||||||
|
$pivot->quantity = $quantity;
|
||||||
|
$pivot->save();
|
||||||
|
|
||||||
return back();
|
return back();
|
||||||
}
|
}
|
||||||
|
|
64
app/Http/Controllers/CategoryController.php
Normal file
64
app/Http/Controllers/CategoryController.php
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Category;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class CategoryController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$categories = Category::query()->get();
|
||||||
|
return view("category", ["categories"=>$categories]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$validatedData = $request->validate([
|
||||||
|
// The server should make sure to serve SVG files with the correct CSP to prevent XSS
|
||||||
|
'name' => 'required|string|unique:categories',
|
||||||
|
]);
|
||||||
|
/*
|
||||||
|
Once the image is validated , create the name on the image
|
||||||
|
*/
|
||||||
|
$cat = new Category();
|
||||||
|
$cat->name = $validatedData["name"];
|
||||||
|
|
||||||
|
$cat->save();
|
||||||
|
return back();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(Category $cat, Request $request)
|
||||||
|
{
|
||||||
|
$validatedData = $request->validate([
|
||||||
|
// The server should make sure to serve SVG files with the correct CSP to prevent XSS
|
||||||
|
'name' => 'required|string|unique:categories',
|
||||||
|
]);
|
||||||
|
/*
|
||||||
|
Once the image is validated , create the name on the image
|
||||||
|
*/
|
||||||
|
$cat->name = $validatedData["name"];
|
||||||
|
$cat->save();
|
||||||
|
return back();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param \App\Models\Image $image
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
Category::query()->findOrFail($id)->delete();
|
||||||
|
return back();
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,5 +50,6 @@ class ImageController extends Controller
|
||||||
public function destroy(Image $image)
|
public function destroy(Image $image)
|
||||||
{
|
{
|
||||||
$image->delete();
|
$image->delete();
|
||||||
|
return back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Category;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
@ -9,13 +10,17 @@ class MainPageController extends Controller
|
||||||
{
|
{
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$query = $request->query->get("q");
|
$query = Product::query()->latest()->limit(100);
|
||||||
if ($query) {
|
$search = $request->query->get("q");
|
||||||
|
if ($search) {
|
||||||
// O(n) query at best, malicious users can just insert % and _ characters into the query if they wanna, but it's fine half the class left every single field vulnurable to sqli so I don't wanna bother doing this properly with a full text search
|
// O(n) query at best, malicious users can just insert % and _ characters into the query if they wanna, but it's fine half the class left every single field vulnurable to sqli so I don't wanna bother doing this properly with a full text search
|
||||||
$products = Product::query()->where('name', 'like', "%{$query}%")->orWhere('description', 'like', "?")->latest()->limit(100)->get();
|
$query = $query->where('name', 'like', "%{$search}%")->orWhere('description', 'like', "%{$search}%");
|
||||||
} else {
|
|
||||||
$products = Product::query()->latest()->limit(100)->get();
|
|
||||||
}
|
}
|
||||||
return view("index", ["products" => $products, "query" => $query]);
|
$category = $request->query->get("category");
|
||||||
|
if ($category) {
|
||||||
|
// O(n) query at best, malicious users can just insert % and _ characters into the query if they wanna, but it's fine half the class left every single field vulnurable to sqli so I don't wanna bother doing this properly with a full text search
|
||||||
|
$query = $query->whereHas('categories', fn ($b) => $b->where("name","=",$category));
|
||||||
|
}
|
||||||
|
return view("index", ["products" => $query->get(), "query" => $search]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,10 +37,12 @@ class OrderController extends Controller
|
||||||
{
|
{
|
||||||
$validated = $request->validate([
|
$validated = $request->validate([
|
||||||
'products' => 'required|array',
|
'products' => 'required|array',
|
||||||
'products.*' => 'exists:products,uuid'
|
'products.*' => 'exists:products,uuid',
|
||||||
|
'product_quantities' => 'required|array',
|
||||||
|
'product_quantities.*' => 'numeric|min:1',
|
||||||
]);
|
]);
|
||||||
$products = array_map(fn ($v) => Product::query()->where("uuid", $v)->first(), $validated["products"]);
|
$products_quantities = array_map(fn ($v, $q) => [Product::query()->where("uuid", $v)->first(), $q], $validated["products"], $validated["product_quantities"]);
|
||||||
return view("order/create", ["products" => $products]);
|
return view("order/create", ["products_with_quantities" => $products_quantities]);
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,11 +62,13 @@ class OrderController extends Controller
|
||||||
$validated = $request->validate([
|
$validated = $request->validate([
|
||||||
'products' => 'required|array',
|
'products' => 'required|array',
|
||||||
'products.*' => 'exists:products,uuid',
|
'products.*' => 'exists:products,uuid',
|
||||||
|
'product_quantities' => 'required|array',
|
||||||
|
'product_quantities.*' => 'numeric|min:1',
|
||||||
'address' => 'required',
|
'address' => 'required',
|
||||||
]);
|
]);
|
||||||
|
$products_quantities = array_map(fn ($v, $q) => [Product::query()->where("uuid", $v)->first(), $q], $validated["products"], $validated["product_quantities"]);
|
||||||
|
|
||||||
$products = array_map(fn ($v) => Product::query()->where("uuid", $v)->first(), $validated["products"]);
|
DB::transaction(function () use ($validated, $user, $products_quantities) {
|
||||||
DB::transaction(function () use ($validated, $user, $products) {
|
|
||||||
$address = new Address($validated);
|
$address = new Address($validated);
|
||||||
$address->user()->associate($user);
|
$address->user()->associate($user);
|
||||||
$address->save();
|
$address->save();
|
||||||
|
@ -73,16 +77,20 @@ class OrderController extends Controller
|
||||||
|
|
||||||
$order->address()->associate($address);
|
$order->address()->associate($address);
|
||||||
$order->user()->associate($user);
|
$order->user()->associate($user);
|
||||||
$order->cost = array_reduce($products, fn ($c, $i) => bcadd($c,$i->price), 0);
|
$order->cost = array_reduce($products_quantities, fn ($c, $i) => bcadd($c,bcmul($i[0]->price,$i[1])), 0);
|
||||||
|
|
||||||
$order->save();
|
$order->save();
|
||||||
foreach($products as $product) {
|
foreach($products_quantities as $product_quantity) {
|
||||||
|
$product = $product_quantity[0];
|
||||||
|
$quantity = $product_quantity[1];
|
||||||
$order->products()->attach($product);
|
$order->products()->attach($product);
|
||||||
|
$order->products()->find($product->uuid)->pivot->quantity = $quantity;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
foreach($products as $product) {
|
foreach($products_quantities as $product) {
|
||||||
$user->cart()->detach($product);
|
$user->cart()->detach($product[0]);
|
||||||
}
|
}
|
||||||
|
return redirect()->route("order.index");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Category;
|
||||||
|
use App\Models\Image;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
@ -21,7 +23,9 @@ class ProductController extends Controller
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
return view("product/create");
|
$prod = new Product();
|
||||||
|
$categories = Category::all();
|
||||||
|
return view("product/edit", [ 'product' => $prod, 'categories' => $categories, 'new'=>true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,17 +36,26 @@ class ProductController extends Controller
|
||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
Log::debug($request);
|
$validated = $request->validate([
|
||||||
$request->validate([
|
|
||||||
'name'=>'required',
|
'name'=>'required',
|
||||||
'description'=>'required',
|
'description'=>'required',
|
||||||
|
'price'=>'required|numeric',
|
||||||
|
'visualization' => 'image|mimes:jpg,png,jpeg,gif,svg,webp|max:5000',
|
||||||
]);
|
]);
|
||||||
$product = new Product([
|
|
||||||
'name' => $request->get("name"),
|
$product = new Product($validated);
|
||||||
'description' => $request->get("description")
|
if($validated['category']) {
|
||||||
]);
|
$product->categories()->sync($validated['category']);
|
||||||
|
}
|
||||||
$product->save();
|
$product->save();
|
||||||
//echo $product->uuid;
|
|
||||||
|
if (isset($validated["visualization"])) {
|
||||||
|
$visualization = new Image();
|
||||||
|
|
||||||
|
$visualization->path = $request->file('image')->store("uploads");
|
||||||
|
|
||||||
|
$product->images()->save($visualization);
|
||||||
|
}
|
||||||
return redirect()->route("product.show", [ 'product' => $product])->with("message", "Product created successfully");
|
return redirect()->route("product.show", [ 'product' => $product])->with("message", "Product created successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +67,7 @@ class ProductController extends Controller
|
||||||
*/
|
*/
|
||||||
public function show(Product $product)
|
public function show(Product $product)
|
||||||
{
|
{
|
||||||
return view("product/view", ["product" => $product]);
|
return view("product.view", ["product" => $product]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,7 +78,8 @@ class ProductController extends Controller
|
||||||
*/
|
*/
|
||||||
public function edit(Product $product)
|
public function edit(Product $product)
|
||||||
{
|
{
|
||||||
//
|
$categories = Category::all();
|
||||||
|
return view("product.edit", ["product" => $product, 'categories' => $categories, 'new'=>false]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,8 +91,25 @@ class ProductController extends Controller
|
||||||
*/
|
*/
|
||||||
public function update(Request $request, Product $product)
|
public function update(Request $request, Product $product)
|
||||||
{
|
{
|
||||||
$product->fill($request->all());
|
$validated = $request->validate([
|
||||||
|
'name'=>'string',
|
||||||
|
'description'=>'string',
|
||||||
|
'price'=>'numeric',
|
||||||
|
'category' => 'array|exists:App\Models\Category,uuid',
|
||||||
|
'visualization' => 'image|mimes:jpg,png,jpeg,gif,svg,webp|max:5000',
|
||||||
|
]);
|
||||||
|
$product->fill($validated);
|
||||||
|
if($validated['category']) {
|
||||||
|
$product->categories()->sync($validated['category']);
|
||||||
|
}
|
||||||
$product->save();
|
$product->save();
|
||||||
|
if (isset($request["image"])) {
|
||||||
|
$visualization = new Image();
|
||||||
|
|
||||||
|
$visualization->path = $request->file('image')->store("uploads");
|
||||||
|
|
||||||
|
$product->images()->save($visualization);
|
||||||
|
}
|
||||||
return redirect()->route("product.show", [ 'product' => $product])->with("message", "Product created successfully");
|
return redirect()->route("product.show", [ 'product' => $product])->with("message", "Product created successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,15 @@ use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Validation\Rules\Password;
|
||||||
|
|
||||||
class LoginController extends Controller
|
class UserController extends Controller
|
||||||
{
|
{
|
||||||
public function authenticate(Request $request)
|
public function authenticate(Request $request)
|
||||||
{
|
{
|
||||||
$creds = $request->validate([
|
$creds = $request->validate([
|
||||||
'email' => ['required', 'email'],
|
'email' => ['required', 'email'],
|
||||||
'password' => ['required']
|
'password' => ['required'],
|
||||||
]);
|
]);
|
||||||
if (Auth::attempt($creds)) {
|
if (Auth::attempt($creds)) {
|
||||||
$request->session()->regenerate();
|
$request->session()->regenerate();
|
||||||
|
@ -29,9 +30,9 @@ class LoginController extends Controller
|
||||||
Auth::logout();
|
Auth::logout();
|
||||||
|
|
||||||
$creds = $request->validate([
|
$creds = $request->validate([
|
||||||
'email' => ['required', 'email', 'unique:users'],
|
|
||||||
'name' => ['required', 'unique:users'],
|
'name' => ['required', 'unique:users'],
|
||||||
'password' => ['required']
|
'email' => ['required', 'email', 'unique:users'],
|
||||||
|
'password' => ['confirmed', Password::min(9)->uncompromised()],
|
||||||
]);
|
]);
|
||||||
$creds["password"] = Hash::make($creds["password"]);
|
$creds["password"] = Hash::make($creds["password"]);
|
||||||
User::create($creds);
|
User::create($creds);
|
||||||
|
@ -39,6 +40,41 @@ class LoginController extends Controller
|
||||||
return redirect("login")->withSuccess("Success! Now login");
|
return redirect("login")->withSuccess("Success! Now login");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function update(Request $request) {
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
$creds = $request->validate([
|
||||||
|
'name' => ['string'],
|
||||||
|
'email' => ['email', 'string'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if($creds["name"]) $user->name = $creds["name"];
|
||||||
|
if($creds["email"]) $user->email = $creds["email"];
|
||||||
|
$user->save();
|
||||||
|
return back();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatePassword(Request $request) {
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
$creds = $request->validate([
|
||||||
|
'old_password' => ['required'],
|
||||||
|
'password' => ['required', 'confirmed', Password::min(9)->uncompromised()],
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (Hash::check($creds["old_password"], $user->password)) {
|
||||||
|
$creds["password"] = Hash::make($creds["password"]);
|
||||||
|
$user->password = $creds["password"];
|
||||||
|
} else {
|
||||||
|
return back()->withErrors([
|
||||||
|
'Incorrect password'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->save();
|
||||||
|
return back();
|
||||||
|
}
|
||||||
|
|
||||||
public function logout(Request $request)
|
public function logout(Request $request)
|
||||||
{
|
{
|
||||||
Auth::logout();
|
Auth::logout();
|
|
@ -1,19 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Resources;
|
|
||||||
|
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
|
||||||
|
|
||||||
class order extends JsonResource
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Transform the resource into an array.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
|
||||||
*/
|
|
||||||
public function toArray($request)
|
|
||||||
{
|
|
||||||
return parent::toArray($request);
|
|
||||||
}
|
|
||||||
}
|
|
23
app/Models/Category.php
Normal file
23
app/Models/Category.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Category extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
use HasUUID;
|
||||||
|
public $primaryKey = "uuid";
|
||||||
|
|
||||||
|
protected $fillable = ['name'];
|
||||||
|
|
||||||
|
public function products() {
|
||||||
|
return $this->belongsToMany(Product::class,'categories_products','category_uuid');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function image() {
|
||||||
|
return $this->morphOne(Image::class, 'imageable');
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,4 +18,8 @@ class Image extends Model
|
||||||
{
|
{
|
||||||
return Storage::url($this->path);
|
return Storage::url($this->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function imageable() {
|
||||||
|
$this->morphTo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,6 @@ class Order extends Model
|
||||||
|
|
||||||
public function products()
|
public function products()
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(Product::class, "orderProduct", "orderId" ,"productId");
|
return $this->belongsToMany(Product::class, "orderProduct", "orderId" ,"productId")->withPivot("quantity");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,19 @@ class Product extends Model
|
||||||
use HasUUID;
|
use HasUUID;
|
||||||
public $primaryKey = "uuid";
|
public $primaryKey = "uuid";
|
||||||
|
|
||||||
public function images()
|
public function images() {
|
||||||
{
|
return $this->morphMany(Image::class, 'imageable');
|
||||||
return $this->hasMany(Image::class, "product_uuid", "uuid");
|
}
|
||||||
|
|
||||||
|
public function categories() {
|
||||||
|
return $this->belongsToMany(Category::class,'categories_products','product_uuid');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name',
|
'name',
|
||||||
'description',
|
'description',
|
||||||
|
'images',
|
||||||
|
'price',
|
||||||
|
'categories'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ class User extends Authenticatable
|
||||||
|
|
||||||
public function cart()
|
public function cart()
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(Product::class, "cart_items", "userID", "productID");
|
return $this->belongsToMany(Product::class, "cart_items", "userID", "productID")->withPivot("quantity");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function orders()
|
public function orders()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use App\Faker\CategoryNameProvider;
|
||||||
use App\Faker\ProductNameProvider;
|
use App\Faker\ProductNameProvider;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ class FakerServiceProvider extends ServiceProvider
|
||||||
$this->app->singleton(Generator::class, function () {
|
$this->app->singleton(Generator::class, function () {
|
||||||
$faker = Factory::create();
|
$faker = Factory::create();
|
||||||
$faker->addProvider(new ProductNameProvider($faker));
|
$faker->addProvider(new ProductNameProvider($faker));
|
||||||
|
$faker->addProvider(new CategoryNameProvider($faker));
|
||||||
return $faker;
|
return $faker;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
29
database/factories/CategoryFactory.php
Normal file
29
database/factories/CategoryFactory.php
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Models\Category;
|
||||||
|
use App\Models\Order;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
class CategoryFactory extends Factory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name of the factory's corresponding model.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $model = Category::class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the model's default state.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function definition()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => $this->faker->categoryName(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
use illuminate\support\str;
|
|
||||||
|
|
||||||
class ProductFactory extends Factory
|
class ProductFactory extends Factory
|
||||||
{
|
{
|
||||||
|
|
35
database/migrations/2021_12_08_183713_make_images_morph.php
Normal file
35
database/migrations/2021_12_08_183713_make_images_morph.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class MakeImagesMorph extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table("images", function(Blueprint $table) {
|
||||||
|
$table->uuidMorphs("imageable");
|
||||||
|
});
|
||||||
|
Schema::table("images", function(Blueprint $table) {
|
||||||
|
DB::table("images")->update(['imageable_id'=>DB::raw('`product_uuid`')], ['imageable_type' => "App\Models\Product"]);
|
||||||
|
$table->dropConstrainedForeignId("product_uuid");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
// Ehh don't wanna bother
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateCategoriesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('categories', function (Blueprint $table) {
|
||||||
|
$table->uuid("uuid")->primary();
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->string("name")->index()->unique();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('categories_products', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->foreignUuid("product_uuid")->references("uuid")->on("products")->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
$table->foreignUuid("category_uuid")->references("uuid")->on("categories")->cascadeOnDelete()->cascadeOnUpdate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('categories');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddCartItemQuantity extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('cart_items', function (Blueprint $table) {
|
||||||
|
$table->unsignedInteger("quantity")->default(1);
|
||||||
|
});
|
||||||
|
Schema::table('orderProduct', function (Blueprint $table) {
|
||||||
|
$table->unsignedInteger("quantity")->default(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('cart_items', function (Blueprint $table) {
|
||||||
|
$table->dropColumn("quantity");
|
||||||
|
});
|
||||||
|
Schema::table('orderProduct', function (Blueprint $table) {
|
||||||
|
$table->dropColumn("quantity");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\Category;
|
||||||
use App\Models\Image;
|
use App\Models\Image;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
@ -17,6 +18,7 @@ class DatabaseSeeder extends Seeder
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
User::factory(10)->create();
|
User::factory(10)->create();
|
||||||
|
|
||||||
$creds = [
|
$creds = [
|
||||||
'email' => config('admin.email'),
|
'email' => config('admin.email'),
|
||||||
'name' => config('admin.username'),
|
'name' => config('admin.username'),
|
||||||
|
@ -27,6 +29,7 @@ class DatabaseSeeder extends Seeder
|
||||||
$user->admin = true;
|
$user->admin = true;
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
\App\Models\Product::factory(10)->has(Image::factory()->count(3))->create();
|
$categories = Category::factory()->count(4)->create();
|
||||||
|
\App\Models\Product::factory(10)->has(Image::factory()->count(3))->hasAttached($categories)->create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
5
resources/scss/app.scss
vendored
5
resources/scss/app.scss
vendored
|
@ -37,6 +37,11 @@ nav {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cart-amount {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
21
resources/scss/user.scss
vendored
Normal file
21
resources/scss/user.scss
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
.cart-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
padding: 2em;
|
||||||
|
font-size: 0.8em;
|
||||||
|
&:nth-child(2n+1) {
|
||||||
|
background-color: #f0f0b1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.product-image {
|
||||||
|
height: 10rem;
|
||||||
|
}
|
||||||
|
.name-price-container {
|
||||||
|
& > * {
|
||||||
|
margin: 0.2em 0px;
|
||||||
|
}
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
43
resources/views/cart.blade.php
Normal file
43
resources/views/cart.blade.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
@push('head')
|
||||||
|
<link rel="stylesheet" href="{{ mix("css/user.css") }}">
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title', "Sklep")
|
||||||
|
|
||||||
|
@section('main')
|
||||||
|
<div>
|
||||||
|
<h2>Your cart:</h2>
|
||||||
|
<div>
|
||||||
|
<div class="cart-items">
|
||||||
|
@foreach($user->cart as $product)
|
||||||
|
{{-- dd($product->pivot->quantity) --}}
|
||||||
|
<div class="cart-item">
|
||||||
|
<x-product :product="$product" />
|
||||||
|
<form method="POST" action="{{route("addToCart",$product)}}">
|
||||||
|
<input type="number" value="{{ $product->pivot->quantity }}" name="quantity">
|
||||||
|
<button type="submit"> Zatwierdź </button>
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
</form>
|
||||||
|
<form class="remove-cart-form" action="{{ route("removeFromCart", $product) }}" method="post">
|
||||||
|
|
||||||
|
@csrf
|
||||||
|
<button type="submit"> Remove from cart </button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
@endforeach()
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="{{ route("order.create") }}" method="post">
|
||||||
|
@csrf
|
||||||
|
@foreach($user->cart as $product)
|
||||||
|
<input type="hidden" name="products[{{ $loop->index }}]" value="{{ $product->uuid }}">
|
||||||
|
<input type="hidden" name="product_quantities[{{ $loop->index }}]" value="{{ $product->pivot->quantity }}">
|
||||||
|
@endforeach()
|
||||||
|
<button type="submit"> Order </button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection()
|
27
resources/views/category.blade.php
Normal file
27
resources/views/category.blade.php
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
@push('head')
|
||||||
|
<link rel="stylesheet" href="{{ mix("css/user.css") }}">
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title', "Sklep")
|
||||||
|
|
||||||
|
@section('main')
|
||||||
|
<form action="{{route("category.store")}}" method="post">
|
||||||
|
<input type="text" name="name" placeholder="nazwa" >
|
||||||
|
<button type="submit">Dodaj</button>
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
|
@foreach($categories as $category)
|
||||||
|
<form action="{{route("category.edit", $category)}}" method="post">
|
||||||
|
<input type="text" name="name" value="{{ $category->name }}">
|
||||||
|
<button type="submit">Zatwierdź</button>
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
|
<form action="{{route("category.destroy", $category)}}" method="post">
|
||||||
|
<button type="submit">Usuń</button>
|
||||||
|
@csrf
|
||||||
|
@method("DELETE")
|
||||||
|
</form>
|
||||||
|
@endforeach
|
||||||
|
@endsection()
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<a href="{{ route('product.show', ['product' => $product]) }}">
|
<a href="{{ route('product.show', ['product' => $product]) }}">
|
||||||
<div class="product-container">
|
<div class="product-container">
|
||||||
<img class="product-image" src="@if(isset($product->images[0])) {{ $product->images[0]->URL() }} @else {{ asset("test.txt") }} @endif">
|
<img class="product-image" src="@if(isset($product->images[0])) {{ $product->images[0]->URL() }} @else {{ "" }} @endif">
|
||||||
<div class="name-price-container">
|
<div class="name-price-container">
|
||||||
<h2 class="product-name"> {{ $product->name }} </h2>
|
<h2 class="product-name"> {{ $product->name }} </h2>
|
||||||
<h3>{{ ($product->price) }}<span class="price-currency">zł</span></h3>
|
<h3>{{ ($product->price) }}<span class="price-currency">zł</span></h3>
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
@auth
|
@auth
|
||||||
<a href="{{ route("user") }}"> Hello {{ Auth::user()->name }} </a>
|
<a href="{{ route("cart") }}"> <i class="fa fa-shopping-cart"></i> <span class="cart-amount">{{count(Auth::user()->cart) }}</span> </a>
|
||||||
|
<a href="{{ route("user") }}"> {{ Auth::user()->name }} </a>
|
||||||
@endauth
|
@endauth
|
||||||
@guest
|
@guest
|
||||||
<a href="{{ route("login") }}">Login</a>
|
<a href="{{ route("login") }}">Login</a>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<input type="email" name="email" placeholder="email">
|
<input type="email" name="email" placeholder="email">
|
||||||
<input type="text" name="name" placeholder="Imie">
|
<input type="text" name="name" placeholder="Imie">
|
||||||
<input type="password" name="password" placeholder="Hasło">
|
<input type="password" name="password" placeholder="Hasło">
|
||||||
<input type="password" name="repeat-password" placeholder="Powtórz hasło">
|
<input type="password" name="password_confirmation" placeholder="Powtórz hasło">
|
||||||
<input type="submit">
|
<input type="submit">
|
||||||
@csrf
|
@csrf
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -15,9 +15,10 @@
|
||||||
@endif
|
@endif
|
||||||
<div>
|
<div>
|
||||||
<form method="post" action="{{ route("order.store") }}">
|
<form method="post" action="{{ route("order.store") }}">
|
||||||
@foreach($products as $product)
|
@foreach($products_with_quantities as $product)
|
||||||
<input type="hidden" name="products[{{ $loop->index }}]" value="{{ $product->uuid }}">
|
<input type="hidden" name="products[{{ $loop->index }}]" value="{{ $product[0]->uuid }}">
|
||||||
<x-product :product="$product" />
|
<x-product :product="$product[0]"/>
|
||||||
|
<input type="number" name="product_quantities[{{ $loop->index }}]" value="{{ $product[1] }}">
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
<textarea name="address"></textarea>
|
<textarea name="address"></textarea>
|
||||||
|
|
36
resources/views/product/edit.blade.php
Normal file
36
resources/views/product/edit.blade.php
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('title', "Sklep")
|
||||||
|
@section('main')
|
||||||
|
@if($new)
|
||||||
|
@php($post_url = route("product.store"))
|
||||||
|
@else
|
||||||
|
@php($post_url = route("product.update", $product))
|
||||||
|
@endif
|
||||||
|
<form action="{{ $post_url }}" method="post" enctype="multipart/form-data">
|
||||||
|
<input type="text" name="name" value="{{ $product->name }}">
|
||||||
|
<textarea name="description">{{ $product->description }}</textarea>
|
||||||
|
<input type="number" name="price" value="{{ $product->price }}">
|
||||||
|
<input type="file" name="image">
|
||||||
|
|
||||||
|
@foreach($categories as $category)
|
||||||
|
<input type="checkbox" id="category_{{$loop->index}}" name="category[{{$loop->index}}]" value="{{$category->uuid}}" @if($category->products()->find($product)) checked @endif>
|
||||||
|
<label for="category_{{$loop->index}}">{{$category->name}}</label>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<button type="submit">Zatwierdź</button>
|
||||||
|
|
||||||
|
@if(!$new)
|
||||||
|
@method("PATCH")
|
||||||
|
@endif
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
|
@foreach($product->images as $vis)
|
||||||
|
<form action="{{ route("image.destroy", $vis) }}" method="post">
|
||||||
|
<img src="{{ $vis->URL() }}"/>
|
||||||
|
<button type="submit">Usuń</button>
|
||||||
|
@method("DELETE")
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
|
@endforeach()
|
||||||
|
@endsection()
|
|
@ -18,6 +18,12 @@
|
||||||
<h2 class="product-name"> {{ $product->name }} </h2>
|
<h2 class="product-name"> {{ $product->name }} </h2>
|
||||||
<h3>{{ ($product->price) }}<span class="price-currency">zł</span></h3>
|
<h3>{{ ($product->price) }}<span class="price-currency">zł</span></h3>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="categories">
|
||||||
|
@foreach($product->categories as $category)
|
||||||
|
<a href="{{ route("main", ['category' => $category->name]) }}"> {{ $category->name }} </a>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="product-commands">
|
<div class="product-commands">
|
||||||
@auth
|
@auth
|
||||||
@if(!Auth::user()->cart()->find($product))
|
@if(!Auth::user()->cart()->find($product))
|
||||||
|
|
|
@ -1,33 +1,32 @@
|
||||||
|
@push('head')
|
||||||
|
<link rel="stylesheet" href="{{ mix("css/user.css") }}">
|
||||||
|
@endpush
|
||||||
|
|
||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('title', "Sklep")
|
@section('title', "Sklep")
|
||||||
|
|
||||||
@section('main')
|
@section('main')
|
||||||
<p>
|
<div>
|
||||||
|
<div>
|
||||||
<b>Welcome, you are logged in as {{ $user->name }}</b>
|
<b>Welcome, you are logged in as {{ $user->name }}</b>
|
||||||
</p>
|
<a href="{{route("logout")}}"> Logout </a>
|
||||||
<p>
|
|
||||||
<a href="/logout"> Logout </a>
|
|
||||||
</p>
|
|
||||||
<div>
|
|
||||||
<h2>Your cart:</h2>
|
|
||||||
<div>
|
|
||||||
<form action="{{ route("order.create") }}" method="post">
|
|
||||||
@csrf
|
|
||||||
@foreach($user->cart as $product)
|
|
||||||
<input type="hidden" name="products[{{ $loop->index }}]" value="{{ $product->uuid }}">
|
|
||||||
@endforeach()
|
|
||||||
<button type="submit"> Order </button>
|
|
||||||
</form>
|
|
||||||
@foreach($user->cart as $product)
|
|
||||||
<div>
|
|
||||||
<x-product :product="$product" />
|
|
||||||
</div>
|
</div>
|
||||||
<form action="{{ route("removeFromCart", $product) }}" method="post">
|
<div>
|
||||||
|
<form method="post" action="{{ route("user.update") }}">
|
||||||
|
<!-- TODO validation in js !-->
|
||||||
|
<input type="email" name="email" placeholder="email" value="{{ $user->email }}">
|
||||||
|
<input type="text" name="name" placeholder="Imie" value="{{ $user->name }}">
|
||||||
|
<input type="submit">
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
|
<form action="{{ route("user.updatepassword") }}" method="post">
|
||||||
|
<input type="password" name="old_password" placeholder="Obecne hasło">
|
||||||
|
<input type="password" name="password" placeholder="Nowe hasło">
|
||||||
|
<input type="password" name="password_confirmation" placeholder="Powtórz nowe hasło">
|
||||||
|
<input type="submit">
|
||||||
@csrf
|
@csrf
|
||||||
<button type="submit"> Remove from cart </button>
|
|
||||||
</form>
|
</form>
|
||||||
@endforeach()
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection()
|
@endsection()
|
||||||
|
|
|
@ -1,132 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
|
|
||||||
<title>Laravel</title>
|
|
||||||
|
|
||||||
<!-- Fonts -->
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
|
|
||||||
|
|
||||||
<!-- Styles -->
|
|
||||||
<style>
|
|
||||||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-t{border-top-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:h-20{height:5rem}.sm\:ml-0{margin-left:0}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}}@media (min-width:768px){.md\:border-t-0{border-top-width:0}.md\:border-l{border-left-width:1px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Nunito', sans-serif;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body class="antialiased">
|
|
||||||
<div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center py-4 sm:pt-0">
|
|
||||||
@if (Route::has('login'))
|
|
||||||
<div class="hidden fixed top-0 right-0 px-6 py-4 sm:block">
|
|
||||||
@auth
|
|
||||||
<a href="{{ url('/home') }}" class="text-sm text-gray-700 underline">Home</a>
|
|
||||||
@else
|
|
||||||
<a href="{{ route('login') }}" class="text-sm text-gray-700 underline">Log in</a>
|
|
||||||
|
|
||||||
@if (Route::has('register'))
|
|
||||||
<a href="{{ route('register') }}" class="ml-4 text-sm text-gray-700 underline">Register</a>
|
|
||||||
@endif
|
|
||||||
@endauth
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="max-w-6xl mx-auto sm:px-6 lg:px-8">
|
|
||||||
<div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
|
|
||||||
<svg viewBox="0 0 651 192" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-16 w-auto text-gray-700 sm:h-20">
|
|
||||||
<g clip-path="url(#clip0)" fill="#EF3B2D">
|
|
||||||
<path d="M248.032 44.676h-16.466v100.23h47.394v-14.748h-30.928V44.676zM337.091 87.202c-2.101-3.341-5.083-5.965-8.949-7.875-3.865-1.909-7.756-2.864-11.669-2.864-5.062 0-9.69.931-13.89 2.792-4.201 1.861-7.804 4.417-10.811 7.661-3.007 3.246-5.347 6.993-7.016 11.239-1.672 4.249-2.506 8.713-2.506 13.389 0 4.774.834 9.26 2.506 13.459 1.669 4.202 4.009 7.925 7.016 11.169 3.007 3.246 6.609 5.799 10.811 7.66 4.199 1.861 8.828 2.792 13.89 2.792 3.913 0 7.804-.955 11.669-2.863 3.866-1.908 6.849-4.533 8.949-7.875v9.021h15.607V78.182h-15.607v9.02zm-1.431 32.503c-.955 2.578-2.291 4.821-4.009 6.73-1.719 1.91-3.795 3.437-6.229 4.582-2.435 1.146-5.133 1.718-8.091 1.718-2.96 0-5.633-.572-8.019-1.718-2.387-1.146-4.438-2.672-6.156-4.582-1.719-1.909-3.032-4.152-3.938-6.73-.909-2.577-1.36-5.298-1.36-8.161 0-2.864.451-5.585 1.36-8.162.905-2.577 2.219-4.819 3.938-6.729 1.718-1.908 3.77-3.437 6.156-4.582 2.386-1.146 5.059-1.718 8.019-1.718 2.958 0 5.656.572 8.091 1.718 2.434 1.146 4.51 2.674 6.229 4.582 1.718 1.91 3.054 4.152 4.009 6.729.953 2.577 1.432 5.298 1.432 8.162-.001 2.863-.479 5.584-1.432 8.161zM463.954 87.202c-2.101-3.341-5.083-5.965-8.949-7.875-3.865-1.909-7.756-2.864-11.669-2.864-5.062 0-9.69.931-13.89 2.792-4.201 1.861-7.804 4.417-10.811 7.661-3.007 3.246-5.347 6.993-7.016 11.239-1.672 4.249-2.506 8.713-2.506 13.389 0 4.774.834 9.26 2.506 13.459 1.669 4.202 4.009 7.925 7.016 11.169 3.007 3.246 6.609 5.799 10.811 7.66 4.199 1.861 8.828 2.792 13.89 2.792 3.913 0 7.804-.955 11.669-2.863 3.866-1.908 6.849-4.533 8.949-7.875v9.021h15.607V78.182h-15.607v9.02zm-1.432 32.503c-.955 2.578-2.291 4.821-4.009 6.73-1.719 1.91-3.795 3.437-6.229 4.582-2.435 1.146-5.133 1.718-8.091 1.718-2.96 0-5.633-.572-8.019-1.718-2.387-1.146-4.438-2.672-6.156-4.582-1.719-1.909-3.032-4.152-3.938-6.73-.909-2.577-1.36-5.298-1.36-8.161 0-2.864.451-5.585 1.36-8.162.905-2.577 2.219-4.819 3.938-6.729 1.718-1.908 3.77-3.437 6.156-4.582 2.386-1.146 5.059-1.718 8.019-1.718 2.958 0 5.656.572 8.091 1.718 2.434 1.146 4.51 2.674 6.229 4.582 1.718 1.91 3.054 4.152 4.009 6.729.953 2.577 1.432 5.298 1.432 8.162 0 2.863-.479 5.584-1.432 8.161zM650.772 44.676h-15.606v100.23h15.606V44.676zM365.013 144.906h15.607V93.538h26.776V78.182h-42.383v66.724zM542.133 78.182l-19.616 51.096-19.616-51.096h-15.808l25.617 66.724h19.614l25.617-66.724h-15.808zM591.98 76.466c-19.112 0-34.239 15.706-34.239 35.079 0 21.416 14.641 35.079 36.239 35.079 12.088 0 19.806-4.622 29.234-14.688l-10.544-8.158c-.006.008-7.958 10.449-19.832 10.449-13.802 0-19.612-11.127-19.612-16.884h51.777c2.72-22.043-11.772-40.877-33.023-40.877zm-18.713 29.28c.12-1.284 1.917-16.884 18.589-16.884 16.671 0 18.697 15.598 18.813 16.884h-37.402zM184.068 43.892c-.024-.088-.073-.165-.104-.25-.058-.157-.108-.316-.191-.46-.056-.097-.137-.176-.203-.265-.087-.117-.161-.242-.265-.345-.085-.086-.194-.148-.29-.223-.109-.085-.206-.182-.327-.252l-.002-.001-.002-.002-35.648-20.524a2.971 2.971 0 00-2.964 0l-35.647 20.522-.002.002-.002.001c-.121.07-.219.167-.327.252-.096.075-.205.138-.29.223-.103.103-.178.228-.265.345-.066.089-.147.169-.203.265-.083.144-.133.304-.191.46-.031.085-.08.162-.104.25-.067.249-.103.51-.103.776v38.979l-29.706 17.103V24.493a3 3 0 00-.103-.776c-.024-.088-.073-.165-.104-.25-.058-.157-.108-.316-.191-.46-.056-.097-.137-.176-.203-.265-.087-.117-.161-.242-.265-.345-.085-.086-.194-.148-.29-.223-.109-.085-.206-.182-.327-.252l-.002-.001-.002-.002L40.098 1.396a2.971 2.971 0 00-2.964 0L1.487 21.919l-.002.002-.002.001c-.121.07-.219.167-.327.252-.096.075-.205.138-.29.223-.103.103-.178.228-.265.345-.066.089-.147.169-.203.265-.083.144-.133.304-.191.46-.031.085-.08.162-.104.25-.067.249-.103.51-.103.776v122.09c0 1.063.568 2.044 1.489 2.575l71.293 41.045c.156.089.324.143.49.202.078.028.15.074.23.095a2.98 2.98 0 001.524 0c.069-.018.132-.059.2-.083.176-.061.354-.119.519-.214l71.293-41.045a2.971 2.971 0 001.489-2.575v-38.979l34.158-19.666a2.971 2.971 0 001.489-2.575V44.666a3.075 3.075 0 00-.106-.774zM74.255 143.167l-29.648-16.779 31.136-17.926.001-.001 34.164-19.669 29.674 17.084-21.772 12.428-43.555 24.863zm68.329-76.259v33.841l-12.475-7.182-17.231-9.92V49.806l12.475 7.182 17.231 9.92zm2.97-39.335l29.693 17.095-29.693 17.095-29.693-17.095 29.693-17.095zM54.06 114.089l-12.475 7.182V46.733l17.231-9.92 12.475-7.182v74.537l-17.231 9.921zM38.614 7.398l29.693 17.095-29.693 17.095L8.921 24.493 38.614 7.398zM5.938 29.632l12.475 7.182 17.231 9.92v79.676l.001.005-.001.006c0 .114.032.221.045.333.017.146.021.294.059.434l.002.007c.032.117.094.222.14.334.051.124.088.255.156.371a.036.036 0 00.004.009c.061.105.149.191.222.288.081.105.149.22.244.314l.008.01c.084.083.19.142.284.215.106.083.202.178.32.247l.013.005.011.008 34.139 19.321v34.175L5.939 144.867V29.632h-.001zm136.646 115.235l-65.352 37.625V148.31l48.399-27.628 16.953-9.677v33.862zm35.646-61.22l-29.706 17.102V66.908l17.231-9.92 12.475-7.182v33.841z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-8 bg-white dark:bg-gray-800 overflow-hidden shadow sm:rounded-lg">
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2">
|
|
||||||
<div class="p-6">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path></svg>
|
|
||||||
<div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laravel.com/docs" class="underline text-gray-900 dark:text-white">Documentation</a></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ml-12">
|
|
||||||
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
|
|
||||||
Laravel has wonderful, thorough documentation covering every aspect of the framework. Whether you are new to the framework or have previous experience with Laravel, we recommend reading all of the documentation from beginning to end.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-6 border-t border-gray-200 dark:border-gray-700 md:border-t-0 md:border-l">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"></path><path d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>
|
|
||||||
<div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laracasts.com" class="underline text-gray-900 dark:text-white">Laracasts</a></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ml-12">
|
|
||||||
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
|
|
||||||
Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript development. Check them out, see for yourself, and massively level up your development skills in the process.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-6 border-t border-gray-200 dark:border-gray-700">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"></path></svg>
|
|
||||||
<div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laravel-news.com/" class="underline text-gray-900 dark:text-white">Laravel News</a></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ml-12">
|
|
||||||
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
|
|
||||||
Laravel News is a community driven portal and newsletter aggregating all of the latest and most important news in the Laravel ecosystem, including new package releases and tutorials.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-6 border-t border-gray-200 dark:border-gray-700 md:border-l">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
|
||||||
<div class="ml-4 text-lg leading-7 font-semibold text-gray-900 dark:text-white">Vibrant Ecosystem</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ml-12">
|
|
||||||
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
|
|
||||||
Laravel's robust library of first-party tools and libraries, such as <a href="https://forge.laravel.com" class="underline">Forge</a>, <a href="https://vapor.laravel.com" class="underline">Vapor</a>, <a href="https://nova.laravel.com" class="underline">Nova</a>, and <a href="https://envoyer.io" class="underline">Envoyer</a> help you take your projects to the next level. Pair them with powerful open source libraries like <a href="https://laravel.com/docs/billing" class="underline">Cashier</a>, <a href="https://laravel.com/docs/dusk" class="underline">Dusk</a>, <a href="https://laravel.com/docs/broadcasting" class="underline">Echo</a>, <a href="https://laravel.com/docs/horizon" class="underline">Horizon</a>, <a href="https://laravel.com/docs/sanctum" class="underline">Sanctum</a>, <a href="https://laravel.com/docs/telescope" class="underline">Telescope</a>, and more.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex justify-center mt-4 sm:items-center sm:justify-between">
|
|
||||||
<div class="text-center text-sm text-gray-500 sm:text-left">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<svg fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" stroke="currentColor" class="-mt-px w-5 h-5 text-gray-400">
|
|
||||||
<path d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"></path>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<a href="https://laravel.bigcartel.com" class="ml-1 underline">
|
|
||||||
Shop
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="ml-4 -mt-px w-5 h-5 text-gray-400">
|
|
||||||
<path d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<a href="https://github.com/sponsors/taylorotwell" class="ml-1 underline">
|
|
||||||
Sponsor
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ml-4 text-center text-sm text-gray-500 sm:text-right sm:ml-0">
|
|
||||||
Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }})
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,17 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Http\Controllers\ImageController;
|
use App\Http\Controllers\ImageController;
|
||||||
use App\Http\Controllers\LoginController;
|
use App\Http\Controllers\UserController;
|
||||||
use App\Http\Controllers\MainPageController;
|
use App\Http\Controllers\MainPageController;
|
||||||
use App\Http\Controllers\CartController;
|
use App\Http\Controllers\CartController;
|
||||||
|
use App\Http\Controllers\CategoryController;
|
||||||
use App\Http\Controllers\OrderController;
|
use App\Http\Controllers\OrderController;
|
||||||
use App\Http\Controllers\ProductController;
|
use App\Http\Controllers\ProductController;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|-------------------------------------------------------------------------- | Web Routes
|
||||||
| Web Routes
|
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here is where you can register web routes for your application. These
|
| Here is where you can register web routes for your application. These
|
||||||
|
@ -26,13 +26,16 @@ Route::get('/user', function () {
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
return view("user", ["user"=>$user]);
|
return view("user", ["user"=>$user]);
|
||||||
})->middleware("auth")->name("user");
|
})->middleware("auth")->name("user");
|
||||||
|
Route::post('/user', [UserController::class, "update"])->name("user.update");
|
||||||
|
Route::post('/user/password', [UserController::class, "updatePassword"])->name("user.updatepassword");
|
||||||
|
|
||||||
Route::view("/login", "login");
|
Route::view("/login", "login");
|
||||||
|
|
||||||
Route::post('/login', [LoginController::class, "authenticate"])->name("login");
|
Route::post('/login', [UserController::class, "authenticate"])->name("login");
|
||||||
Route::post('/register', [LoginController::class, "register"])->name("register");
|
Route::post('/register', [UserController::class, "register"])->name("register");
|
||||||
Route::any("/logout", [LoginController::class, "logout"])->name("logout");
|
Route::any("/logout", [UserController::class, "logout"])->name("logout");
|
||||||
|
|
||||||
|
Route::get("/cart", [CartController::class, "show"])->name("cart")->middleware("auth");
|
||||||
Route::post("/product/{product}/addToCart", [CartController::class, "addToCart"])->name("addToCart")->middleware("auth");
|
Route::post("/product/{product}/addToCart", [CartController::class, "addToCart"])->name("addToCart")->middleware("auth");
|
||||||
Route::post("/product/{product}/removeFromCart", [CartController::class, "removeFromCart"])->name("removeFromCart")->middleware("auth");
|
Route::post("/product/{product}/removeFromCart", [CartController::class, "removeFromCart"])->name("removeFromCart")->middleware("auth");
|
||||||
|
|
||||||
|
@ -42,4 +45,5 @@ Route::resource("product", ProductController::class)->only(["show"]);
|
||||||
Route::resource("order", OrderController::class)->middleware("auth");
|
Route::resource("order", OrderController::class)->middleware("auth");
|
||||||
Route::post('/order/create', [OrderController::class, "create"])->name("order.create");
|
Route::post('/order/create', [OrderController::class, "create"])->name("order.create");
|
||||||
|
|
||||||
Route::resource("image", ImageController::class)->only(["store", "delete", "create"])->middleware("auth.admin");
|
Route::resource("image", ImageController::class)->only(["store", "destroy", "create"])->middleware("auth.admin");
|
||||||
|
Route::resource("category", CategoryController::class)->only(["index","destroy","edit", "store"])->middleware("auth.admin");
|
||||||
|
|
5
webpack.mix.js
vendored
5
webpack.mix.js
vendored
|
@ -20,4 +20,7 @@ mix.js("resources/js/app.js", "public/js").sass(
|
||||||
).sass(
|
).sass(
|
||||||
"resources/scss/product.scss",
|
"resources/scss/product.scss",
|
||||||
"public/css"
|
"public/css"
|
||||||
);;
|
).sass(
|
||||||
|
"resources/scss/user.scss",
|
||||||
|
"public/css"
|
||||||
|
);
|
||||||
|
|
Loading…
Reference in a new issue