mirror of
https://github.com/Funkoala14/CreatorCenter_OOIN.git
synced 2025-06-07 12:28:15 +08:00
[dev]brands search
This commit is contained in:
parent
1a51aff75b
commit
3492e16c40
@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';
|
||||
import { Button, Form, Modal } from 'react-bootstrap';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { fetchCampaigns } from '../store/slices/brandsSlice';
|
||||
import SpinningComponent from './Spinning';
|
||||
import SpinningComponent from './SpinningComponent';
|
||||
import { addCreatorsToCampaign } from '../store/slices/creatorsSlice';
|
||||
|
||||
export default function AddToCampaign({ show, onHide }) {
|
||||
|
@ -3,15 +3,26 @@ import { useSelector, useDispatch } from 'react-redux';
|
||||
import { fetchBrands } from '../store/slices/brandsSlice';
|
||||
import { Card } from 'react-bootstrap';
|
||||
import { Folders, Hash, Link, Users } from 'lucide-react';
|
||||
import SpinningComponent from './SpinningComponent';
|
||||
|
||||
export default function BrandsList({ openBrandDetail }) {
|
||||
const brands = useSelector((state) => state.brands.brands);
|
||||
const { brands, status, error } = useSelector((state) => state.brands);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchBrands());
|
||||
}, [dispatch]);
|
||||
|
||||
if (status === 'loading') {
|
||||
return <SpinningComponent />;
|
||||
}
|
||||
|
||||
// 如果加载失败,显示错误信息
|
||||
if (status === 'failed') {
|
||||
return <div className='alert alert-danger'>{error || 'Failed to load brands. Please try again later.'}</div>;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className='brands-list'>
|
||||
{brands?.length > 0 && brands.map((brand) => (
|
||||
|
@ -3,7 +3,7 @@ import { useEffect } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
import { ChartNoAxesColumnIncreasing, CircleDollarSign, Edit, Eye, Folders, Hash, Layers, Tag, TrendingUp, UserRoundCheck } from 'lucide-react';
|
||||
import Spinning from './Spinning';
|
||||
import Spinning from './SpinningComponent';
|
||||
|
||||
export default function CampaignList() {
|
||||
const { selectedBrand ,status } = useSelector((state) => state.brands);
|
||||
|
@ -3,9 +3,9 @@ import { Table, Form, Button, Modal } from 'react-bootstrap';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import '../styles/Products.scss';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import Spinning from './Spinning';
|
||||
import Spinning from './SpinningComponent';
|
||||
import { Plus } from 'lucide-react';
|
||||
import SpinningComponent from './Spinning';
|
||||
import SpinningComponent from './SpinningComponent';
|
||||
import { addProductToCampaign } from '../store/slices/productSlice';
|
||||
|
||||
export default function ProductsList({ products, onShowProductDetail, type = 'default' }) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Copy, Edit, FileText, LayoutTemplate } from 'lucide-react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import { useSelector } from 'react-redux';
|
||||
import Spinning from './Spinning';
|
||||
import Spinning from './SpinningComponent';
|
||||
|
||||
export default function TemplateList({ activeTab, openModal, setFormData }) {
|
||||
const { templates, templatesStatus } = useSelector((state) => state.inbox);
|
||||
|
@ -6,27 +6,32 @@ import '../styles/Brands.scss';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Plus } from 'lucide-react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { createBrandThunk, fetchBrands, selectBrand } from '../store/slices/brandsSlice';
|
||||
import SpinningComponent from '../components/Spinning';
|
||||
import { createBrandThunk, fetchBrands, searchBrands, selectBrand } from '../store/slices/brandsSlice';
|
||||
import SpinningComponent from '../components/SpinningComponent';
|
||||
import { BRAND_SOURCES } from '../lib/constant';
|
||||
|
||||
export default function Brands() {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const [showAddBrandModal, setShowAddBrandModal] = useState(false);
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
|
||||
useEffect(() => {}, [dispatch]);
|
||||
|
||||
const openBrandDetail = async (item) => {
|
||||
console.log(item);
|
||||
await dispatch(selectBrand(item));
|
||||
navigate(`/brands/${item.id}`);
|
||||
};
|
||||
|
||||
const handleSearch = (e) => {
|
||||
e.preventDefault();
|
||||
dispatch(searchBrands({ keyword: searchValue }));
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className='function-bar'>
|
||||
<SearchBar />
|
||||
<SearchBar onSearch={handleSearch} value={searchValue} onChange={(e) => setSearchValue(e.target.value)} />
|
||||
<Button onClick={() => setShowAddBrandModal(true)}>
|
||||
<Plus />
|
||||
Add Brand
|
||||
@ -76,7 +81,7 @@ function AddBrandModal({ show, onHide }) {
|
||||
setCampaignId('');
|
||||
};
|
||||
|
||||
if (status === 'loading') {
|
||||
if (show && status === 'loading') {
|
||||
return <SpinningComponent />;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ import SlidePanel from '../components/SlidePanel';
|
||||
import ProductDetail, { CampaignsCollabCreators } from '../components/ProductDetail';
|
||||
import { CAMPAIGN_SERVICES, CREATOR_CATEGORIES, CREATOR_LEVELS, CREATOR_TYPES, GMV_RANGES } from '../lib/constant';
|
||||
import RangeSlider from '../components/RangeSlider';
|
||||
import SpinningComponent from '../components/Spinning';
|
||||
import { setNotificationBarMessage } from '../store/slices/notificationBarSlice';
|
||||
|
||||
export default function BrandsDetail() {
|
||||
|
@ -120,6 +120,18 @@ export const fetchBrands = createAsyncThunk('brands/fetchBrands', async (_, { re
|
||||
}
|
||||
});
|
||||
|
||||
export const searchBrands = createAsyncThunk('brands/searchBrands', async (params, { rejectWithValue }) => {
|
||||
try {
|
||||
const response = await api.get('/brands/search/', { params });
|
||||
if (response.code !== 200) {
|
||||
throw new Error(response.message);
|
||||
}
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
return rejectWithValue(error.message);
|
||||
}
|
||||
});
|
||||
|
||||
export const fetchBrandDetail = createAsyncThunk('brands/fetchBrandDetail', async (brandId, { rejectWithValue }) => {
|
||||
try {
|
||||
const response = await api.get(`/brands/${brandId}/`);
|
||||
@ -324,6 +336,17 @@ const brandsSlice = createSlice({
|
||||
.addCase(createCampaignThunk.rejected, (state, action) => {
|
||||
state.status = 'failed';
|
||||
state.error = action.error.message;
|
||||
})
|
||||
.addCase(searchBrands.pending, (state) => {
|
||||
state.status = 'loading';
|
||||
})
|
||||
.addCase(searchBrands.fulfilled, (state, action) => {
|
||||
state.status = 'succeeded';
|
||||
state.brands = action.payload;
|
||||
})
|
||||
.addCase(searchBrands.rejected, (state, action) => {
|
||||
state.status = 'failed';
|
||||
state.error = action.error.message;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user