mirror of
https://github.com/Funkoala14/CreatorCenter_OOIN.git
synced 2025-06-08 01:18:14 +08:00
Compare commits
2 Commits
40afeb4e5d
...
099d11ed9f
Author | SHA1 | Date | |
---|---|---|---|
099d11ed9f | |||
8ee06cceaa |
@ -22,7 +22,7 @@ export default function TemplateList({ activeTab, openModal, setFormData }) {
|
|||||||
mission: template.type,
|
mission: template.type,
|
||||||
platform: template.platform,
|
platform: template.platform,
|
||||||
service: template.service,
|
service: template.service,
|
||||||
content: template.content,
|
content: template.preview,
|
||||||
title: template.title,
|
title: template.title,
|
||||||
category: template.category,
|
category: template.category,
|
||||||
collaboration_type: template.collaboration_type,
|
collaboration_type: template.collaboration_type,
|
||||||
@ -49,7 +49,7 @@ export default function TemplateList({ activeTab, openModal, setFormData }) {
|
|||||||
{template.mission === 'follow_up' && (
|
{template.mission === 'follow_up' && (
|
||||||
<span className='template-item-name-text-cooperation'>合作追踪</span>
|
<span className='template-item-name-text-cooperation'>合作追踪</span>
|
||||||
)}{' '}
|
)}{' '}
|
||||||
- {template.name}
|
- {template.title}
|
||||||
</span>
|
</span>
|
||||||
<div className='template-item-name-actions'>
|
<div className='template-item-name-actions'>
|
||||||
<Button variant='outline-primary' className='border-0' size='sm' onClick={() => handleEdit(template)}>
|
<Button variant='outline-primary' className='border-0' size='sm' onClick={() => handleEdit(template)}>
|
||||||
@ -77,7 +77,7 @@ export default function TemplateList({ activeTab, openModal, setFormData }) {
|
|||||||
<FileText size={20} />
|
<FileText size={20} />
|
||||||
Message
|
Message
|
||||||
</div>
|
</div>
|
||||||
<div className='value'>{template.content}</div>
|
<div className='value'>{template.preview}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
@ -151,3 +151,13 @@ export const TEMPLATE_MISSIONS = [
|
|||||||
{ value: 'script', name: '脚本邮件' },
|
{ value: 'script', name: '脚本邮件' },
|
||||||
{ value: 'follow_up', name: '合作追踪' },
|
{ value: 'follow_up', name: '合作追踪' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const STATUS_OPTIONS = [
|
||||||
|
{ value: 'brand_review', name: '品牌回顾' },
|
||||||
|
{ value: 'price_negotiation', name: '价格谈判' },
|
||||||
|
{ value: 'contract_review', name: '合同确认' },
|
||||||
|
{ value: 'draft_ready', name: '准备合同' },
|
||||||
|
{ value: 'draft_approved', name: '合同提交' },
|
||||||
|
{ value: 'accepted', name: '已接受' },
|
||||||
|
{ value: 'abandoned', name: '已放弃' },
|
||||||
|
];
|
||||||
|
@ -23,7 +23,11 @@ export default function InboxTemplate() {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(fetchTemplates(activeTab));
|
if (activeTab === 'all') {
|
||||||
|
dispatch(fetchTemplates());
|
||||||
|
} else {
|
||||||
|
dispatch(fetchTemplates({ mission: activeTab }));
|
||||||
|
}
|
||||||
}, [dispatch, activeTab]);
|
}, [dispatch, activeTab]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -46,14 +50,14 @@ export default function InboxTemplate() {
|
|||||||
全部
|
全部
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`tab-switch-item ${activeTab === 'initial' ? 'active' : ''}`}
|
className={`tab-switch-item ${activeTab === 'initial_contact' ? 'active' : ''}`}
|
||||||
onClick={() => setActiveTab('initial')}
|
onClick={() => setActiveTab('initial_contact')}
|
||||||
>
|
>
|
||||||
初步建联
|
初步建联
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`tab-switch-item ${activeTab === 'bargain' ? 'active' : ''}`}
|
className={`tab-switch-item ${activeTab === 'negotiation' ? 'active' : ''}`}
|
||||||
onClick={() => setActiveTab('bargain')}
|
onClick={() => setActiveTab('negotiation')}
|
||||||
>
|
>
|
||||||
砍价邮件
|
砍价邮件
|
||||||
</div>
|
</div>
|
||||||
@ -64,8 +68,8 @@ export default function InboxTemplate() {
|
|||||||
脚本邮件
|
脚本邮件
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`tab-switch-item ${activeTab === 'cooperation' ? 'active' : ''}`}
|
className={`tab-switch-item ${activeTab === 'follow_up' ? 'active' : ''}`}
|
||||||
onClick={() => setActiveTab('cooperation')}
|
onClick={() => setActiveTab('follow_up')}
|
||||||
>
|
>
|
||||||
合作追踪
|
合作追踪
|
||||||
</div>
|
</div>
|
||||||
@ -104,7 +108,6 @@ function AddTemplateModal({ show, formData, setFormData, handleClose, type = 'ad
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
console.log(formData);
|
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
dispatch(addTemplateThunk(formData));
|
dispatch(addTemplateThunk(formData));
|
||||||
} else {
|
} else {
|
||||||
@ -146,11 +149,11 @@ function AddTemplateModal({ show, formData, setFormData, handleClose, type = 'ad
|
|||||||
<option value='' disabled>
|
<option value='' disabled>
|
||||||
Select mission
|
Select mission
|
||||||
</option>
|
</option>
|
||||||
{
|
{TEMPLATE_MISSIONS.map((mission) => (
|
||||||
TEMPLATE_MISSIONS.map((mission) => (
|
<option key={mission.value} value={mission.value}>
|
||||||
<option value={mission.value}>{mission.name}</option>
|
{mission.name}
|
||||||
))
|
</option>
|
||||||
}
|
))}
|
||||||
</Form.Select>
|
</Form.Select>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Form.Group className='col' controlId='formBasicEmail'>
|
<Form.Group className='col' controlId='formBasicEmail'>
|
||||||
@ -185,7 +188,9 @@ function AddTemplateModal({ show, formData, setFormData, handleClose, type = 'ad
|
|||||||
Select service
|
Select service
|
||||||
</option>
|
</option>
|
||||||
{CAMPAIGN_SERVICES.map((service) => (
|
{CAMPAIGN_SERVICES.map((service) => (
|
||||||
<option value={service.value}>{service.name}</option>
|
<option key={service.value} value={service.value}>
|
||||||
|
{service.name}
|
||||||
|
</option>
|
||||||
))}
|
))}
|
||||||
</Form.Select>
|
</Form.Select>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
|
@ -9,6 +9,7 @@ import authReducer from './slices/authSlice';
|
|||||||
import discoveryReducer from './slices/discoverySlice';
|
import discoveryReducer from './slices/discoverySlice';
|
||||||
import notificationBarReducer from './slices/notificationBarSlice';
|
import notificationBarReducer from './slices/notificationBarSlice';
|
||||||
import productReducer from './slices/productSlice';
|
import productReducer from './slices/productSlice';
|
||||||
|
import chatReducer from './slices/chatSlice';
|
||||||
|
|
||||||
const authPersistConfig = {
|
const authPersistConfig = {
|
||||||
key: 'auth',
|
key: 'auth',
|
||||||
@ -24,6 +25,7 @@ const rootReducer = combineReducers({
|
|||||||
auth: persistReducer(authPersistConfig, authReducer),
|
auth: persistReducer(authPersistConfig, authReducer),
|
||||||
notificationBar: notificationBarReducer,
|
notificationBar: notificationBarReducer,
|
||||||
products: productReducer,
|
products: productReducer,
|
||||||
|
chat: chatReducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
const store = configureStore({
|
const store = configureStore({
|
||||||
|
@ -1,19 +1,56 @@
|
|||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
|
||||||
|
import api from '@/services/api';
|
||||||
|
import { setNotificationBarMessage } from './notificationBarSlice';
|
||||||
|
|
||||||
export const fetchChats = createAsyncThunk('chat/fetchChats', async (_, { rejectWithValue }) => {
|
export const fetchChatDetails = createAsyncThunk(
|
||||||
try {
|
'chat/fetchChatDetails',
|
||||||
const response = await api.get(`/chat-history/search/`);
|
async (query, { rejectWithValue, dispatch }) => {
|
||||||
if (response.code === 200) {
|
try {
|
||||||
return response.data;
|
const response = await api.get('/chat-history/conversation_detail/', { params: query });
|
||||||
|
if (response.code === 200) {
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
throw new Error(response.message);
|
||||||
|
} catch (error) {
|
||||||
|
dispatch(setNotificationBarMessage({ message: error.message, type: 'error' }));
|
||||||
|
return rejectWithValue(error.message);
|
||||||
}
|
}
|
||||||
throw new Error(response.message);
|
|
||||||
} catch (error) {
|
|
||||||
return rejectWithValue(error.message);
|
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
|
||||||
|
export const sendEMailToCreator = createAsyncThunk(
|
||||||
|
'chat/sendEMailToCreator',
|
||||||
|
async (query, { rejectWithValue, dispatch }) => {
|
||||||
|
try {
|
||||||
|
const response = await api.post('/chat-history/send_email_to_creator/', query);
|
||||||
|
if (response.code === 200) {
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
throw new Error(response.message);
|
||||||
|
} catch (error) {
|
||||||
|
dispatch(setNotificationBarMessage({ message: error.message, type: 'error' }));
|
||||||
|
return rejectWithValue(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const createConversation = createAsyncThunk(
|
||||||
|
'chat/createConversation',
|
||||||
|
async (id, { rejectWithValue, dispatch }) => {
|
||||||
|
try {
|
||||||
|
const response = await api.post('/chat-history/create_conversation/', { negotiation_id: id });
|
||||||
|
if (response.code === 200) {
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
throw new Error(response.message);
|
||||||
|
} catch (error) {
|
||||||
|
dispatch(setNotificationBarMessage({ message: error.message, type: 'error' }));
|
||||||
|
return rejectWithValue(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
chats: [],
|
|
||||||
currentChat: null,
|
currentChat: null,
|
||||||
status: 'idle',
|
status: 'idle',
|
||||||
error: null,
|
error: null,
|
||||||
@ -24,14 +61,14 @@ const chatSlice = createSlice({
|
|||||||
initialState,
|
initialState,
|
||||||
reducers: {},
|
reducers: {},
|
||||||
extraReducers: (builder) => {
|
extraReducers: (builder) => {
|
||||||
builder.addCase(fetchChats.pending, (state) => {
|
builder.addCase(fetchChatDetails.pending, (state) => {
|
||||||
state.status = 'loading';
|
state.status = 'loading';
|
||||||
})
|
});
|
||||||
builder.addCase(fetchChats.fulfilled, (state, action) => {
|
builder.addCase(fetchChatDetails.fulfilled, (state, action) => {
|
||||||
state.status = 'succeeded';
|
state.status = 'succeeded';
|
||||||
state.chats = action.payload;
|
state.currentChat = action.payload;
|
||||||
})
|
});
|
||||||
builder.addCase(fetchChats.rejected, (state, action) => {
|
builder.addCase(fetchChatDetails.rejected, (state, action) => {
|
||||||
state.status = 'failed';
|
state.status = 'failed';
|
||||||
state.error = action.payload;
|
state.error = action.payload;
|
||||||
});
|
});
|
||||||
|
@ -513,16 +513,20 @@ const creatorsSlice = createSlice({
|
|||||||
state.error = action.error.message;
|
state.error = action.error.message;
|
||||||
})
|
})
|
||||||
.addCase(fetchCreatorMetrics.fulfilled, (state, action) => {
|
.addCase(fetchCreatorMetrics.fulfilled, (state, action) => {
|
||||||
state.selectedCreator.metricsData = action.payload;
|
console.log(action.payload);
|
||||||
|
state.selectedCreator.metricsData = action.payload || null;
|
||||||
})
|
})
|
||||||
.addCase(fetchCreatorFollowers.fulfilled, (state, action) => {
|
.addCase(fetchCreatorFollowers.fulfilled, (state, action) => {
|
||||||
state.selectedCreator.followerData = action.payload;
|
console.log(action.payload);
|
||||||
|
state.selectedCreator.followerData = action.payload || null;
|
||||||
})
|
})
|
||||||
.addCase(fetchCreatorTrends.fulfilled, (state, action) => {
|
.addCase(fetchCreatorTrends.fulfilled, (state, action) => {
|
||||||
state.selectedCreator.trendsData = action.payload;
|
console.log(action.payload);
|
||||||
|
state.selectedCreator.trendsData = action.payload || null;
|
||||||
})
|
})
|
||||||
.addCase(fetchCreatorVideos.fulfilled, (state, action) => {
|
.addCase(fetchCreatorVideos.fulfilled, (state, action) => {
|
||||||
state.selectedCreator.videosData = action.payload;
|
console.log(action.payload);
|
||||||
|
state.selectedCreator.videosData = action.payload || null;
|
||||||
})
|
})
|
||||||
.addCase(searchCreators.pending, (state) => {
|
.addCase(searchCreators.pending, (state) => {
|
||||||
state.status = 'loading';
|
state.status = 'loading';
|
||||||
|
@ -191,9 +191,9 @@ export const fetchChatHistory = createAsyncThunk('inbox/fetchChatHistory', async
|
|||||||
return { chatHistory: mockChatHistory, chatId: id };
|
return { chatHistory: mockChatHistory, chatId: id };
|
||||||
});
|
});
|
||||||
|
|
||||||
export const fetchTemplates = createAsyncThunk('inbox/fetchTemplates', async (_, { rejectWithValue }) => {
|
export const fetchTemplates = createAsyncThunk('inbox/fetchTemplates', async (query, { rejectWithValue }) => {
|
||||||
try {
|
try {
|
||||||
const response = await api.get('/template/');
|
const response = await api.get('/template/', { params: query });
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
return response.data.results;
|
return response.data.results;
|
||||||
} else {
|
} else {
|
||||||
@ -226,7 +226,7 @@ export const addTemplateThunk = createAsyncThunk(
|
|||||||
async (formData, { rejectWithValue, dispatch }) => {
|
async (formData, { rejectWithValue, dispatch }) => {
|
||||||
try {
|
try {
|
||||||
const response = await api.post('/template/', formData);
|
const response = await api.post('/template/', formData);
|
||||||
if (response.code === 200) {
|
if (response.code === 200 || response.code === 201) {
|
||||||
return response.data;
|
return response.data;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(response.message);
|
throw new Error(response.message);
|
||||||
|
@ -414,7 +414,6 @@
|
|||||||
|
|
||||||
#addProductForm {
|
#addProductForm {
|
||||||
.modal-body {
|
.modal-body {
|
||||||
width: 400px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.creator-database-table {
|
.creator-database-table {
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.creator-cell {
|
.creator-cell {
|
||||||
|
@ -366,7 +366,7 @@
|
|||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
height: calc(100% - 85px);
|
max-height: calc(100% - 85px);
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
|
|
||||||
.template-item {
|
.template-item {
|
||||||
|
Loading…
Reference in New Issue
Block a user