diff --git a/.prettierignore b/.prettierignore index a3ced00..e82e540 100644 --- a/.prettierignore +++ b/.prettierignore @@ -9,4 +9,8 @@ node_modules/ .husky .prettierignore .env.* -project.*.json \ No newline at end of file +<<<<<<< HEAD +project.*.json +======= +**/*.svg +>>>>>>> dev diff --git a/src/assets/icons/MainPage/cross.svg b/src/assets/icons/MainPage/cross.svg new file mode 100644 index 0000000..35ab54d --- /dev/null +++ b/src/assets/icons/MainPage/cross.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/MainPage/tick.svg b/src/assets/icons/MainPage/tick.svg new file mode 100644 index 0000000..e31ad61 --- /dev/null +++ b/src/assets/icons/MainPage/tick.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/PageFooter/PageFooter.config.ts b/src/components/PageFooter/PageFooter.config.ts new file mode 100644 index 0000000..fd50080 --- /dev/null +++ b/src/components/PageFooter/PageFooter.config.ts @@ -0,0 +1,3 @@ +export default { + component: true, +}; diff --git a/src/components/PageFooter/PageFooter.scss b/src/components/PageFooter/PageFooter.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/PageFooter/PageFooter.tsx b/src/components/PageFooter/PageFooter.tsx new file mode 100644 index 0000000..fb475f2 --- /dev/null +++ b/src/components/PageFooter/PageFooter.tsx @@ -0,0 +1,17 @@ +import { View } from '@tarojs/components'; +import { AtDivider } from 'taro-ui'; +import pt from '@/plain-text'; + +export default () => { + const blankHeight = 120; + return ( + + + + + ); +}; diff --git a/src/pages/index/DutyInfo.tsx b/src/pages/index/DutyInfo.tsx new file mode 100644 index 0000000..4e3daac --- /dev/null +++ b/src/pages/index/DutyInfo.tsx @@ -0,0 +1,107 @@ +import { Component, ReactNode } from 'react'; +import { View, Image } from '@tarojs/components'; +import { AtTimeline } from 'taro-ui'; +import pt from '@/plain-text'; +import tick from '@/assets/icons/MainPage/tick.svg'; +import cross from '@/assets/icons/MainPage/cross.svg'; + +export class DutyData { + constructor() { + this.isInDuty = false; + this.inDutyCnt = 3; + this.currentDuty = '2'; + this.offDutyReason = '学园维修'; + this.dutyRecoverTime = '下周一'; + } + + isInDuty: boolean; + inDutyCnt: number; + currentDuty: 'off' | '1' | '2' | '3'; + offDutyReason: string; // from backend + dutyRecoverTime: string; // from backend +} + +class Card extends Component { + props = { + isInDuty: false, + }; + render(): ReactNode { + const inDuty = this.props.isInDuty; + const dc = pt.get().mainPage.dutyCard; + const title = inDuty ? dc.inDuty.title : dc.offDuty.title; + const iconsrc = inDuty ? tick : cross; + return ( + + + + + {title} + + + + ); + } +} + +export class DutyInfo extends Component { + props = { + data: new DutyData(), + }; + + offDutyContent(): ReactNode { + const data = this.props.data; + const od = pt.get().mainPage.dutyCard.offDuty; + return ( + + + + + ); + } + + inDutyContent(): ReactNode { + const data = this.props.data; + const id = pt.get().mainPage.dutyCard.inDuty; + return ( + + + + + ); + } + + render(): ReactNode { + if (this.props.data.isInDuty) { + return this.inDutyContent(); + } else { + return this.offDutyContent(); + } + } +} diff --git a/src/pages/index/StepTipsInfo.tsx b/src/pages/index/StepTipsInfo.tsx new file mode 100644 index 0000000..4747016 --- /dev/null +++ b/src/pages/index/StepTipsInfo.tsx @@ -0,0 +1,24 @@ +import { Component, ReactNode } from 'react'; +import { View } from '@tarojs/components'; +import { AtTimeline } from 'taro-ui'; +import pt from '@/plain-text'; + +export class StepInfo extends Component { + render(): ReactNode { + return ( + + + + ); + } +} + +export class TipsInfo extends Component { + render(): ReactNode { + return ( + + + + ); + } +} diff --git a/src/pages/index/TitleCard.tsx b/src/pages/index/TitleCard.tsx new file mode 100644 index 0000000..39fb1ac --- /dev/null +++ b/src/pages/index/TitleCard.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { View } from '@tarojs/components'; +import pt from '@/plain-text'; + +export default class TitleCard extends React.Component { + render(): React.ReactNode { + const mainPage = pt.get().mainPage; + return ( + + {mainPage.mainTitleLine} + {mainPage.subTitleLine} + + ); + } +} diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index 1700871..f001c83 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -1,12 +1,81 @@ -import { View, Text } from '@tarojs/components'; +import { View } from '@tarojs/components'; import { Component, ReactNode } from 'react'; import Taro from '@tarojs/taro'; -import type CustomTabBar from '../../custom-tab-bar'; +import { AtCard, AtAccordion } from 'taro-ui'; +import type CustomTabBar from '@/custom-tab-bar'; +import PageFooter from '@/components/PageFooter/PageFooter'; +import pt from '@/plain-text'; import './index.scss'; +import TitleCard from './TitleCard'; +import { DutyInfo, DutyData } from './DutyInfo'; +import { StepInfo, TipsInfo } from './StepTipsInfo'; -class Index extends Component { +class CardContent { + title: string; + note: string; + extra: JSX.Element | string; + content: () => JSX.Element; +} + +function mainPageCard(c: CardContent): JSX.Element { + return ( + + + {c.content()} + + + ); +} + +class ExpandItem extends Component { state = { - msg: 'Hello World!', + open: false, + }; + props = { + title: '', + content: , + }; + + handleClick(value: boolean) { + this.setState({ open: value }); + } + + render(): ReactNode { + return ( + + + {this.props.content} + + + ); + } +} + +export default class Index extends Component { + state = { + dutyData: new DutyData(), + dutyInfoCard: { + title: pt.get().mainPage.cardTitle.dutyInfo, + note: 'Tips', + extra: '额外信息', + content: () => , + }, + stepInfoCard: { + title: pt.get().mainPage.cardTitle.stepInfo, + note: 'Tips 请在20:30以前取走自己的物品哦', + extra: '额外信息', + content: () => , + }, + tipsInfoCard: { + title: pt.get().mainPage.cardTitle.tipsInfo, + note: 'Tips', + extra: '额外信息', + content: () => , + }, }; // 以下是TabBar相关 @@ -18,12 +87,20 @@ class Index extends Component { // 以上是TabBar相关 render(): ReactNode { + const mainPage = pt.get().mainPage; return ( - {this.state.msg} + + + {mainPageCard(this.state.dutyInfoCard)} + {mainPageCard(this.state.tipsInfoCard)} + + + ); } } - -export default Index; diff --git a/src/pages/user/inform/inform.tsx b/src/pages/user/inform/inform.tsx index 0c00edf..051ae9d 100644 --- a/src/pages/user/inform/inform.tsx +++ b/src/pages/user/inform/inform.tsx @@ -1,10 +1,60 @@ -import { View } from '@tarojs/components'; import { Component, ReactNode } from 'react'; -import Taro from '@tarojs/taro'; +import { AtForm, AtInput, AtButton } from 'taro-ui'; import './inform.scss'; export default class InformPage extends Component { + state = { + phone: '', + name: '', + }; + handleChangePhone(phone: string) { + this.setState({ + phone: phone, + }); + return phone; + } + handleChangeName(name: string) { + this.setState({ + name: name, + }); + return name; + } + onSubmit() { + console.log(this.state.name, this.state.phone); + } + onReset() { + this.setState({ + phone: '', + name: '', + }); + } + render(): ReactNode { - return ; + return ( + + + + 提交 + 重置 + + ); } } diff --git a/src/plain-text/MainPage.ts b/src/plain-text/MainPage.ts new file mode 100644 index 0000000..e804739 --- /dev/null +++ b/src/plain-text/MainPage.ts @@ -0,0 +1,77 @@ +export interface MainPageText { + mainTitleLine: string; + subTitleLine: string; + cardTitle: { + dutyInfo: string; + stepInfo: string; + tipsInfo: string; + }; + expandTitle: { + stepInfo: string; + tipsInfo: string; + }; + stepList: Array<{ title: string }>; + tipsList: Array<{ title: string }>; + + dutyCard: { + offDuty: { + title: string; + reason: (s: string) => string; + recoverTime: (t: string) => string; + }; + inDuty: { + title: string; + currentDutyText: (c: 'off' | '1' | '2' | '3') => string; + inDutyCnt: (n: number) => string; + }; + }; +} + +export const mainPageZhCn: MainPageText = { + mainTitleLine: '您好,这里是E志者协会', + subTitleLine: '维修请至【东三-204】实验室', + cardTitle: { + dutyInfo: '204值班情况', + stepInfo: '维修步骤', + tipsInfo: '注意事项', + }, + expandTitle: { + stepInfo: '查看维修步骤', + tipsInfo: '查看注意事项', + }, + stepList: [ + { title: '线上填写工单' }, + { title: '去`东三-204`实验室维修电脑' }, + { title: '等待电脑维修' }, + { title: '维修结束,取回电脑' }, + ], + tipsList: [ + { title: '戴尔、Surface、外星人、苹果电脑不能拆机哦~' }, + { title: '数据无价,请随时做好数据备份哦~' }, + { title: '204也是实验室,请遵守实验室纪律,请勿饮食~' }, + { title: '我们是志愿服务,不收任何礼物哦~' }, + ], + dutyCard: { + offDuty: { + title: '未值班', + reason: s => '值班停止原因:' + s, + recoverTime: t => '恢复值班时间:' + t, + }, + inDuty: { + title: '值班中', + currentDutyText: c => { + switch (c) { + case 'off': + return '当前未值班'; + case '1': + return '第一班 13:30-16:00'; + case '2': + return '第二班 16:00-18:00'; + case '3': + return '第三班 18:00-20:30'; + } + }, + inDutyCnt: n => '当前值班人数:' + n, + }, + }, +}; diff --git a/src/plain-text/PageFooter.ts b/src/plain-text/PageFooter.ts new file mode 100644 index 0000000..ac20e88 --- /dev/null +++ b/src/plain-text/PageFooter.ts @@ -0,0 +1,7 @@ +export interface PageFooterText { + dividerText: string; +} + +export const pageFooterZhCn: PageFooterText = { + dividerText: 'EVA Notify', +}; diff --git a/src/plain-text/index.ts b/src/plain-text/index.ts new file mode 100644 index 0000000..bb3fdea --- /dev/null +++ b/src/plain-text/index.ts @@ -0,0 +1,40 @@ +import { PageFooterText, pageFooterZhCn } from './PageFooter'; +import { MainPageText, mainPageZhCn } from './MainPage'; + +interface TextRecord { + pageFooter: PageFooterText; + mainPage: MainPageText; +} + +const textZhCn: TextRecord = { + pageFooter: pageFooterZhCn, + mainPage: mainPageZhCn, +}; + +// type Lang = 'zh_CN' | 'en_US' | ...; +type Lang = 'zh_CN'; + +class PlainText { + private readonly textZhCn: TextRecord; + private lang: Lang; + + constructor() { + this.textZhCn = textZhCn; + this.lang = 'zh_CN'; + } + + setLang(lang: Lang) { + this.lang = lang; + } + + get(): TextRecord { + if (this.lang == 'zh_CN') { + return this.textZhCn; + } + return this.textZhCn; + } +} + +const pt = new PlainText(); + +export default pt;