diff --git a/src/App.tsx b/src/App.tsx index 843997c..875238e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,18 +1,14 @@ -import React from 'react'; import Head from './layout/head/Head.tsx'; -import Nav from "./layout/nav/Nav.tsx"; import Body from './layout/body/Body.tsx'; import Foot from './layout/foot/Foot.tsx'; - const App: React.FC = () => { return ( -
+ <> -
+ ); }; diff --git a/src/components/card/CardProjType.tsx b/src/components/card/CardProjType.tsx new file mode 100644 index 0000000..14163b0 --- /dev/null +++ b/src/components/card/CardProjType.tsx @@ -0,0 +1,83 @@ +import './card-proj-type.css'; +import {ICardProj, ICardProjChargeLine} from "../../interfaces/proj/ICardProj.ts"; +import {Checkbox} from 'antd'; +import {useState} from "react"; + +export default function CardProjType(props: ICardProj) { + + const [chargeAmount, setChargeAmount] = useState(0); + + const renderContents = (lineIndex: number, contents: string[]) => { + return contents.map((item, index) =>
  • {item}
  • ); + } + + const renderLines = () => { + return props.bodyLineArray.map((line, index) => { + return ( +
    +
    {line.title}
    +
    +
      {renderContents(index, line.contents)}
    +
    +
    + ) + }) + } + + const onChargeChange = (checked: boolean, line: ICardProjChargeLine) => { + if (checked) { + setChargeAmount(chargeAmount + line.price); + } else { + setChargeAmount(chargeAmount - line.price); + } + } + + const renderCharge = () => { + if (!props.chargeLineArray || props.chargeLineArray.length == 0) { + return <> + } + return ( + <> +
    { + props.chargeLineArray.map((line, index) => ( +
    + { + onChargeChange(e.target.checked, line); + }}>{line.title} +
    + )) + }
    + + ) + } + + const renderBuyBtn = () => { + return props.buyArray.map((buy, index) => { + return ( +
    +
    {buy.label}{buy.price + chargeAmount} 元
    +
    +
    + +
    +
    + ) + }) + } + + return ( +
    +
    +
    {props.head}
    +
    +
    +
    {renderLines()}
    + {renderCharge()} +
    +
    {renderBuyBtn()}
    +
    + ) +} \ No newline at end of file diff --git a/src/components/card/card-proj-type.css b/src/components/card/card-proj-type.css new file mode 100644 index 0000000..56fb5ba --- /dev/null +++ b/src/components/card/card-proj-type.css @@ -0,0 +1,61 @@ +.proj { + width: 250px; +} + +.proj .proj-head { + margin-bottom: 15px; + padding: 15px; + font-size: 20px; + font-weight: bold; + text-align: center; + border: 1px solid var(--color-border); +} + +.proj .proj-body { + min-height: 360px; + margin-bottom: 15px; + padding: 15px; + display: flex; + flex-direction: column; + justify-content: space-between; + + border: 1px solid var(--color-border); +} + +.proj .proj-body .line .line-title { + font-size: 16px; + font-weight: bold; +} + +.proj .proj-body .line .line-content ol { + padding-left: 15px; + +} + +.proj .proj-body .proj-charge { +} + +.proj .proj-foot { + padding: 15px; + border: 1px solid var(--color-border); + display: flex; + justify-content: center; + align-items: center; +} + +.proj .proj-foot .buy-btn { + text-align: center; + margin: 0 5px; + flex-basis: 100%; +} + +.proj .proj-foot .buy-btn .price { +} +.proj .proj-foot .buy-btn .buy { +} + +.proj .proj-foot .buy-btn .buy button { + border: none; + cursor: pointer; + background-color: transparent; +} \ No newline at end of file diff --git a/src/context/Context.tsx b/src/context/Context.tsx index 956d492..8e9871b 100644 --- a/src/context/Context.tsx +++ b/src/context/Context.tsx @@ -1,15 +1,6 @@ import {createContext} from "react"; import axios from 'axios'; -import {ItemType} from "antd/es/breadcrumb/Breadcrumb"; axios.defaults.baseURL = 'https://localhost:8080'; -export const Axios = createContext(axios) - -const nav: ItemType = { - title: 首页 -} - -export const Navs = createContext([nav, { - title: 首页 -}]) \ No newline at end of file +export const Axios = createContext(axios); diff --git a/src/interfaces/proj/ICardProj.ts b/src/interfaces/proj/ICardProj.ts new file mode 100644 index 0000000..acfe14a --- /dev/null +++ b/src/interfaces/proj/ICardProj.ts @@ -0,0 +1,23 @@ +export interface ICardProjBodyLine { + title: string; + contents: string[]; +} + +export interface ICardProjChargeLine { + title: string; + price: number; +} + +export interface ICardProjBuy { + label?: string, + price: number; + + handleClick(title: string, price: number): void; +} + +export interface ICardProj { + head: string; + bodyLineArray: ICardProjBodyLine[]; + chargeLineArray?: ICardProjChargeLine[]; + buyArray: ICardProjBuy[]; +} \ No newline at end of file diff --git a/src/layout/body/Body.tsx b/src/layout/body/Body.tsx index 4c20161..5560419 100644 --- a/src/layout/body/Body.tsx +++ b/src/layout/body/Body.tsx @@ -1,7 +1,8 @@ import './body.css' import {createBrowserRouter, RouterProvider} from 'react-router-dom'; import Index from '../../route/index'; -import ProjType from "../../route/proj/ProjType.tsx"; +import ProjCreate from "../../route/proj/ProjCreate.tsx"; +import ProjNew from "../../route/proj/ProjNew.tsx"; const router = createBrowserRouter([ { @@ -9,8 +10,12 @@ const router = createBrowserRouter([ element: }, { - path: '/proj-type', - element: + path: '/proj-create', + element: + }, + { + path: '/proj-new/:type/:price', + element: } ]) diff --git a/src/layout/body/body.css b/src/layout/body/body.css index 5624718..3da79a1 100644 --- a/src/layout/body/body.css +++ b/src/layout/body/body.css @@ -1,5 +1,8 @@ .body { - margin: 0 auto 10px auto; + margin: 65px auto 10px auto; width: var(--width-workspace); - background-color: #FFFFFF; +} + +.body > .ant-breadcrumb { + padding: 10px 15px; } \ No newline at end of file diff --git a/src/layout/nav/Nav.tsx b/src/layout/nav/Nav.tsx deleted file mode 100644 index ba0177f..0000000 --- a/src/layout/nav/Nav.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import './nav.css'; -import {Breadcrumb } from 'antd'; -import {useContext} from "react"; -import {Navs} from '../../context/Context.tsx'; - -export default function Nav() { - - const navs = useContext(Navs) - return ( -
    - -
    - ) -} \ No newline at end of file diff --git a/src/layout/nav/nav.css b/src/layout/nav/nav.css deleted file mode 100644 index d14b487..0000000 --- a/src/layout/nav/nav.css +++ /dev/null @@ -1,22 +0,0 @@ -.nav { - width: var(--width-workspace); - margin: calc(var(--height-head) + 15px) auto 10px auto; -} - -.nav ul { - display: flex; - align-items: center; -} - -.nav ul li { - -} - -.nav li::after { - content: ' > '; - padding: 0 5px; -} - -.nav li:last-child::after { - content: '' -} \ No newline at end of file diff --git a/src/route/index/index.css b/src/route/index/index.css index 9908fc9..2f7069c 100644 --- a/src/route/index/index.css +++ b/src/route/index/index.css @@ -1,6 +1,7 @@ .index { position: relative; height: 100%; + background-color: var(--color-light); } .index .left { diff --git a/src/route/index/index.tsx b/src/route/index/index.tsx index f7115ea..8b74e26 100644 --- a/src/route/index/index.tsx +++ b/src/route/index/index.tsx @@ -1,23 +1,21 @@ import './index.css'; import {MouseEvent, useState} from "react"; -import {useNavigate} from "react-router-dom"; +import {Link, useNavigate} from "react-router-dom"; import {IMenuListItem, IMenuWithTopButton} from "../../interfaces/menu/IMenuWithTopButton.ts"; import MenuWithTopButton from "../../components/menu/MenuWithTopButton.tsx"; import MenuTreeWithTopButton from "../../components/menu/MenuTreeWithTopButton.tsx"; import ListProj from "../../components/list/ListProj.tsx"; import ListProjAgent from "../../components/list/ListProjAgent.tsx"; +import {Breadcrumb} from 'antd'; export default function Index() { - - const navigate = useNavigate(); const [listType, setListType] = useState('proj'); - + const nav = useNavigate(); const projMenu: IMenuWithTopButton = { button: { name: '创建项目', - handle(e: MouseEvent) { - console.log(e) - navigate('/proj-type') + handle() { + nav('/proj-create') } }, list: [ @@ -54,21 +52,28 @@ export default function Index() { } return ( -
    -
    - - - + <> + 首页} + ]} + /> +
    +
    + + + +
    +
    {listType === 'proj' ? : }
    -
    {listType === 'proj' ? : }
    -
    + ) } \ No newline at end of file diff --git a/src/route/proj/ProjCreate.tsx b/src/route/proj/ProjCreate.tsx new file mode 100644 index 0000000..7185fc0 --- /dev/null +++ b/src/route/proj/ProjCreate.tsx @@ -0,0 +1,170 @@ +import './proj-create.css' +import {Link, useNavigate} from "react-router-dom"; +import {Breadcrumb} from "antd"; +import CardProjType from "../../components/card/CardProjType.tsx"; + +export default function ProjCreate() { + const nav = useNavigate(); + return ( + <> + 首页}, + {title: 创建项目}, + ]} + /> +
    + { + nav(`/proj-new/q/${price}`) + } + } + ]} + /> + { + nav(`/proj-new/xdp/${price}`) + } + }, + { + label: '加急:', + price: 300, + handleClick: (_title, price) => { + nav(`/proj-new/xdj/${price}`) + } + } + ]} + /> + { + nav(`/proj-new/x/${price}`) + } + } + ]} + /> + { + nav(`/proj-new/m/${price}`) + } + } + ]} + /> +
    + + ) +} \ No newline at end of file diff --git a/src/route/proj/ProjNew.tsx b/src/route/proj/ProjNew.tsx new file mode 100644 index 0000000..5e3692b --- /dev/null +++ b/src/route/proj/ProjNew.tsx @@ -0,0 +1,82 @@ +import './proj-new.css'; +import {Link, useNavigate} from "react-router-dom"; +import {Breadcrumb, Button, Flex, Form, type FormProps, Input} from "antd"; + +const {TextArea} = Input; + +type FieldType = { + projTitle: string; + projDesc: string; +}; + +export default function ProjNew() { + const nav = useNavigate(); + + const onFinish: FormProps["onFinish"] = (values) => { + console.log('Success:', values); + + }; + + const onFinishFailed: FormProps["onFinishFailed"] = (errorInfo) => { + console.log('Failed:', errorInfo); + }; + + const onBack = () => { + nav(-1); + } + + return ( + <> + 首页}, + {title: 创建项目}, + {title: 新建项目}, + ]} + /> +
    +
    请完善项目的基本信息
    +
    +
    + + label="系统标题" + name="projTitle" + rules={[{required: true, message: '请输入系统标题'}]} + > + + + + + label="简单描述" + name="projDesc" + rules={[{required: true, message: '请输入简单描述'}]} + > +