[dev]templates

This commit is contained in:
susie-laptop 2025-05-21 18:13:14 -04:00
parent bcbc8fafab
commit 8a6c6c27b4
3 changed files with 199 additions and 7 deletions

View File

@ -3,7 +3,7 @@ import { Button } from 'react-bootstrap';
import { useSelector } from 'react-redux';
import Spinning from './Spinning';
export default function TemplateList({ activeTab }) {
export default function TemplateList({ activeTab, openModal, setFormData }) {
const { templates, templatesStatus } = useSelector((state) => state.inbox);
//
if (templatesStatus === 'loading') {
@ -16,6 +16,17 @@ export default function TemplateList({ activeTab }) {
</div>
);
}
const handleEdit = (template) => {
setFormData({
id: template.id,
mission: template.type,
platform: template.platform,
service: template.service,
template: template.message,
});
openModal();
}
return (
<div className='template-list'>
{templates.map((template) => (
@ -37,7 +48,7 @@ export default function TemplateList({ activeTab }) {
- {template.name}
</span>
<div className='template-item-name-actions'>
<Button variant='outline-primary' className='border-0' size='sm'>
<Button variant='outline-primary' className='border-0' size='sm' onClick={() => handleEdit(template)}>
<Edit size={16} />
Edit
</Button>

View File

@ -1,13 +1,21 @@
import { Button } from 'react-bootstrap';
import { Button, Form, Modal } from 'react-bootstrap';
import SearchBar from '../components/SearchBar';
import { Plus } from 'lucide-react';
import { Footprints, Plus } from 'lucide-react';
import React, { useEffect, useState } from 'react';
import { useDispatch } from 'react-redux';
import { fetchTemplates } from '../store/slices/inboxSlice';
import { addTemplateApi, editTemplateApi, fetchTemplates } from '../store/slices/inboxSlice';
import TemplateList from '../components/TemplateList';
export default function InboxTemplate() {
const [activeTab, setActiveTab] = useState('all');
const [showAddTemplateModal, setShowAddTemplateModal] = useState(false);
const [showEditTemplateModal, setShowEditTemplateModal] = useState(false);
const [formData, setFormData] = useState({
mission: '',
platform: '',
service: '',
template: '',
});
const dispatch = useDispatch();
useEffect(() => {
@ -18,7 +26,7 @@ export default function InboxTemplate() {
<React.Fragment>
<div className='function-bar'>
<SearchBar />
<Button onClick={() => setShowAddBrandModal(true)}>
<Button onClick={() => setShowAddTemplateModal(true)}>
<Plus />
Add Template
</Button>
@ -58,7 +66,138 @@ export default function InboxTemplate() {
合作追踪
</div>
</div>
<TemplateList activeTab={activeTab} />
<TemplateList
activeTab={activeTab}
openModal={() => setShowEditTemplateModal(true)}
setFormData={setFormData}
/>
<AddTemplateModal
show={showAddTemplateModal}
handleClose={() => setShowAddTemplateModal(false)}
type='add'
formData={formData}
setFormData={setFormData}
/>
<AddTemplateModal
show={showEditTemplateModal}
handleClose={() => setShowEditTemplateModal(false)}
type='edit'
formData={formData}
setFormData={setFormData}
/>
</React.Fragment>
);
}
function AddTemplateModal({ show, formData, setFormData, handleClose, type = 'add' }) {
const dispatch = useDispatch();
const handleChange = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value,
});
};
const handleSubmit = () => {
console.log(formData);
if(type === 'add') {
dispatch(addTemplateApi(formData));
} else {
dispatch(editTemplateApi(formData));
}
};
useEffect(() => {
}, [formData]);
return (
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>{type === 'add' ? 'Add Template' : 'Edit Template'}</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group className='mb-3' controlId='formBasicEmail'>
<Form.Label>Mission</Form.Label>
<Form.Select
required
type='select'
placeholder='Select mission'
value={formData.mission}
name='mission'
onChange={handleChange}
>
<option value='' disabled>
Select mission
</option>
<option value='initial'>初步建联</option>
<option value='bargain'>砍价邮件</option>
<option value='script'>脚本邮件</option>
<option value='cooperation'>合作追踪</option>
</Form.Select>
</Form.Group>
<Form.Group className='mb-3' controlId='formBasicEmail'>
<Form.Label>Platform</Form.Label>
<Form.Select
required
type='select'
placeholder='Select platform'
value={formData.platform}
name='platform'
onChange={handleChange}
>
<option value='' disabled>
Select platform
</option>
<option value='TikTok'>TikTok</option>
<option value='Instagram'>Instagram</option>
<option value='Facebook'>Facebook</option>
<option value='YouTube'>Youtube</option>
</Form.Select>
</Form.Group>
<Form.Group className='mb-3' controlId='formBasicEmail'>
<Form.Label>合作模式</Form.Label>
<Form.Select
required
type='select'
value={formData.service}
name='service'
onChange={handleChange}
>
<option value='' disabled>
Select service
</option>
<option value='fufei'>达人短视频付费</option>
<option value='chunyong'>达人短视频纯佣</option>
<option value='dai'>直播代播</option>
<option value='dabao'>直播达播</option>
<option value='chun'>纯素材短视频</option>
</Form.Select>
</Form.Group>
<Form.Group className='mb-3' controlId='formBasicEmail'>
<Form.Label>Template</Form.Label>
<Form.Control
required
type='textarea'
as='textarea'
rows={10}
placeholder='Enter template'
value={formData.template}
name='template'
onChange={handleChange}
/>
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button variant='outline-primary' className='border-0' onClick={handleClose}>
Close
</Button>
<Button variant='primary' type='submit' onClick={handleSubmit}>
Create
</Button>
</Modal.Footer>
</Modal>
);
}

View File

@ -191,6 +191,25 @@ export const fetchTemplates = createAsyncThunk('inbox/fetchTemplates', async (ty
return mockTemplates.filter((item) => item.type === type);
});
export const editTemplateApi = createAsyncThunk('inbox/editTemplate', async (formData) => {
await new Promise((resolve) => setTimeout(resolve, 500));
const {id, ...rest} = formData;
const index = mockTemplates.findIndex((item) => item.id === id);
mockTemplates[index] = { ...mockTemplates[index], ...rest };
return mockTemplates;
});
export const addTemplateApi = createAsyncThunk('inbox/addTemplate', async (formData) => {
await new Promise((resolve) => setTimeout(resolve, 500));
const newTemplate = {
id: mockTemplates.length + 1,
message: formData.template,
...formData,
};
const newTemplates = [...mockTemplates, newTemplate];
return newTemplates;
});
const initialState = {
inboxList: [],
inboxStatus: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed'
@ -252,6 +271,29 @@ const inboxSlice = createSlice({
.addCase(fetchTemplates.fulfilled, (state, action) => {
state.templatesStatus = 'succeeded';
state.templates = action.payload;
})
.addCase(editTemplateApi.pending, (state) => {
state.templatesStatus = 'loading';
})
.addCase(editTemplateApi.fulfilled, (state, action) => {
state.templatesStatus = 'succeeded';
state.templates = action.payload;
})
.addCase(editTemplateApi.rejected, (state, action) => {
state.templatesStatus = 'failed';
state.error = action.error.message;
})
.addCase(addTemplateApi.pending, (state) => {
state.templatesStatus = 'loading';
})
.addCase(addTemplateApi.fulfilled, (state, action) => {
console.log(action.payload);
state.templatesStatus = 'succeeded';
state.templates = action.payload;
})
.addCase(addTemplateApi.rejected, (state, action) => {
state.templatesStatus = 'failed';
state.error = action.error.message;
});
},
});