mirror of
https://github.com/Funkoala14/CreatorCenter_OOIN.git
synced 2025-06-08 05:28:14 +08:00
[dev]add prod to campaign
from band page
This commit is contained in:
parent
10f3420890
commit
855ea29b92
@ -1,15 +1,20 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Table, Form } from 'react-bootstrap';
|
import { Table, Form, Button, Modal } from 'react-bootstrap';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import '../styles/Products.scss';
|
import '../styles/Products.scss';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import Spinning from './Spinning';
|
import Spinning from './Spinning';
|
||||||
|
import { Plus } from 'lucide-react';
|
||||||
|
import SpinningComponent from './Spinning';
|
||||||
|
import { addProductToCampaign } from '../store/slices/productSlice';
|
||||||
|
|
||||||
export default function ProductsList({ products, setSelectedProduct, onShowProductDetail }) {
|
export default function ProductsList({ products, onShowProductDetail, type = 'default' }) {
|
||||||
const { selectedBrand } = useSelector((state) => state.brands);
|
const { selectedBrand, status } = useSelector((state) => state.brands);
|
||||||
const [sortField, setSortField] = useState(null);
|
const [sortField, setSortField] = useState(null);
|
||||||
const [sortDirection, setSortDirection] = useState('asc');
|
const [sortDirection, setSortDirection] = useState('asc');
|
||||||
const [selectedProducts, setSelectedProducts] = useState([]);
|
const [selectedProducts, setSelectedProducts] = useState([]);
|
||||||
|
const [showAddProductToCampaignModal, setShowAddProductToCampaignModal] = useState(false);
|
||||||
|
const [selectedProduct, setSelectedProduct] = useState(null);
|
||||||
|
|
||||||
const handleSort = (field) => {
|
const handleSort = (field) => {
|
||||||
return;
|
return;
|
||||||
@ -44,10 +49,9 @@ export default function ProductsList({ products, setSelectedProduct, onShowProdu
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (status === 'loading') {
|
if (status === 'loading') {
|
||||||
return <Spinning />;
|
return <SpinningComponent />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='products-list rounded shadow-xs'>
|
<div className='products-list rounded shadow-xs'>
|
||||||
<Table responsive hover className='bg-white rounded overflow-hidden m-0'>
|
<Table responsive hover className='bg-white rounded overflow-hidden m-0'>
|
||||||
@ -87,6 +91,7 @@ export default function ProductsList({ products, setSelectedProduct, onShowProdu
|
|||||||
<th className='tiktokShop text-center' onClick={() => handleSort('tiktokShop')}>
|
<th className='tiktokShop text-center' onClick={() => handleSort('tiktokShop')}>
|
||||||
TikTok Shop {renderSortIcon('tiktokShop')}
|
TikTok Shop {renderSortIcon('tiktokShop')}
|
||||||
</th>
|
</th>
|
||||||
|
{type === 'brand' && <th className='actions text-center'>Add To Campaign</th>}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -107,18 +112,24 @@ export default function ProductsList({ products, setSelectedProduct, onShowProdu
|
|||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td className='product-cell'>
|
<td className='product-cell'>
|
||||||
<div className='d-flex align-items-center' onClick={() => onShowProductDetail(product)} style={{cursor: 'pointer'}}>
|
<div
|
||||||
|
className='d-flex align-items-center'
|
||||||
|
onClick={() => onShowProductDetail(product)}
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
|
>
|
||||||
<img className='product-logo' src={product.image_url} alt={product.name} />
|
<img className='product-logo' src={product.image_url} alt={product.name} />
|
||||||
{/* <div className='product-logo'>{product.name.slice(0, 1)}</div> */}
|
{/* <div className='product-logo'>{product.name.slice(0, 1)}</div> */}
|
||||||
<div className='product-name'>{product.name}</div>
|
<div className='product-name'>{product.name}</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className='text-center' >
|
<td className='text-center'>
|
||||||
<div>{product.commission_rate}</div>
|
<div>{product.commission_rate}</div>
|
||||||
<div className='small text-muted'>Open collab. {product.open_collab}</div>
|
<div className='small text-muted'>Open collab. {product.open_collab}</div>
|
||||||
</td>
|
</td>
|
||||||
<td className='text-center'>{product.available_samples}</td>
|
<td className='text-center'>{product.available_samples}</td>
|
||||||
<td className='text-center'>{product.sales_price_min} - {product.sales_price_max}</td>
|
<td className='text-center'>
|
||||||
|
{product.sales_price_min} - {product.sales_price_max}
|
||||||
|
</td>
|
||||||
<td className='text-center'>{product.stock}</td>
|
<td className='text-center'>{product.stock}</td>
|
||||||
<td className='text-center'>{product.items_sold}</td>
|
<td className='text-center'>{product.items_sold}</td>
|
||||||
<td className='text-center'>
|
<td className='text-center'>
|
||||||
@ -126,12 +137,74 @@ export default function ProductsList({ products, setSelectedProduct, onShowProdu
|
|||||||
<div className='small text-muted'>{product.reviews_count} Reviews</div>
|
<div className='small text-muted'>{product.reviews_count} Reviews</div>
|
||||||
</td>
|
</td>
|
||||||
<td className='text-center'>{product.collab_creators}</td>
|
<td className='text-center'>{product.collab_creators}</td>
|
||||||
<td className='text-center'>{product.tiktok_shop && <FontAwesomeIcon icon='fa-brands fa-tiktok' />}</td>
|
<td className='text-center'>
|
||||||
|
{product.tiktok_shop && <FontAwesomeIcon icon='fa-brands fa-tiktok' />}
|
||||||
|
</td>
|
||||||
|
{type === 'brand' && (
|
||||||
|
<td className='text-center'>
|
||||||
|
<button className='border-0 bg-transparent text-primary' onClick={() => {
|
||||||
|
setSelectedProduct(product.id);
|
||||||
|
setShowAddProductToCampaignModal(true);
|
||||||
|
}}>
|
||||||
|
<Plus />
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
<AddProductToCampaignModal show={showAddProductToCampaignModal} onHide={() => setShowAddProductToCampaignModal(false)} productId={selectedProduct} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AddProductToCampaignModal({ show, onHide, productId }) {
|
||||||
|
const [campaignId, setCampaignId] = useState(null);
|
||||||
|
const { selectedBrand } = useSelector((state) => state.brands);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log(campaignId, productId);
|
||||||
|
await dispatch(addProductToCampaign({ campaignId, productId })).unwrap();
|
||||||
|
handleCancel();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
setCampaignId(null);
|
||||||
|
onHide();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal show={show} onHide={onHide} size='md'>
|
||||||
|
<Modal.Header closeButton className='fw-bold'>
|
||||||
|
Add Product
|
||||||
|
</Modal.Header>
|
||||||
|
<Form onSubmit={handleSubmit}>
|
||||||
|
<Modal.Body>
|
||||||
|
<Form.Group>
|
||||||
|
<Form.Label>Campaign Name</Form.Label>
|
||||||
|
<Form.Select required value={campaignId} onChange={(e) => setCampaignId(e.target.value)}>
|
||||||
|
<option value=''>Select Campaign</option>
|
||||||
|
{selectedBrand?.campaigns?.map((campaign) => (
|
||||||
|
<option key={campaign.id} value={campaign.id}>
|
||||||
|
{campaign.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</Form.Select>
|
||||||
|
</Form.Group>
|
||||||
|
</Modal.Body>
|
||||||
|
<Modal.Footer>
|
||||||
|
<Button variant='outline-primary' className='border-0' onClick={handleCancel}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button variant='primary' type='submit'>
|
||||||
|
Add
|
||||||
|
</Button>
|
||||||
|
</Modal.Footer>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -139,6 +139,7 @@ export default function BrandsDetail() {
|
|||||||
<ProductsList
|
<ProductsList
|
||||||
products={selectedBrand?.products}
|
products={selectedBrand?.products}
|
||||||
onShowProductDetail={handleShowProductDetail}
|
onShowProductDetail={handleShowProductDetail}
|
||||||
|
type='brand'
|
||||||
/>
|
/>
|
||||||
<SlidePanel
|
<SlidePanel
|
||||||
show={showProductDetail}
|
show={showProductDetail}
|
||||||
|
@ -170,7 +170,7 @@ function AddProductModal({ campaignId, show, onHide }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal show={show} onHide={handleCancel}>
|
<Modal show={show} onHide={handleCancel} size='sm'>
|
||||||
<Modal.Header closeButton className='fw-bold'>
|
<Modal.Header closeButton className='fw-bold'>
|
||||||
Add Product
|
Add Product
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
|
@ -21,8 +21,7 @@ export const addProductToCampaign = createAsyncThunk('products/addProductToCampa
|
|||||||
if (response.code !== 201 && response.code !== 200) {
|
if (response.code !== 201 && response.code !== 200) {
|
||||||
throw new Error(response.message);
|
throw new Error(response.message);
|
||||||
}
|
}
|
||||||
console.log(response);
|
dispatch(setNotificationBarMessage({ message: response.message, type: 'success' }));
|
||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(setNotificationBarMessage({ message: error.message, type: 'error' }));
|
dispatch(setNotificationBarMessage({ message: error.message, type: 'error' }));
|
||||||
|
@ -134,8 +134,3 @@ a {
|
|||||||
box-shadow: 0px 0px 1px #171a1f12, 0px 0px 2px #171a1f1f; /* shadow-xs */
|
box-shadow: 0px 0px 1px #171a1f12, 0px 0px 2px #171a1f1f; /* shadow-xs */
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-content {
|
|
||||||
width: max-content;
|
|
||||||
max-width: 60vw;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user