chore: update nginx docker compose

This commit is contained in:
2026-01-22 22:23:37 +01:00
parent c3ac31917a
commit 325b1b7c10
15 changed files with 606 additions and 638 deletions
@@ -114,14 +114,14 @@ const ProductDetailsModal: React.FC<ProductDetailsModalProps> = ({
<div className="media-viewer">
{currentMedia?.type === "image" ? (
<img
src={`http://localhost:8080${currentMedia.url}`}
src={`${currentMedia.url}`}
alt={product.name}
className="media-display"
/>
) : currentMedia?.type === "video" ? (
<div className="video-container">
<video
src={`http://localhost:8080${currentMedia.url}`}
src={`${currentMedia.url}`}
controls
className="media-display"
>
@@ -179,7 +179,7 @@ const ProductDetailsModal: React.FC<ProductDetailsModalProps> = ({
>
{media.type === "image" ? (
<img
src={`http://localhost:8080${media.url}`}
src={`{product.media[0].url}${media.url}`}
alt={`Media ${index + 1}`}
/>
) : (
+512 -424
View File
@@ -6,457 +6,545 @@
// ✅ Upload séparé des médias
// ✅ Boutons au lieu de select (comme AdminUsers)
import React, { useState } from 'react';
import { X, Plus, Trash2, Upload, DollarSign, Image as ImageIcon } from 'lucide-react';
import { updateProductAdmin, deleteProductMediaAdmin, uploadProductMediaAdmin } from '../api/api_admin';
import type { Product, ProductPrice } from '../api/api_admin_types';
import './ProductModal.css';
import React, { useState } from "react";
import {
X,
Plus,
Trash2,
Upload,
DollarSign,
Image as ImageIcon,
} from "lucide-react";
import {
updateProductAdmin,
deleteProductMediaAdmin,
uploadProductMediaAdmin,
} from "../api/api_admin";
import type { Product, ProductPrice } from "../api/api_admin_types";
import "./ProductModal.css";
interface ProductEditModalProps {
product: Product;
onClose: () => void;
onSuccess: () => void;
product: Product;
onClose: () => void;
onSuccess: () => void;
}
const ProductEditModal: React.FC<ProductEditModalProps> = ({ product, onClose, onSuccess }) => {
// ============================================
// 📝 STATE
// ============================================
const [name, setName] = useState(product.name);
const [category, setCategory] = useState(product.category);
const [description, setDescription] = useState(product.description);
const [stock, setStock] = useState(product.stock);
const [prices, setPrices] = useState<ProductPrice[]>(
product.prices && product.prices.length > 0
? product.prices
: [{ quantity: 1, price: 0 }]
);
const [existingMedia, setExistingMedia] = useState(product.media || []);
const [newMediaFiles, setNewMediaFiles] = useState<File[]>([]);
const [mediaToDelete, setMediaToDelete] = useState<number[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const ProductEditModal: React.FC<ProductEditModalProps> = ({
product,
onClose,
onSuccess,
}) => {
// ============================================
// 📝 STATE
// ============================================
const [name, setName] = useState(product.name);
const [category, setCategory] = useState(product.category);
const [description, setDescription] = useState(product.description);
const [stock, setStock] = useState(product.stock);
const [prices, setPrices] = useState<ProductPrice[]>(
product.prices && product.prices.length > 0
? product.prices
: [{ quantity: 1, price: 0 }],
);
const [existingMedia, setExistingMedia] = useState(product.media || []);
const [newMediaFiles, setNewMediaFiles] = useState<File[]>([]);
const [mediaToDelete, setMediaToDelete] = useState<number[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
// ✅ Options de catégories
const categoryOptions = [
{ value: 'weed&hash', label: 'Weed & Hash' },
{ value: 'zipette&co', label: 'Zipette & Co' },
{ value: 'gros&semi', label: 'Gros & Semi' }
];
// ✅ Options de catégories
const categoryOptions = [
{ value: "weed&hash", label: "Weed & Hash" },
{ value: "zipette&co", label: "Zipette & Co" },
{ value: "gros&semi", label: "Gros & Semi" },
];
// ============================================
// 💰 GESTION DES PRIX
// ============================================
const addPriceRow = () => {
setPrices([...prices, { quantity: 1, price: 0 }]);
};
// ============================================
// 💰 GESTION DES PRIX
// ============================================
const addPriceRow = () => {
setPrices([...prices, { quantity: 1, price: 0 }]);
};
const removePriceRow = (index: number) => {
if (prices.length > 1) {
setPrices(prices.filter((_, i) => i !== index));
}
};
const updatePrice = (index: number, field: 'quantity' | 'price', value: number) => {
const newPrices = [...prices];
newPrices[index][field] = value;
setPrices(newPrices);
};
// ============================================
// 📁 GESTION DES MÉDIAS
// ============================================
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files) {
const newFiles = Array.from(e.target.files);
setNewMediaFiles([...newMediaFiles, ...newFiles]);
console.log(`📁 ${newFiles.length} nouveau(x) fichier(s) ajouté(s)`);
}
};
const removeNewFile = (index: number) => {
setNewMediaFiles(newMediaFiles.filter((_, i) => i !== index));
};
const markMediaForDeletion = (mediaId: number) => {
setMediaToDelete([...mediaToDelete, mediaId]);
setExistingMedia(existingMedia.filter(m => m.id !== mediaId));
console.log(`🗑️ Média ${mediaId} marqué pour suppression`);
};
// ============================================
// ✅ VALIDATION
// ============================================
const validateForm = (): string | null => {
if (!name.trim()) return 'Le nom est requis';
if (!description.trim()) return 'La description est requise';
if (stock < 0) return 'Le stock ne peut pas être négatif';
if (prices.length === 0) return 'Au moins un prix est requis';
for (const price of prices) {
if (price.quantity <= 0) return 'Toutes les quantités doivent être positives';
if (price.price <= 0) return 'Tous les prix doivent être positifs';
}
return null;
};
// ============================================
// 📤 SOUMISSION - VERSION CORRIGÉE
// ============================================
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const validationError = validateForm();
if (validationError) {
setError(validationError);
return;
}
if (!product.id) {
setError('ID du produit manquant');
return;
}
try {
setLoading(true);
setError(null);
console.log('📤 [EDIT_MODAL] Début de la mise à jour du produit:', product.id);
// ============================================
// ÉTAPE 1: Supprimer les médias marqués
// ============================================
if (mediaToDelete.length > 0) {
console.log(`🗑️ Suppression de ${mediaToDelete.length} média(s)...`);
for (const mediaId of mediaToDelete) {
try {
await deleteProductMediaAdmin(product.id, mediaId);
console.log(`✅ Média ${mediaId} supprimé`);
} catch (err) {
console.warn(`⚠️ Erreur suppression média ${mediaId}:`, err);
}
const removePriceRow = (index: number) => {
if (prices.length > 1) {
setPrices(prices.filter((_, i) => i !== index));
}
}
};
// ============================================
// ÉTAPE 2: Préparer les données de mise à jour (JSON)
// ============================================
const updateData: Partial<Product> = {
name: name.trim(),
category,
description: description.trim(),
stock,
prices: prices.map(p => ({
quantity: p.quantity,
price: p.price
}))
};
const updatePrice = (
index: number,
field: "quantity" | "price",
value: number,
) => {
const newPrices = [...prices];
newPrices[index][field] = value;
setPrices(newPrices);
};
console.log('📝 [EDIT_MODAL] Données de mise à jour:', updateData);
// ============================================
// 📁 GESTION DES MÉDIAS
// ============================================
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files) {
const newFiles = Array.from(e.target.files);
setNewMediaFiles([...newMediaFiles, ...newFiles]);
console.log(
`📁 ${newFiles.length} nouveau(x) fichier(s) ajouté(s)`,
);
}
};
// ============================================
// ÉTAPE 3: Mettre à jour le produit
// ============================================
const response = await updateProductAdmin(product.id, updateData);
const removeNewFile = (index: number) => {
setNewMediaFiles(newMediaFiles.filter((_, i) => i !== index));
};
if (!response.success) {
console.error('❌ [EDIT_MODAL] Erreur API:', response.error);
setError(response.error || 'Erreur lors de la mise à jour du produit');
setLoading(false);
return;
}
const markMediaForDeletion = (mediaId: number) => {
setMediaToDelete([...mediaToDelete, mediaId]);
setExistingMedia(existingMedia.filter((m) => m.id !== mediaId));
console.log(`🗑️ Média ${mediaId} marqué pour suppression`);
};
console.log('✅ [EDIT_MODAL] Produit mis à jour avec succès');
// ============================================
// ✅ VALIDATION
// ============================================
const validateForm = (): string | null => {
if (!name.trim()) return "Le nom est requis";
if (!description.trim()) return "La description est requise";
if (stock < 0) return "Le stock ne peut pas être négatif";
if (prices.length === 0) return "Au moins un prix est requis";
// ============================================
// ÉTAPE 4: Upload des nouveaux médias
// ============================================
if (newMediaFiles.length > 0) {
console.log(`📤 [EDIT_MODAL] Upload de ${newMediaFiles.length} nouveau(x) média(s)...`);
for (const file of newMediaFiles) {
try {
const fileType = file.type.startsWith('image/') ? 'image' : 'video';
const uploadResponse = await uploadProductMediaAdmin(product.id, file, fileType);
if (uploadResponse.success) {
console.log(`✅ Média uploadé: ${file.name}`);
} else {
console.warn(`⚠️ Erreur upload ${file.name}:`, uploadResponse.error);
for (const price of prices) {
if (price.quantity <= 0)
return "Toutes les quantités doivent être positives";
if (price.price <= 0) return "Tous les prix doivent être positifs";
}
return null;
};
// ============================================
// 📤 SOUMISSION - VERSION CORRIGÉE
// ============================================
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const validationError = validateForm();
if (validationError) {
setError(validationError);
return;
}
if (!product.id) {
setError("ID du produit manquant");
return;
}
try {
setLoading(true);
setError(null);
console.log(
"📤 [EDIT_MODAL] Début de la mise à jour du produit:",
product.id,
);
// ============================================
// ÉTAPE 1: Supprimer les médias marqués
// ============================================
if (mediaToDelete.length > 0) {
console.log(
`🗑️ Suppression de ${mediaToDelete.length} média(s)...`,
);
for (const mediaId of mediaToDelete) {
try {
await deleteProductMediaAdmin(product.id, mediaId);
console.log(`✅ Média ${mediaId} supprimé`);
} catch (err) {
console.warn(
`⚠️ Erreur suppression média ${mediaId}:`,
err,
);
}
}
}
} catch (err) {
console.warn(`⚠️ Erreur upload ${file.name}:`, err);
}
// ============================================
// ÉTAPE 2: Préparer les données de mise à jour (JSON)
// ============================================
const updateData: Partial<Product> = {
name: name.trim(),
category,
description: description.trim(),
stock,
prices: prices.map((p) => ({
quantity: p.quantity,
price: p.price,
})),
};
console.log("📝 [EDIT_MODAL] Données de mise à jour:", updateData);
// ============================================
// ÉTAPE 3: Mettre à jour le produit
// ============================================
const response = await updateProductAdmin(product.id, updateData);
if (!response.success) {
console.error("❌ [EDIT_MODAL] Erreur API:", response.error);
setError(
response.error ||
"Erreur lors de la mise à jour du produit",
);
setLoading(false);
return;
}
console.log("✅ [EDIT_MODAL] Produit mis à jour avec succès");
// ============================================
// ÉTAPE 4: Upload des nouveaux médias
// ============================================
if (newMediaFiles.length > 0) {
console.log(
`📤 [EDIT_MODAL] Upload de ${newMediaFiles.length} nouveau(x) média(s)...`,
);
for (const file of newMediaFiles) {
try {
const fileType = file.type.startsWith("image/")
? "image"
: "video";
const uploadResponse = await uploadProductMediaAdmin(
product.id,
file,
fileType,
);
if (uploadResponse.success) {
console.log(`✅ Média uploadé: ${file.name}`);
} else {
console.warn(
`⚠️ Erreur upload ${file.name}:`,
uploadResponse.error,
);
}
} catch (err) {
console.warn(`⚠️ Erreur upload ${file.name}:`, err);
}
}
}
console.log("🎉 [EDIT_MODAL] Toutes les modifications appliquées");
// Fermer et rafraîchir
onSuccess();
} catch (error) {
console.error("❌ [EDIT_MODAL] Erreur:", error);
setError(
error instanceof Error ? error.message : "Erreur inconnue",
);
} finally {
setLoading(false);
}
}
};
console.log('🎉 [EDIT_MODAL] Toutes les modifications appliquées');
// Fermer et rafraîchir
onSuccess();
} catch (error) {
console.error('❌ [EDIT_MODAL] Erreur:', error);
setError(error instanceof Error ? error.message : 'Erreur inconnue');
} finally {
setLoading(false);
}
};
// ============================================
// 🎨 RENDER
// ============================================
return (
<>
<div className="modal-overlay" onClick={onClose} />
<div className="product-modal edit-modal">
{/* Header */}
<div className="modal-header">
<h2>Modifier le Produit</h2>
<button className="close-modal" onClick={onClose} disabled={loading}>
<X size={24} />
</button>
</div>
{/* Content */}
<form onSubmit={handleSubmit} className="modal-content">
{error && (
<div className="error-message">
<p>{error}</p>
</div>
)}
{/* Informations de base */}
<div className="form-section">
<h3>Informations de Base</h3>
<div className="form-group">
<label htmlFor="name">Nom du Produit *</label>
<input
id="name"
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Ex: OG Kush Premium"
disabled={loading}
required
/>
</div>
{/* ✅ CATÉGORIE AVEC BOUTONS AU LIEU DE SELECT */}
<div className="form-group">
<label>Catégorie *</label>
<div className="filter-buttons">
{categoryOptions.map(option => (
<button
key={option.value}
type="button"
className={category === option.value ? 'active' : ''}
onClick={() => setCategory(option.value)}
disabled={loading}
>
{option.label}
</button>
))}
</div>
</div>
<div className="form-group">
<label htmlFor="description">Description *</label>
<textarea
id="description"
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Décrivez le produit en détail..."
rows={4}
disabled={loading}
required
/>
</div>
<div className="form-group">
<label htmlFor="stock">Stock (en grammes) *</label>
<input
id="stock"
type="number"
min="0"
step="0.1"
value={stock}
onChange={(e) => setStock(parseFloat(e.target.value) || 0)}
placeholder="100"
disabled={loading}
required
/>
</div>
</div>
{/* Prix */}
<div className="form-section">
<div className="section-header">
<h3>Tarifs</h3>
<button
type="button"
className="add-price-btn"
onClick={addPriceRow}
disabled={loading}
>
<Plus size={18} />
Ajouter un Prix
</button>
</div>
<div className="prices-grid">
{prices.map((price, index) => (
<div key={index} className="price-row">
<div className="price-input-group">
<label>Quantité (g)</label>
<input
type="number"
min="1"
step="1"
value={price.quantity}
onChange={(e) => updatePrice(index, 'quantity', parseInt(e.target.value) || 1)}
disabled={loading}
required
/>
</div>
<div className="price-input-group">
<label>Prix ()</label>
<div className="price-input-wrapper">
<DollarSign size={18} />
<input
type="number"
min="0"
step="0.01"
value={price.price}
onChange={(e) => updatePrice(index, 'price', parseFloat(e.target.value) || 0)}
// ============================================
// 🎨 RENDER
// ============================================
return (
<>
<div className="modal-overlay" onClick={onClose} />
<div className="product-modal edit-modal">
{/* Header */}
<div className="modal-header">
<h2>Modifier le Produit</h2>
<button
className="close-modal"
onClick={onClose}
disabled={loading}
required
/>
</div>
</div>
{prices.length > 1 && (
<button
type="button"
className="remove-price-btn"
onClick={() => removePriceRow(index)}
disabled={loading}
title="Supprimer ce prix"
>
<Trash2 size={18} />
<X size={24} />
</button>
)}
</div>
))}
</div>
</div>
{/* Médias existants */}
{existingMedia.length > 0 && (
<div className="form-section">
<h3>Médias Actuels</h3>
<div className="existing-media-grid">
{existingMedia.map((media) => (
<div key={media.id} className="existing-media-item">
{media.type === 'image' ? (
<img
src={`http://localhost:8080${media.url}`}
alt="Media"
className="media-thumbnail"
/>
) : (
<div className="video-thumbnail">
<ImageIcon size={32} />
<span>Vidéo</span>
</div>
{/* Content */}
<form onSubmit={handleSubmit} className="modal-content">
{error && (
<div className="error-message">
<p>{error}</p>
</div>
)}
<button
type="button"
className="delete-media-btn"
onClick={() => markMediaForDeletion(media.id!)}
disabled={loading}
title="Supprimer ce média"
>
<Trash2 size={16} />
</button>
</div>
))}
</div>
</div>
)}
{/* Nouveaux médias */}
<div className="form-section">
<h3>Ajouter de Nouveaux Médias</h3>
{/* Informations de base */}
<div className="form-section">
<h3>Informations de Base</h3>
<div className="upload-zone">
<label htmlFor="media-upload" className="upload-label">
<Upload size={32} />
<p>Cliquez pour ajouter des fichiers</p>
<span>Images (JPG, PNG, WebP) ou Vidéos (MP4, WebM)</span>
</label>
<input
id="media-upload"
type="file"
accept="image/*,video/*"
multiple
onChange={handleFileSelect}
disabled={loading}
style={{ display: 'none' }}
/>
</div>
<div className="form-group">
<label htmlFor="name">Nom du Produit *</label>
<input
id="name"
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Ex: OG Kush Premium"
disabled={loading}
required
/>
</div>
{newMediaFiles.length > 0 && (
<div className="files-list">
{newMediaFiles.map((file, index) => (
<div key={index} className="file-item">
<div className="file-info">
<span className="file-name">{file.name}</span>
<span className="file-size">
{(file.size / 1024).toFixed(1)} KB
</span>
{/* ✅ CATÉGORIE AVEC BOUTONS AU LIEU DE SELECT */}
<div className="form-group">
<label>Catégorie *</label>
<div className="filter-buttons">
{categoryOptions.map((option) => (
<button
key={option.value}
type="button"
className={
category === option.value
? "active"
: ""
}
onClick={() =>
setCategory(option.value)
}
disabled={loading}
>
{option.label}
</button>
))}
</div>
</div>
<div className="form-group">
<label htmlFor="description">Description *</label>
<textarea
id="description"
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Décrivez le produit en détail..."
rows={4}
disabled={loading}
required
/>
</div>
<div className="form-group">
<label htmlFor="stock">Stock (en grammes) *</label>
<input
id="stock"
type="number"
min="0"
step="0.1"
value={stock}
onChange={(e) =>
setStock(parseFloat(e.target.value) || 0)
}
placeholder="100"
disabled={loading}
required
/>
</div>
</div>
<button
type="button"
className="remove-file-btn"
onClick={() => removeNewFile(index)}
disabled={loading}
>
<Trash2 size={16} />
</button>
</div>
))}
</div>
)}
</div>
</form>
{/* Footer */}
<div className="modal-actions">
<button
type="button"
className="action-button secondary"
onClick={onClose}
disabled={loading}
>
Annuler
</button>
<button
type="submit"
className="action-button primary"
onClick={handleSubmit}
disabled={loading}
>
{loading ? 'Mise à jour...' : 'Mettre à Jour'}
</button>
</div>
</div>
</>
);
{/* Prix */}
<div className="form-section">
<div className="section-header">
<h3>Tarifs</h3>
<button
type="button"
className="add-price-btn"
onClick={addPriceRow}
disabled={loading}
>
<Plus size={18} />
Ajouter un Prix
</button>
</div>
<div className="prices-grid">
{prices.map((price, index) => (
<div key={index} className="price-row">
<div className="price-input-group">
<label>Quantité (g)</label>
<input
type="number"
min="1"
step="1"
value={price.quantity}
onChange={(e) =>
updatePrice(
index,
"quantity",
parseInt(e.target.value) ||
1,
)
}
disabled={loading}
required
/>
</div>
<div className="price-input-group">
<label>Prix ()</label>
<div className="price-input-wrapper">
<DollarSign size={18} />
<input
type="number"
min="0"
step="0.01"
value={price.price}
onChange={(e) =>
updatePrice(
index,
"price",
parseFloat(
e.target.value,
) || 0,
)
}
disabled={loading}
required
/>
</div>
</div>
{prices.length > 1 && (
<button
type="button"
className="remove-price-btn"
onClick={() =>
removePriceRow(index)
}
disabled={loading}
title="Supprimer ce prix"
>
<Trash2 size={18} />
</button>
)}
</div>
))}
</div>
</div>
{/* Médias existants */}
{existingMedia.length > 0 && (
<div className="form-section">
<h3>Médias Actuels</h3>
<div className="existing-media-grid">
{existingMedia.map((media) => (
<div
key={media.id}
className="existing-media-item"
>
{media.type === "image" ? (
<img
src={`${media.url}`}
alt="Media"
className="media-thumbnail"
/>
) : (
<div className="video-thumbnail">
<ImageIcon size={32} />
<span>Vidéo</span>
</div>
)}
<button
type="button"
className="delete-media-btn"
onClick={() =>
markMediaForDeletion(media.id!)
}
disabled={loading}
title="Supprimer ce média"
>
<Trash2 size={16} />
</button>
</div>
))}
</div>
</div>
)}
{/* Nouveaux médias */}
<div className="form-section">
<h3>Ajouter de Nouveaux Médias</h3>
<div className="upload-zone">
<label
htmlFor="media-upload"
className="upload-label"
>
<Upload size={32} />
<p>Cliquez pour ajouter des fichiers</p>
<span>
Images (JPG, PNG, WebP) ou Vidéos (MP4,
WebM)
</span>
</label>
<input
id="media-upload"
type="file"
accept="image/*,video/*"
multiple
onChange={handleFileSelect}
disabled={loading}
style={{ display: "none" }}
/>
</div>
{newMediaFiles.length > 0 && (
<div className="files-list">
{newMediaFiles.map((file, index) => (
<div key={index} className="file-item">
<div className="file-info">
<span className="file-name">
{file.name}
</span>
<span className="file-size">
{(file.size / 1024).toFixed(1)}{" "}
KB
</span>
</div>
<button
type="button"
className="remove-file-btn"
onClick={() => removeNewFile(index)}
disabled={loading}
>
<Trash2 size={16} />
</button>
</div>
))}
</div>
)}
</div>
</form>
{/* Footer */}
<div className="modal-actions">
<button
type="button"
className="action-button secondary"
onClick={onClose}
disabled={loading}
>
Annuler
</button>
<button
type="submit"
className="action-button primary"
onClick={handleSubmit}
disabled={loading}
>
{loading ? "Mise à jour..." : "Mettre à Jour"}
</button>
</div>
</div>
</>
);
};
export default ProductEditModal;
export default ProductEditModal;
@@ -514,7 +514,7 @@ const AdminProduct: React.FC = () => {
product.media.length > 0 ? (
<div className="product-image">
<img
src={`http://localhost:8080${product.media[0].url}`}
src={`${product.media[0].url}`}
alt={
product.name
}
+2 -4
View File
@@ -85,9 +85,7 @@ function UserAccueil() {
(mediaItem) => mediaItem && mediaItem.type === "video",
);
return videoMedia?.url
? `http://localhost:8080${videoMedia.url}`
: undefined;
return videoMedia?.url ? `${videoMedia.url}` : undefined;
};
const getProductImage = (product: Product): string => {
// Pas de media ? Image placeholder
@@ -101,7 +99,7 @@ function UserAccueil() {
// Vérifier si c'est un objet avec type "image" et url
if (mediaItem && mediaItem.type === "image" && mediaItem.url) {
return `http://localhost:8080${mediaItem.url}`;
return `${mediaItem.url}`;
}
}
+2 -4
View File
@@ -111,7 +111,7 @@ function Cart() {
for (let i = 0; i < product.media.length; i++) {
const mediaItem = product.media[i];
if (mediaItem && mediaItem.type === "image" && mediaItem.url) {
return `http://localhost:8080${mediaItem.url}`;
return `${mediaItem.url}`;
}
}
@@ -136,9 +136,7 @@ function Cart() {
(mediaItem) => mediaItem && mediaItem.type === "video",
);
return videoMedia?.url
? `http://localhost:8080${videoMedia.url}`
: undefined;
return videoMedia?.url ? `${videoMedia.url}` : undefined;
};
// ============================================
@@ -117,7 +117,7 @@ function OrderDetails() {
for (let i = 0; i < product.media.length; i++) {
const mediaItem = product.media[i];
if (mediaItem && mediaItem.type === "image" && mediaItem.url) {
return `http://localhost:8080${mediaItem.url}`;
return `${mediaItem.url}`;
}
}
@@ -142,9 +142,7 @@ function OrderDetails() {
(mediaItem) => mediaItem && mediaItem.type === "video",
);
return videoMedia?.url
? `http://localhost:8080${videoMedia.url}`
: undefined;
return videoMedia?.url ? `${videoMedia.url}` : undefined;
};
// HANDLERS VIDÉO