Commit 08c351f4 authored by littleforest's avatar littleforest

feat: add chat of the molibe version

parent 4ce8dd4a
......@@ -23,8 +23,8 @@
"prepare": "husky install",
"prettier": "prettier -c --write \"src/**/*\"",
"serve": "umi-serve",
"start": "cross-env UMI_ENV=dev umi dev",
"start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev umi dev",
"start": "SET NODE_OPTIONS=--openssl-legacy-provider && cross-env UMI_ENV=dev umi dev",
"start:dev": "SET NODE_OPTIONS=--openssl-legacy-provider && cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev umi dev",
"start:no-mock": "cross-env MOCK=none UMI_ENV=dev umi dev",
"start:no-ui": "cross-env UMI_UI=none UMI_ENV=dev umi dev",
"start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev umi dev",
......@@ -100,4 +100,4 @@
"engines": {
"node": ">=12.0.0"
}
}
}
\ No newline at end of file
.content {
width: 100%;
padding: 100px;
background: white;
.cardPadding {
margin: 16px 18px;
}
.CardContent {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.cardPadding {
padding: 8px;
}
.CardContent {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-bottom: 150px;
}
import { Layout } from 'antd';
import { Row, Col } from 'antd';
import type { FC } from 'react';
import { FormattedMessage, useIntl } from 'umi';
import styles from './content.less';
import ProductionCard from './productionCard';
import ChatHeader from './header';
const { Content } = Layout;
interface ChatFirstContentProps {
onChange?: (text: string) => void;
......@@ -75,17 +71,19 @@ const ChatFirstContent: FC<ChatFirstContentProps> = (props) => {
];
return (
<Content className={styles.content}>
<div className={styles.CardContent}>
<div className={styles.CardContent}>
<Row gutter={1}>
{cardList.map((item, index) => {
return (
<div className={styles.cardPadding} key={`${item.title}-card-${index}`}>
<ProductionCard title={item.title} content={item.content} onChange={item.onclick} />
</div>
<Col lg={8} md={12} span={8} xs={16} sm={16} key={`${item.title}-card-${index}`}>
<div className={styles.cardPadding}>
<ProductionCard title={item.title} content={item.content} onChange={item.onclick} />
</div>
</Col>
);
})}
</div>
</Content>
</Row>
</div>
);
};
......
.footer {
position: fixed;
bottom: 0;
display: flex;
width: calc(100% - 200px);
height: 150px;
padding: 16px 180px;
background-color: white;
box-shadow: 0 2px 8px #f0f1f2;
.chatWrapper {
flex: 1;
padding: 0 16px 0 50px;
:global {
.ant-input:focus,
.ant-input:hover,
.ant-input-focused {
border-color: #009b95;
}
.ant-input:focus,
.ant-input-focused {
box-shadow: 0 0 0 2px #009b95;
}
}
}
.outputButtonWrapper {
width: 120px;
:global(.ant-btn-primary) {
background: #009b95;
border: solid 1px #009b95;
}
}
}
import { Layout, Input, Button, Form } from 'antd';
import styles from './footer.less';
const { Footer } = Layout;
const { Item } = Form;
function ChatFooter() {
return (
<Footer className={styles.footer}>
<div className={styles.chatWrapper}>
<Item name="chatInput">
<Input placeholder="在这里输入你想知道的问题,给我几句提示,我来帮你回答" size="large" />
</Item>
</div>
<div className={styles.outputButtonWrapper}>
<Item name="outputButton">
<Button type="primary" size="large">
发送
</Button>
</Item>
</div>
</Footer>
);
}
export default ChatFooter;
.header {
margin-top: 68px;
color: #333;
font-size: 32px;
line-height: 45px;
text-align: center;
.subTitle {
color: #999999;
font-weight: 400;
}
}
import { PageContainer } from '@ant-design/pro-components';
import { Alert, Card, Typography, Layout } from 'antd';
import React from 'react';
import styles from './header.less';
import ProductionCard from './productionCard';
const { Header } = Layout;
const { Title } = Typography;
const ChatHeader: React.FC = () => {
return (
<div className={styles.header}>
<Title level={1}>产品名称</Title>
<Title level={5} className={styles.subTitle}>
AI改变世界
</Title>
</div>
);
};
export default ChatHeader;
......@@ -3,23 +3,43 @@
.chatContent {
background: white !important;
}
.sider {
width: 240px !important;
min-height: 100vh;
padding: 30px 20px;
.siderChatContent {
height: 70%;
:global(.ant-btn-primary) {
background: #009b95;
border: solid 1px #009b95;
border-radius: 2px;
.siderWrapper {
background: white;
.sider {
position: fixed;
left: 0;
z-index: 100;
width: 240px;
min-height: 100vh;
padding: 30px 20px;
background-color: #001529;
.siderChatContent {
height: 70%;
min-height: 400px;
:global(.ant-btn-primary) {
background: #009b95;
border: solid 1px #009b95;
border-radius: 2px;
}
}
.siderTabs {
}
.noMentionLogin {
}
}
.siderTabs {
}
.noMentionLogin {
}
.header {
margin-top: 68px;
color: #333;
font-size: 32px;
line-height: 45px;
text-align: center;
.subTitle {
color: #999999;
font-weight: 400;
}
}
.chatSiderChatTabsCard {
display: flex;
margin-top: 40px;
......@@ -50,3 +70,42 @@
font-family: PingFangSC-Regular, PingFang SC;
}
}
.footer {
position: fixed;
bottom: 0;
width: calc(100% - 200px);
height: 150px;
padding: 16px;
background-color: white;
box-shadow: 0 2px 8px #f0f1f2;
.chatWrapper {
flex: 1;
padding: 0 16px 0 50px;
:global {
.ant-input:focus,
.ant-input:hover,
.ant-input-focused {
border-color: #009b95;
}
.ant-input:focus,
.ant-input-focused {
box-shadow: 0 0 0 2px #009b95;
}
}
}
.outputButtonWrapper {
width: 120px;
:global(.ant-btn-primary) {
background: #009b95;
border: solid 1px #009b95;
}
}
}
.mobileHeader {
height: 44px;
color: white;
font-size: 15px;
background-color: #009b95;
}
/* eslint-disable @typescript-eslint/no-unused-expressions */
import { Layout, Form, Button } from 'antd';
import { Form, Button, Col, Row, Input, Typography } from 'antd';
import React, { useState } from 'react';
import styles from './index.less';
import ChatFirstContent from './components/content';
import ChatHeader from './components/header';
import ChatFooter from './components/footer';
import {
DeleteOutlined,
FieldTimeOutlined,
MenuOutlined,
PlusOutlined,
SettingOutlined,
UserOutlined,
WechatOutlined,
} from '@ant-design/icons';
import classNames from 'classnames';
import { Grid } from 'antd';
const { useBreakpoint } = Grid;
const { Title } = Typography;
const { Sider } = Layout;
const { Item } = Form;
const Chat: React.FC = () => {
const screens = useBreakpoint();
const isMobile = screens.xs;
const [chat, SetChat] = useState({
chatInput: '',
});
const [showSider, setShowSider] = useState(true);
const [firstChat, setFirstChat] = useState(false);
const [form] = Form.useForm();
const [selectSiderTabs, setSelectSiderTabs] = useState('');
......@@ -68,66 +75,135 @@ const Chat: React.FC = () => {
setSelectSiderTabs(value);
};
const renderMobileHeader = () => {
return (
<Row align={'middle'} justify="space-between" gutter={1} className={styles.mobileHeader}>
<Col push={1}>
<MenuOutlined
onClick={() => {
setShowSider(!showSider);
}}
/>
</Col>
<Col>AI改变世界</Col>
<Col pull={1}>
<FieldTimeOutlined />
</Col>
</Row>
);
};
return (
<Layout>
<Sider className={styles.sider}>
<div className={styles.siderChatContent}>
<Button size="large" block type="primary" icon={<PlusOutlined />}>
新建对话
</Button>
</div>
<div className={styles.siderTabs}>
{siderTabsList.map((item) => {
return (
<div
key={item.text}
className={styles.chatSiderChatTabsCard}
onClick={() => {
selectSliderTabsHandleClick(item.checked);
}}
>
<div
className={classNames(
styles.chatSiderChatTabsCardIcons,
selectSiderTabs === item.checked && styles.checkedChatSiderChatTabsCardIcons,
)}
>
{item.icons}
</div>
<div
className={classNames(
styles.chatSiderChatTabsCardText,
selectSiderTabs === item.checked && styles.checkedChatSiderChatTabsCardText,
)}
>
{item.text}
</div>
<>
{isMobile && renderMobileHeader()}
<Row>
{showSider && (
<Col span={4} sm={10} md={7} xs={12} lg={5} className={styles.siderWrapper}>
<div className={styles.sider}>
<div className={styles.siderChatContent}>
<Button size="large" block type="primary" icon={<PlusOutlined />}>
新建对话
</Button>
</div>
);
})}
</div>
<div className={styles.noMentionLogin} />
</Sider>
<Layout className={styles.chatContent}>
{!firstChat && <ChatHeader />}
<Form
form={form}
initialValues={{ ...chat }}
name="chat"
onValuesChange={onChange}
onFinish={onSend}
>
{firstChat ? (
<div className={styles.chatRoom}>sss</div>
) : (
<Item name="firstInput">
<ChatFirstContent />
</Item>
<div className={styles.siderTabs}>
<Row>
{siderTabsList.map((item) => {
return (
<Col key={item.text}>
<div
className={styles.chatSiderChatTabsCard}
onClick={() => {
selectSliderTabsHandleClick(item.checked);
}}
>
<div
className={classNames(
styles.chatSiderChatTabsCardIcons,
selectSiderTabs === item.checked &&
styles.checkedChatSiderChatTabsCardIcons,
)}
>
{item.icons}
</div>
<div
className={classNames(
styles.chatSiderChatTabsCardText,
selectSiderTabs === item.checked &&
styles.checkedChatSiderChatTabsCardText,
)}
>
{item.text}
</div>
</div>
</Col>
);
})}
</Row>
</div>
<div className={styles.noMentionLogin} />
</div>
</Col>
)}
<Col className={styles.chatContent} span={20} lg={19} sm={14} md={17} xs={12}>
{!firstChat && (
<>
<div className={styles.header}>
<Row>
<Col span={24}>
<Title level={1}>产品名称</Title>
</Col>
<Col span={24}>
<Title level={5} className={styles.subTitle}>
AI改变世界
</Title>
</Col>
</Row>
</div>
</>
)}
<ChatFooter />
</Form>
</Layout>
</Layout>
<Form
form={form}
initialValues={{ ...chat }}
name="chat"
onValuesChange={onChange}
onFinish={onSend}
>
{firstChat ? (
<div className={styles.chatRoom}>sss</div>
) : (
<Item name="firstInput">
<ChatFirstContent />
</Item>
)}
<div className={styles.footer}>
<Row>
<Col span={20}>
<div className={styles.chatWrapper}>
<Item name="chatInput">
<Input
placeholder="在这里输入你想知道的问题,给我几句提示,我来帮你回答"
size="large"
/>
</Item>
</div>
</Col>
<Col span={4}>
<div className={styles.outputButtonWrapper}>
<Item name="outputButton">
<Button type="primary" size="large">
发送
</Button>
</Item>
</div>
</Col>
</Row>
</div>
</Form>
</Col>
</Row>
</>
);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment