[dev]upload

This commit is contained in:
susie-laptop 2025-05-22 17:00:59 -04:00
parent 46014fb62e
commit 9706970690
2 changed files with 171 additions and 73 deletions

View File

@ -1,8 +1,9 @@
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { Button, Card, Col, Form, Row } from 'react-bootstrap'; import { Accordion, Button, Card, Col, Form, Row, Table } from 'react-bootstrap';
import { CloudUpload, Paperclip } from 'lucide-react'; import { CloudUpload, Paperclip } from 'lucide-react';
import { useDropzone } from 'react-dropzone'; import { useDropzone } from 'react-dropzone';
import { mockCreators } from '../store/slices/creatorsSlice';
export default function CampaignScript() { export default function CampaignScript() {
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -77,81 +78,178 @@ export default function CampaignScript() {
Campaigns & Collaborated Creators Campaigns & Collaborated Creators
</div> </div>
</div> </div>
<Card className='product-script-video-req'> {activeTab === 'collaborationInfo' && <CollabInfo />}
<Form className='video-req-form'> {activeTab === 'campaigns' && <CampaignsCollabCreators />}
<div className='form-header'>Video Posting Requirement</div>
<Form.Group>
<Form.Label>Product Selling Point</Form.Label>
<Form.Control
type='textarea'
as='textarea'
rows={3}
placeholder='吸力强、有效除菌、香薰片功能、价格更优惠、两种颜色'
/>
</Form.Group>
<Form.Group>
<Form.Label>Example Videos</Form.Label>
<Form.Control
type='textarea'
as='textarea'
rows={3}
placeholder='https://mcnmza4kafoj.feishu.cn/drive/folder/HzhWfGvWtlCBqIduwfLczQ9Cnyb'
/>
</Form.Group>
<Form.Group>
<Form.Label>Video Posting Suggestion</Form.Label>
<Form.Control
type='textarea'
as='textarea'
rows={3}
placeholder='开头引人+产品亮点+CTA呼吁/时长30~50s左右'
/>
</Form.Group>
<Form.Group>
<Form.Label>Video Acceptance Standard</Form.Label>
<Form.Control
type='textarea'
as='textarea'
rows={3}
placeholder='1.场景包括不限于厨房卫生间衣柜在橱柜下方和洗手台下方安装橱柜灯衣柜等安全及方便需求场景展示要有黑暗环境对比HOOK
2.红人必须要表达卖点以下卖点按优先级排列达人任意选择提到至少三个卖点即可
电池大续航能力强可以必须提到可用字幕展示
容易安装有磁铁必须提到要拍出安装过程
开启人体感应模式 必须提到可视觉展示
可充电
亮度高且可调节
加分卖点
视频需说明购买理由以及使用感受例如老人家晚上更安全宝妈晚上起床更便捷安全等等购买理由
3.正确的hashtags 以及正确@官方账号'
/>
</Form.Group>
<Form.Group className='upload-group'>
<FileUpload />
</Form.Group>
</Form>
<div className='product-ai-script'>
<div className='header'>
<div className='title'>Script</div>
<Button variant='primary' className='generate-btn'>
AI Generate
</Button>
</div>
<Form className='script-versions'>
<Form.Group>
<Form.Label>Version 1</Form.Label>
<Form.Control type='textarea' as='textarea' rows={4} />
</Form.Group>
<Form.Group>
<Form.Label>Version 2</Form.Label>
<Form.Control type='textarea' as='textarea' rows={4} />
</Form.Group>
</Form>
</div>
</Card>
</div> </div>
) )
); );
} }
const CollabInfo = () => {
const [formData, setFormData] = useState({
productSellingPoint: '吸力强、有效除菌、香薰片功能、价格更优惠、两种颜色',
exampleVideos: 'https://mcnmza4kafoj.feishu.cn/drive/folder/HzhWfGvWtlCBqIduwfLczQ9Cnyb',
videoPostingSuggestion: '开头引人+产品亮点+CTA呼吁/时长30~50s左右',
videoAcceptanceStandard: `1.场景包括不限于厨房、卫生间、衣柜在橱柜下方和洗手台下方安装橱柜灯、衣柜等安全及方便需求。场景展示要有黑暗环境对比HOOK。
2.红人必须要表达卖点以下卖点按优先级排列达人任意选择提到至少三个卖点即可
电池大续航能力强可以必须提到可用字幕展示
容易安装有磁铁必须提到要拍出安装过程
开启人体感应模式 必须提到可视觉展示
可充电
亮度高且可调节
加分卖点
视频需说明购买理由以及使用感受例如老人家晚上更安全宝妈晚上起床更便捷安全等等购买理由
3.正确的hashtags 以及正确@官方账号`,
documentsUpload: [],
});
const handleChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
return (
<Card className='product-script-video-req'>
<Form className='video-req-form'>
<div className='form-header'>Video Posting Requirement</div>
<Form.Group>
<Form.Label>Product Selling Point</Form.Label>
<Form.Control
type='textarea'
as='textarea'
rows={3}
placeholder='Enter the product selling point'
name='productSellingPoint'
value={formData.productSellingPoint}
onChange={handleChange}
/>
</Form.Group>
<Form.Group>
<Form.Label>Example Videos</Form.Label>
<Form.Control
type='textarea'
as='textarea'
rows={3}
placeholder='Enter the example videos'
name='exampleVideos'
value={formData.exampleVideos}
onChange={handleChange}
/>
</Form.Group>
<Form.Group>
<Form.Label>Video Posting Suggestion</Form.Label>
<Form.Control
type='textarea'
as='textarea'
rows={3}
placeholder='Enter the video posting suggestion'
name='videoPostingSuggestion'
value={formData.videoPostingSuggestion}
onChange={handleChange}
/>
</Form.Group>
<Form.Group>
<Form.Label>Video Acceptance Standard</Form.Label>
<Form.Control
type='textarea'
as='textarea'
rows={3}
placeholder='Enter the video acceptance standard'
name='videoAcceptanceStandard'
value={formData.videoAcceptanceStandard}
onChange={handleChange}
/>
</Form.Group>
<Form.Group className='upload-group'>
<FileUpload />
</Form.Group>
</Form>
<div className='product-ai-script'>
<div className='header'>
<div className='title'>Script</div>
<Button variant='primary' className='generate-btn'>
AI Generate
</Button>
</div>
<Form className='script-versions'>
<Form.Group>
<Form.Label>Version 1</Form.Label>
<Form.Control type='textarea' as='textarea' rows={4} />
</Form.Group>
<Form.Group>
<Form.Label>Version 2</Form.Label>
<Form.Control type='textarea' as='textarea' rows={4} />
</Form.Group>
</Form>
</div>
</Card>
);
};
const CampaignsCollabCreators = () => {
const mockData = [
{
id: 1,
name: 'SUNLINK 拍拍灯',
creatorList: mockCreators,
},
{
id: 2,
name: 'SUNLINK 拍拍灯2',
creatorList: mockCreators,
},
];
if (mockData.length === 0) {
return <div className='text-center'>No campaigns found</div>;
}
return (
<Accordion className='campaigns-collab-creators-list' defaultActiveKey={mockData[0].id}>
{mockData.map((item) => (
<Accordion.Item eventKey={item.id} key={item.id} className='campaigns-collab-creators-item'>
<Accordion.Header>{item.name}</Accordion.Header>
<Accordion.Body>
<Table responsive hover className='bg-white shadow-xs rounded overflow-hidden'>
<thead>
<tr>
<th>Creator</th>
<th>Category</th>
<th>Followers</th>
<th>GMV Generated</th>
<th>Views Generated</th>
<th>Pricing</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{item?.creatorList.length > 0 &&
item?.creatorList.map((creator) => (
<tr key={creator.id}>
<td>
<div className='white-space-nowrap'>
<img
className='creator-avatar'
src={creator.avatar}
alt={creator.name}
/>
<span className='creator-name'>{creator.name}</span>
</div>
</td>
<td>{creator.category}</td>
<td>{creator.followers || '--'}</td>
<td>{creator.gmv || '--'}</td>
<td>{creator.views || '--'}</td>
<td>{creator.pricing || '--'}</td>
<td>{creator.status || '--'}</td>
</tr>
))}
</tbody>
</Table>
</Accordion.Body>
</Accordion.Item>
))}
</Accordion>
);
};
const FileUpload = () => { const FileUpload = () => {
const [files, setFiles] = useState([]); const [files, setFiles] = useState([]);

View File

@ -26,7 +26,7 @@ const mockVideos = [
}, },
]; ];
// 模拟创作者数据实际项目中会从API获取 // 模拟创作者数据实际项目中会从API获取
const mockCreators = [ export const mockCreators = [
{ {
id: 1, id: 1,
name: 'name', name: 'name',