Merge branch 'react-version' of https://github.com/MarcEricMartel/420-5DW-HY-TP into react-version

This commit is contained in:
DavidBelisle 2022-10-17 23:38:07 -04:00
commit 91a03751d6
6 changed files with 253 additions and 140 deletions

View File

@ -4,6 +4,7 @@ using System.Linq;
using GrossesMitainesAPI.Data; using GrossesMitainesAPI.Data;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
namespace GrossesMitainesAPI.Controllers; namespace GrossesMitainesAPI.Controllers;
@ -30,17 +31,39 @@ public class ProductController : Controller {
} }
[HttpPost(Name = "Product")] [HttpPost(Name = "Product")]
public void Post(string title, string category, string description, decimal? price, decimal? promoprice, uint? quantity, bool? disc, string imagename) { public void Post(string title, string category, string description, decimal? price, decimal? promoprice, uint? quantity, string? status, string imagename) {
Product prod = new() { Product prod = new() {
Title = title, Title = title,
Category = category, Category = category,
Description = description, Description = description,
Price = price.HasValue? (decimal)price: 0.01M, Price = price.HasValue ? (decimal)price : 0.01M,
PromoPrice = promoprice.HasValue ? (decimal)promoprice : 0.01M, PromoPrice = promoprice.HasValue ? (decimal)promoprice : 0.01M,
Quantity = quantity.HasValue ? (uint)quantity : 0, Quantity = quantity.HasValue ? (uint)quantity : 0,
ImageName = imagename ImageName = imagename
}; };
switch (status) {
case "isAvailable":
prod.Status = Product.States.Available;
break;
case "isUnavailable":
prod.Status = Product.States.Unavailable;
break;
case "isBackOrder":
prod.Status = Product.States.BackOrder;
break; ;
case "isClearance":
prod.Status = Product.States.Clearance;
break;
case "isPromotion":
prod.Status = Product.States.Promotion;
break;
case "isDiscontinued":
prod.Status = Product.States.Discontinued;
break;
default: break;
}
if (prod.Price <= prod.PromoPrice) if (prod.Price <= prod.PromoPrice)
prod.PromoPrice = prod.Price - 0.01M; prod.PromoPrice = prod.Price - 0.01M;
@ -54,6 +77,63 @@ public class ProductController : Controller {
[HttpPut(Name = "Product")] [HttpPut(Name = "Product")]
public void Put(int id, string title, string category, string description, decimal? price, decimal? promoprice, uint? quantity, string? status, string imagename) { public void Put(int id, string title, string category, string description, decimal? price, decimal? promoprice, uint? quantity, string? status, string imagename) {
Product prod = _context.Products.Where(x => x.Id == id).FirstOrDefault();
if (prod == new Product())
Post(title, category, description, price, promoprice, quantity, status, imagename);
else try {
if (title != null || title != "")
prod.Title = title;
if (category != null || category != "")
prod.Category = category;
if (description != null || description != "")
prod.Description = description;
if (price.HasValue || price > 0)
prod.Price = (decimal)price;
if (promoprice.HasValue || promoprice > prod.Price)
prod.PromoPrice = (decimal)promoprice;
if (quantity.HasValue)
prod.Quantity = (uint)quantity;
switch (status) {
case "isAvailable":
prod.Status = Product.States.Available;
break;
case "isUnavailable":
prod.Status = Product.States.Unavailable;
break;
case "isBackOrder":
prod.Status = Product.States.BackOrder;
break; ;
case "isClearance":
prod.Status = Product.States.Clearance;
break;
case "isPromotion":
prod.Status = Product.States.Promotion;
break;
case "isDiscontinued":
prod.Status = Product.States.Discontinued;
break;
default: break;
}
if (imagename != null || imagename != "")
prod.ImageName = imagename;
_context.Products.Update(prod);
_context.SaveChanges();
} catch (Exception e) {
_logger.LogError(8, e.Message);
}
}
[HttpPatch(Name = "Product")]
public void Patch(int id, string title, string category, string description, decimal? price, decimal? promoprice, uint? quantity, string? status, string imagename) {
try { try {
Product prod = _context.Products.Where(x => x.Id == id).First(); Product prod = _context.Products.Where(x => x.Id == id).First();
@ -106,65 +186,4 @@ public class ProductController : Controller {
_logger.LogError(8, e.Message); _logger.LogError(8, e.Message);
} }
} }
}
[HttpPatch(Name = "Product")]
public void Patch(int id, string title, string category, string description, decimal? price, decimal? promoprice, uint? quantity, string? status, string imagename) {
try {
Product prod = _context.Products.Where(x => x.Id == id).First();
if (title != null)
prod.Title = title;
else prod.Title = "";
if (category != null)
prod.Category = category;
else prod.Category = "";
if (description != null)
prod.Description = description;
else prod.Description = "";
if (promoprice.HasValue || promoprice < prod.Price)
prod.PromoPrice = (decimal)promoprice;
else prod.PromoPrice = prod.Price - 0.01M;
if (quantity.HasValue)
prod.Quantity = (uint)quantity;
else prod.Quantity = 0;
switch (status) {
case "isAvailable":
prod.Status = Product.States.Available;
break;
case "isUnavailable":
prod.Status = Product.States.Unavailable;
break;
case "isBackOrder":
prod.Status = Product.States.BackOrder;
break; ;
case "isClearance":
prod.Status = Product.States.Clearance;
break;
case "isPromotion":
prod.Status = Product.States.Promotion;
break;
case "isDiscontinued":
prod.Status = Product.States.Discontinued;
break;
default:
prod.Status = prod.Quantity > 0 ? Product.States.Available : Product.States.Unavailable;
break;
}
if (imagename != null)
prod.ImageName = imagename;
else prod.ImageName = "";
_context.Products.Update(prod);
_context.SaveChanges();
} catch (Exception e) {
_logger.LogError(8, e.Message);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -6,6 +6,7 @@ const ItemList = ({ items }) => {
return ( return (
<> <>
<div className='item-list'> <div className='item-list'>
{items.length <= 0 && <p>Aucun morceaux à montrer...</p>}
{items.map((item) => {items.map((item) =>
<Link key={item.id} className='item-link' to={`/morceaux/${item.id}`}> <Link key={item.id} className='item-link' to={`/morceaux/${item.id}`}>
<Item imageUrl={item.imageName} <Item imageUrl={item.imageName}

View File

@ -0,0 +1,64 @@
import Dropdown from 'react-bootstrap/Dropdown'
import { useState } from 'react';
const Sorting = ({onChange}) => {
const [currentSort, setSort] = useState("...");
return (
<>
<Dropdown className='sorting-dropdown'>
<Dropdown.Toggle id="dropdown-sort">
{currentSort}
</Dropdown.Toggle>
<Dropdown.Menu className='sorting-menu'>
<Dropdown.Item key="0" onClick={() => {
setSort("Prix ascendants"); // Mets le nom afficher quand le dropdown est fermé
onChange("Price"); // Trigger le handler pour trier
}}>
Prix ascendants {/*Le nom de l'option*/}
</Dropdown.Item>
<Dropdown.Item key="1" onClick={() => {
setSort(" Prix déscendants");
onChange("PriceDesc");
}}>
Prix déscendants
</Dropdown.Item>
<Dropdown.Item key="2" onClick={() => {
setSort("Titre a -> z");
onChange("Title");
}}>
Titre a -{'>'} z
</Dropdown.Item>
<Dropdown.Item key="3" onClick={() => {
setSort("Titre z -> a");
onChange("TitleDesc");
}}>
Titre z -{'>'} a
</Dropdown.Item>
<Dropdown.Item key="4" onClick={() => {
setSort("Catégorie a -> z");
onChange("Category");
}}>
Catégorie a -{'>'} z
</Dropdown.Item>
<Dropdown.Item key="5" onClick={() => {
setSort("Catégorie z -> a");
onChange("CategoryDesc");
}}>
Catégorie z -{'>'} a
</Dropdown.Item>
<Dropdown.Item key="6" onClick={() => {
setSort("...");
onChange("");
}}>
...
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</>
);
}
export default Sorting;

View File

@ -2,107 +2,70 @@ import { Button } from 'react-bootstrap';
import { useEffect } from "react"; import { useEffect } from "react";
import ItemList from "../components/ItemList"; import ItemList from "../components/ItemList";
import { useState } from 'react'; import { useState } from 'react';
import Sorting from "../components/Sorting"
const Morceaux = (startingProducts) => { const Morceaux = (startingProducts) => {
// public enum States {
// Available,
// BackOrder,
// Unavailable,
// Clearance,
// Promotion,
// Discontinued
// }
// const products = [
// {
// "id":0,
// "name": "Ceinture flèchée",
// "status": 0,
// "price": 85.86,
// "newPrice": -1,
// "imageUrl": "/images/ceintureflechee.jpg"
// },
// {
// "id":1,
// "name": "Chandail de nowel",
// "status": 2,
// "price": 69.50,
// "newPrice": -1,
// "imageUrl": "/images/chandailquetaine.jpg"
// },
// {
// "id":2,
// "name": "Pantoufles du Canadien en Phentex",
// "status": 5,
// "price": 15.64,
// "newPrice": -1,
// "imageUrl": "/images/pantouflesCH.jpg"
// },
// {
// "id":3,
// "name": "Jean-Luc Mongrain",
// "status": 1,
// "price": 1453.12,
// "newPrice": -1,
// "imageUrl": "/images/jeanlucmongrain.jpg"
// },
// {
// "id":4,
// "name": "Mitaines de laine",
// "status": 4,
// "price": 24.99,
// "newPrice": 19.99,
// "imageUrl": "/images/mitaines.jpg"
// },
// {
// "id":5,
// "name": "Sous-vêtements coquins",
// "status": 3,
// "price": 19.99,
// "newPrice": 14.99,
// "imageUrl": "/images/kokin.jpg"
// },
// {
// "id":6,
// "name": "Doudou douce et grise",
// "status": 3,
// "price": 99.99,
// "newPrice": 89.99,
// "imageUrl": "/images/doudou.jpg"
// }
// ];
useEffect(() => { useEffect(() => {
document.title = 'Morceaux'; document.title = 'Morceaux';
}); });
const [products, setProducts] = useState([]); const [products, setProducts] = useState([]);
const [isLoading, setIsLoading] = useState(false);
var order = "";
var filterPrice = "";
var filterState = "";
const handleNextItems = async () => { const handleNextItems = async () => {
var url; var url;
if (products.length > 0) if (products.length > 0)
url = `https://localhost:7292/api/Inventory?lastId=${products[products.length - 1].id}`; url = `https://localhost:7292/api/Inventory?lastId=${products[products.length - 1].id}&order=${order}&filterPrice=${filterPrice}&filterState=${filterState}`;
else else
url = 'https://localhost:7292/api/Inventory' url = `https://localhost:7292/api/Inventory?order=${order}&filterPrice=${filterPrice}&filterState=${filterState}`
setIsLoading(true);
const response = await fetch(url);
const json = await response.json();
//TODO: regler bug qui permet d'avoir des duplicats (trouver une façon de skipper les duplicats)
if (json.length > 0)
setProducts([...products, ...json]);
setIsLoading(false);
}
const handleOrder = async (sortBy) => {
order = sortBy;
var url = `https://localhost:7292/api/Inventory?order=${order}&filterPrice=${filterPrice}&filterState=${filterState}`;
setIsLoading(true);
const response = await fetch(url); const response = await fetch(url);
const json = await response.json(); const json = await response.json();
if (json.length > 0) if (json.length > 0)
setProducts([...products, ...json]); setProducts([...json]);
setIsLoading(false);
}
const handleFilterPrice = async () => {
}
const handleFilterState = async () => {
} }
return ( return (
<div className="morceaux"> <div className="morceaux"div>
<div className="sorting-container">
<Sorting onChange={handleOrder} />
</div>
<div className="morceaux-container"> <div className="morceaux-container">
<ItemList items={products} /> <ItemList items={products} />
</div> </div>
{/* faire un spinner qui tourne quand ça load */} <div className={isLoading ? "cat-load" : "d-none cat-load"} />
<script type="text/javascript" async src="https://tenor.com/embed.js"></script>
<div> <div>
<Button onClick={handleNextItems} className='btn-load-more'> <Button onClick={handleNextItems} className='btn-load-more'>
... ...

View File

@ -450,7 +450,33 @@ html {
background-color: beige; background-color: beige;
} }
.sorting-container{
width:100%;
float:right;
margin-right:5%;
margin-left:5%;
margin-top:15px;
margin-bottom:15px;
}
.sorting-dropdown{
width:fit-content;
margin:auto;
float:right;
}
.cat-load{
display:block;
margin:auto;
width:auto;
background-image: url("/public/images/cat-yarn.gif");
background-repeat: no-repeat;
background-color: white;
background-size: contain;
background-position: center;
mix-blend-mode: multiply;
height:200px;
}
/* -------------------------------------------------------- */ /* -------------------------------------------------------- */
/* specification pour les moyennes écrans /* specification pour les moyennes écrans
/* -------------------------------------------------------- */ /* -------------------------------------------------------- */
@ -458,6 +484,38 @@ html {
.item { .item {
width: 45%; width: 45%;
} }
.btn-load-more{
width:45%;
}
.sorting-dropdown{
width:100%;
float:none;
}
.sorting-dropdown button{
height:60px !important;
width: 100% !important;
font-size: larger;
}
.sorting-container{
width: 90%;
float:none;
}
.sorting-menu{
width: 100%;
}
.sorting-menu a {
font-size: larger;
height: 50px;
background-color: beige;
border: 2px white solid;
}
} }
@ -471,6 +529,14 @@ html {
width: 85%; width: 85%;
} }
.btn-load-more{
width:85%;
}
.btn-load-more{
width:85%;
}
.featured-img { .featured-img {
border: 5px purple double; border: 5px purple double;
width: 100%; width: 100%;