EF17 So Many Addresses
This commit is contained in:
parent
980cb1ab53
commit
73421ea1ef
@ -104,10 +104,13 @@ public class AddressController : Controller {
|
||||
}
|
||||
|
||||
[EnableCors("_myAllowSpecificOrigins"), HttpPost]
|
||||
public async Task<ActionResult<AddressModel>> Post(AddressModel ad) {
|
||||
public async Task<ActionResult<AddressModel>> Post([FromForm] AddressModel ad) {
|
||||
string id;
|
||||
|
||||
try {
|
||||
var user = await _userMan.GetUserAsync(_signInMan.Context.User);
|
||||
user.Adresses.Add(ad);
|
||||
id = _signInMan.Context.User.Identity.GetUserId();
|
||||
_context.Users.Where(x => x.Id == id).Include("Adresses").First().Adresses.Add(ad);
|
||||
_context.SaveChanges();
|
||||
} catch (Exception e) {
|
||||
_logger.LogError(10, e.Message);
|
||||
|
@ -0,0 +1,31 @@
|
||||
import { useState } from 'react';
|
||||
import { faTimes } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
const Address = ({ address, onDelete }) => {
|
||||
return (
|
||||
<div className="inventaire-item">
|
||||
<div className='simple-item-top-container'>
|
||||
<h3 className='simple-item-title' >
|
||||
{address.civicNumber} {address.street}
|
||||
</h3>
|
||||
<h1 className='simple-item-buttons'>
|
||||
<FontAwesomeIcon icon={faTimes} className='.btn-effacer-morceau' style={{ color: "red", cursor: 'pointer' }}
|
||||
onClick={() => onDelete(address)} />
|
||||
</h1>
|
||||
</div>
|
||||
{address.appartment != null ?
|
||||
<h5>
|
||||
App: {address.appartment}
|
||||
</h5>
|
||||
:
|
||||
null
|
||||
}
|
||||
<div>
|
||||
<p> {address.city}, {address.province}, {address.country}, {address.postalCode}</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Address;
|
@ -17,6 +17,7 @@ import React from 'react';
|
||||
import Invoices from "../pages/Invoices";
|
||||
import Cookies from "universal-cookie";
|
||||
import ReviewInvoice from "../pages/ReviewInvoice";
|
||||
import MyAddresses from "../pages/MyAddresses";
|
||||
|
||||
const App = () => {
|
||||
const cookies = new Cookies();
|
||||
@ -53,6 +54,7 @@ const App = () => {
|
||||
<Route path="myinvoices" element={<MyInvoices />} />
|
||||
<Route path="invoices" element={<Invoices />} />
|
||||
<Route path="reviewinvoice" element={<ReviewInvoice />} />
|
||||
<Route path="myaddresses" element={<MyAddresses />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
|
@ -137,7 +137,7 @@ export default function App() {
|
||||
Adresse
|
||||
<Form.Select onChange={(e) => setFormAddress(userAddresses[e.target.value])}>
|
||||
{userAddresses.map((a, i) => (
|
||||
<option key={a.id} value={i} >{a.civicNumber} {a.street} </option> //{a.civicNumber} {a.street}
|
||||
<option key={a.id} value={i} >{a.civicNumber} {a.street} </option>
|
||||
))}
|
||||
</Form.Select>
|
||||
</h5>
|
||||
|
238
GrossesMitaines/grosses-mitaines-ui/src/pages/MyAddresses.js
Normal file
238
GrossesMitaines/grosses-mitaines-ui/src/pages/MyAddresses.js
Normal file
@ -0,0 +1,238 @@
|
||||
import { useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
import { Button } from "react-bootstrap";
|
||||
import { useForm } from "react-hook-form";
|
||||
import Cookies from "universal-cookie";
|
||||
import { Form } from "react-bootstrap";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Address from "../components/Address";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import { Alert } from "react-bootstrap";
|
||||
|
||||
|
||||
const MyAddresses = () => {
|
||||
const { register, handleSubmit, setValue, formState: { errors } } = useForm();
|
||||
const cookies = new Cookies();
|
||||
const [userAddresses, setUserAddresses] = useState([]);
|
||||
const [alertTitle, setAlertTitle] = useState("");
|
||||
const [alertMessage, setAlertMessage] = useState("");
|
||||
const [showAlert, setShowAlert] = useState(false);
|
||||
const [isFormvisible, setFormVisibility] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const mySwal = withReactContent(Swal);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
const userInfo = cookies.get("GMGM");
|
||||
if (userInfo != null && userInfo.LoggedIn == true) {
|
||||
|
||||
fetch("https://localhost:7292/api/Address", {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
mode: 'cors'
|
||||
},).then(async (response) => {
|
||||
if (response.ok) {
|
||||
const json = await response.json();
|
||||
setUserAddresses(json);
|
||||
setIsLoading(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (userAddresses.length == 0) {
|
||||
// if (cookies.get('addresses') != null && cookies.get('addresses').length != 0)
|
||||
// setUserAddresses(cookies.get('addresses'));
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
// useEffect(() => {
|
||||
// cookies.set('addresses', userAddresses, { path: '/', SameSite: 'strict', secure: true, maxAge: 2592000 })
|
||||
|
||||
|
||||
// }, [userAddresses]);
|
||||
|
||||
const OnDelete = async (address) => {
|
||||
mySwal.fire({
|
||||
title: `Effacer ${address.civicNumber} ${address.street}?`,
|
||||
text: 'Êtes-vous certain de vouloir effacer cette adresse (cette action est irréversible)?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Oui',
|
||||
cancelButtonText: 'Non',
|
||||
}).then(async (result) => {
|
||||
if (result.isConfirmed) {
|
||||
fetch(`https://localhost:7292/api/Address?id=${address.id}`, {
|
||||
method: 'DELETE',
|
||||
mode: 'cors',
|
||||
credentials: 'include'
|
||||
}).then(async (response) => {
|
||||
console.log(response);
|
||||
if (response.ok) {
|
||||
const deletedId = await response.json();
|
||||
setUserAddresses(userAddresses.filter((address) => address.id !== deletedId));
|
||||
|
||||
onShowAlert('Suppression de:', `${address.civicNumber} ${address.street} avec succès!`, 2000);
|
||||
}
|
||||
else {
|
||||
console.log("test");
|
||||
mySwal.fire({
|
||||
title: `Erreur lors de la suppression de ${address.civicNumber} ${address.street}`,
|
||||
text: `L'erreur: ${response}`,
|
||||
icon: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const onSubmit = async (address) => {
|
||||
console.log(address);
|
||||
|
||||
let formData = new FormData();
|
||||
Object.keys(address).map((k) => {
|
||||
formData.set(k, address[k]);
|
||||
});
|
||||
|
||||
console.log(formData);
|
||||
|
||||
const response = await fetch(`https://localhost:7292/api/Address`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'accept': 'application/json',
|
||||
},
|
||||
body: formData
|
||||
})
|
||||
|
||||
const newAddress = await response.json();
|
||||
console.log(newAddress);
|
||||
|
||||
if (response.ok) {
|
||||
setUserAddresses([...userAddresses, { ...newAddress }]);
|
||||
|
||||
onShowAlert('Création de:', `${address.civicNumber} ${address.street} avec succès!`);
|
||||
setFormVisibility(false);
|
||||
}
|
||||
else
|
||||
console.log("Erreur de creation " + address.civicNumber + " " + address.street);
|
||||
}
|
||||
|
||||
const onShowAlert = (title, message, time) => {
|
||||
|
||||
setAlertTitle(title);
|
||||
setAlertMessage(message);
|
||||
setShowAlert(true);
|
||||
|
||||
window.setTimeout(() => { setShowAlert(false); }, time);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="inventaire">
|
||||
<Alert variant="success" show={showAlert}>
|
||||
<b>{alertTitle}</b> {alertMessage}
|
||||
</Alert>
|
||||
<header className='header'>
|
||||
<h1>Adresses</h1>
|
||||
<Button
|
||||
className={isFormvisible ? 'btn-fermer' : 'btn-ajouter'}
|
||||
onClick={() => setFormVisibility(!isFormvisible)}>
|
||||
{isFormvisible ? 'Fermer' : 'Ajouter'}
|
||||
</Button>
|
||||
|
||||
</header>
|
||||
{isFormvisible &&
|
||||
<div className="form-container">
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<h4 className="text-center">Ajouter une adresse</h4>
|
||||
<div className="Error_color">
|
||||
<div className="formulaire-address">
|
||||
<div className="form-group">
|
||||
<label>Numéro civique*: </label>
|
||||
<input type="number" min="0" {...register("civicNumber", { required: true })}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{errors.civicNumber && errors.civicNumber.type === 'required' && <span>Vous devez entrer une numéro civique!</span>}
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>Rue*: </label>
|
||||
<input {...register("street", { required: true, minLength: 3, maxLength: 50 })}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{errors.street && errors.street.type === 'required' && <span>Vous devez entrer votre rue!</span>}
|
||||
{errors.street && errors.street.type === 'minLength' && <span>Votre rue doit avoir au moins 3 lettres!</span>}
|
||||
{errors.street && errors.street.type === 'maxLength' && <span>Votre rue doit avoir moins de 51 lettres!</span>}
|
||||
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>Numéro d'appartement: </label>
|
||||
<input {...register("appartment", { required: false })}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>Ville*: </label>
|
||||
<input {...register("city", { required: true, minLength: 4, maxLength: 50 })}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{errors.city && errors.city.type === 'required' && <span>Vous devez entrer votre ville!</span>}
|
||||
{errors.city && errors.city.type === 'minLength' && <span>Votre ville doit avoir au moins 4 lettres!</span>}
|
||||
{errors.city && errors.city.type === 'maxLength' && <span>Votre ville doit avoir moins de 51 lettres!</span>}
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>Province (abréviation)*: </label>
|
||||
<input placeholder="Exemple: QC" {...register("province", { required: true, maxLength: 3 })}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{errors.province && errors.province.type === 'required' && <span>Vous devez entrer votre province!</span>}
|
||||
{errors.province && errors.province.type === 'maxLength' && <span>Votre province doit avoir moins de 4 lettres!</span>}
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>Pays*: </label>
|
||||
<input {...register("country", { required: true, minLength: 4, maxLength: 30 })}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{errors.country && errors.country.type === 'required' && <span>Vous devez entrer votre pays!</span>}
|
||||
{errors.country && errors.country.type === 'minLength' && <span>Votre pays doit avoir au moins 4 lettres!</span>}
|
||||
{errors.cicountryty && errors.country.type === 'maxLength' && <span>Votre pays doit avoir moins de 31 lettres!</span>}
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>Code postal*: </label>
|
||||
<input {...register("postalCode", { required: true })}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{errors.postalCode && errors.postalCode.type === 'required' && <span>Vous devez entrer votre code postal!</span>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<Button className="btn-primary btn-ajouter-morceau" type="submit" >Confirmer</Button>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
{isLoading && <div className="cat-load" />}
|
||||
{userAddresses.length > 0 ?
|
||||
userAddresses.map((add) => (
|
||||
add &&
|
||||
<Address key={add.id}
|
||||
address={add}
|
||||
onDelete={OnDelete}
|
||||
/>
|
||||
))
|
||||
:
|
||||
('Il n\'y a pas d\'adresses!')}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MyAddresses;
|
Loading…
Reference in New Issue
Block a user