-
Notifications
You must be signed in to change notification settings - Fork 818
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(flat-components): add InviteModal and RemoveDetailModal (#618)
- Loading branch information
Showing
5 changed files
with
319 additions
and
0 deletions.
There are no files selected for viewing
35 changes: 35 additions & 0 deletions
35
packages/flat-components/src/components/InviteModal/InviteModal.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import React from "react"; | ||
import { Meta, Story } from "@storybook/react"; | ||
import { InviteModal, InviteModalProps } from "."; | ||
import { RoomStatus, RoomType } from "../../types/room"; | ||
import { message } from "antd"; | ||
|
||
const storyMeta: Meta = { | ||
title: "Components/InviteModal", | ||
component: InviteModal, | ||
}; | ||
|
||
export default storyMeta; | ||
|
||
export const Overview: Story<InviteModalProps> = args => ( | ||
<div className="vh-75 mw8-ns"> | ||
<InviteModal {...args} /> | ||
</div> | ||
); | ||
Overview.args = { | ||
visible: true, | ||
room: { | ||
roomUUID: "roomUUID", | ||
ownerUUID: "ownerUUID", | ||
title: "RoomDetailTitle", | ||
roomType: RoomType.BigClass, | ||
roomStatus: RoomStatus.Started, | ||
beginTime: 1619771930756, | ||
endTime: 1619775530756, | ||
}, | ||
userName: "Flat", | ||
onCopy: () => { | ||
message.success("复制成功"); | ||
}, | ||
onCancel: () => {}, | ||
}; |
69 changes: 69 additions & 0 deletions
69
packages/flat-components/src/components/InviteModal/index.less
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
.invite-modal { | ||
.ant-modal-content { | ||
border-radius: 8px; | ||
} | ||
|
||
.ant-modal-footer { | ||
button { | ||
border-radius: 4px; | ||
} | ||
} | ||
} | ||
|
||
.invite-modal-header { | ||
margin-top: -5px; | ||
width: 100%; | ||
|
||
span { | ||
display: block; | ||
font-size: 14px; | ||
font-family: PingFangSC-Medium, PingFang SC, serif; | ||
|
||
&:first-of-type { | ||
margin-bottom: 8px; | ||
color: #444e60; | ||
font-weight: 500; | ||
font-size: 16px; | ||
} | ||
|
||
&:last-of-type { | ||
color: #7a7b7c; | ||
padding-bottom: 16px; | ||
border-bottom: 1px solid #dbe1ea; | ||
} | ||
} | ||
} | ||
|
||
.invite-modal-content { | ||
margin-top: 23px; | ||
} | ||
|
||
.invite-modal-content-item { | ||
display: flex; | ||
|
||
span { | ||
display: inline-block; | ||
|
||
&:first-of-type { | ||
flex: 1; | ||
min-width: 25%; | ||
color: #7a7b7c; | ||
} | ||
|
||
&:last-of-type { | ||
flex: auto; | ||
text-align: right; | ||
} | ||
} | ||
|
||
&:not(:last-of-type) { | ||
margin-bottom: 8px; | ||
} | ||
} | ||
|
||
.invite-modal-content-title { | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
white-space: nowrap; | ||
word-break: keep-all; | ||
} |
98 changes: 98 additions & 0 deletions
98
packages/flat-components/src/components/InviteModal/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import "./index.less"; | ||
|
||
import React, { useMemo } from "react"; | ||
import { Modal } from "antd"; | ||
import { differenceInCalendarDays, format } from "date-fns/fp"; | ||
import { RoomInfo, Week } from "../../types/room"; | ||
import { getWeekNames } from "../../utils/room"; | ||
|
||
const completeTimeFormat = format("yyyy-MM-dd HH:mm"); | ||
const onlySuffixTimeFormat = format("HH:mm"); | ||
|
||
export interface InviteModalProps { | ||
visible: boolean; | ||
room: RoomInfo; | ||
weeks?: Week[]; | ||
userName: string; | ||
onCopy: (text: string) => void; | ||
onCancel: () => void; | ||
} | ||
|
||
export const InviteModal: React.FC<InviteModalProps> = ({ | ||
visible, | ||
room, | ||
weeks, | ||
userName, | ||
onCopy, | ||
onCancel, | ||
}) => { | ||
const { beginTime, endTime, periodicUUID, roomUUID, title } = room; | ||
const uuid = periodicUUID || roomUUID; | ||
|
||
const formattedTimeRange = useMemo<string>(() => { | ||
if (!beginTime || !endTime) { | ||
return ""; | ||
} | ||
|
||
const formatBeginTime = completeTimeFormat(beginTime!); | ||
const formatEndTime = | ||
differenceInCalendarDays(beginTime!, endTime!) !== 0 | ||
? completeTimeFormat(endTime!) | ||
: onlySuffixTimeFormat(endTime!); | ||
|
||
return `${formatBeginTime}~${formatEndTime}`; | ||
}, [beginTime, endTime]); | ||
|
||
const onCopyClicked = (): void => { | ||
const basePrefixText = | ||
`${userName} 邀请你加入 Flat 房间\n` + | ||
`房间主题:${title}\n` + | ||
(formattedTimeRange ? `开始时间:${formattedTimeRange}\n` : ""); | ||
const baseSuffixText = | ||
`\n房间号:${uuid}\n\n` + | ||
`打开(没有安装的话请先下载并安装)并登录 Flat,点击加入房间,输入房间号即可加入和预约`; | ||
|
||
if (periodicUUID) { | ||
const content = weeks ? `重复周期:${getWeekNames(weeks || [])}` : ""; | ||
|
||
onCopy(`${basePrefixText}${content}${baseSuffixText}`); | ||
} else { | ||
onCopy(`${basePrefixText}${baseSuffixText}`); | ||
} | ||
}; | ||
|
||
return ( | ||
<Modal | ||
width={460} | ||
visible={visible} | ||
onOk={onCopyClicked} | ||
onCancel={onCancel} | ||
okText="复制" | ||
cancelText="取消" | ||
className="invite-modal" | ||
> | ||
<div className="invite-modal-header"> | ||
<span>{userName} 邀请加入 FLAT 房间</span> | ||
<span>可通过房间号加入和预约</span> | ||
</div> | ||
<div className="invite-modal-content"> | ||
<div className="invite-modal-content-item"> | ||
<span>房间主题</span> | ||
<span className="invite-modal-content-title">{title}</span> | ||
</div> | ||
<div className="invite-modal-content-item"> | ||
<span>房间号</span> | ||
<span style={{ userSelect: "text" }}>{uuid}</span> | ||
</div> | ||
{formattedTimeRange && ( | ||
<div className="invite-modal-content-item"> | ||
<span>开始时间</span> | ||
<span>{formattedTimeRange}</span> | ||
</div> | ||
)} | ||
</div> | ||
{/* @TODO Add invite URL */} | ||
{/*<Input type="text" placeholder="https://netless.link/url/5f2259d5069bc052d2" />*/} | ||
</Modal> | ||
); | ||
}; |
25 changes: 25 additions & 0 deletions
25
packages/flat-components/src/components/RemoveRoomModal/RemoveRoomModal.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import React from "react"; | ||
import { Meta, Story } from "@storybook/react"; | ||
import { RemoveRoomModal, RemoveRoomModalProps } from "."; | ||
|
||
const storyMeta: Meta = { | ||
title: "Components/RemoveRoomModal", | ||
component: RemoveRoomModal, | ||
}; | ||
|
||
export default storyMeta; | ||
|
||
export const Overview: Story<RemoveRoomModalProps> = args => ( | ||
<div className="vh-75 mw8-ns"> | ||
<RemoveRoomModal {...args} /> | ||
</div> | ||
); | ||
Overview.args = { | ||
cancelModalVisible: true, | ||
isCreator: true, | ||
roomUUID: "roomUUID", | ||
periodicUUID: "periodicUUID", | ||
isPeriodicDetailsPage: true, | ||
onCancel: () => {}, | ||
onCancelRoom: () => {}, | ||
}; |
92 changes: 92 additions & 0 deletions
92
packages/flat-components/src/components/RemoveRoomModal/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { Button, Checkbox, Modal } from "antd"; | ||
import React, { useState } from "react"; | ||
|
||
export interface RemoveRoomModalProps { | ||
cancelModalVisible: boolean; | ||
isCreator: boolean; | ||
roomUUID?: string; | ||
periodicUUID?: string; | ||
isPeriodicDetailsPage: boolean; | ||
onCancel: () => void; | ||
onCancelRoom: () => void; | ||
} | ||
|
||
export const RemoveRoomModal: React.FC<RemoveRoomModalProps> = ({ | ||
cancelModalVisible, | ||
isCreator, | ||
roomUUID, | ||
periodicUUID, | ||
isPeriodicDetailsPage, | ||
onCancel, | ||
onCancelRoom, | ||
}) => { | ||
const [isCancelAll, setIsCancelAll] = useState(false); | ||
const isPeriodicRoom = !!periodicUUID && !roomUUID; | ||
const isSubPeriodicRoom = periodicUUID && roomUUID; | ||
|
||
const title = (() => { | ||
if (!isCreator) { | ||
return "移除房间"; | ||
} | ||
|
||
if (isPeriodicRoom && isPeriodicDetailsPage) { | ||
return "取消周期性房间"; | ||
} | ||
|
||
return "取消房间"; | ||
})(); | ||
|
||
const content = (): React.ReactElement => { | ||
if (!periodicUUID) { | ||
if (isCreator) { | ||
return <span>确定取消该房间?取消后其他成员将无法加入。</span>; | ||
} | ||
|
||
return <span>确定从房间列表移除该房间?移除后可通过房间号再次加入。</span>; | ||
} | ||
|
||
if (!isCreator) { | ||
return <span>确定从房间列表中移除该系列周期性房间?移除后可通过房间号再次加入。</span>; | ||
} | ||
|
||
if (!isPeriodicDetailsPage) { | ||
return ( | ||
<> | ||
<span>确定取消该房间?</span> | ||
<br /> | ||
<br /> | ||
<Checkbox | ||
checked={isCancelAll} | ||
onChange={e => setIsCancelAll(e.target.checked)} | ||
> | ||
同时取消该系列周期性房间 | ||
</Checkbox> | ||
</> | ||
); | ||
} | ||
|
||
if (isSubPeriodicRoom) { | ||
return <span>确定将此房间从该周期性房间中取消?取消后其他成员将无法加入。</span>; | ||
} | ||
|
||
return <span>确定取消该周期性房间?取消后其他成员将无法加入。</span>; | ||
}; | ||
|
||
return ( | ||
<Modal | ||
visible={cancelModalVisible} | ||
title={title} | ||
onCancel={onCancel} | ||
footer={[ | ||
<Button key="Cancel" onClick={onCancel}> | ||
{isCreator ? "再想想" : "取消"} | ||
</Button>, | ||
<Button key="Ok" type="primary" onClick={onCancelRoom}> | ||
确定 | ||
</Button>, | ||
]} | ||
> | ||
{content()} | ||
</Modal> | ||
); | ||
}; |