diff options
3 files changed, 118 insertions, 100 deletions
diff --git a/Timeline/ClientApp/src/app/views/timeline-common/InfoCardTemplate.tsx b/Timeline/ClientApp/src/app/views/timeline-common/InfoCardTemplate.tsx new file mode 100644 index 00000000..a8de20aa --- /dev/null +++ b/Timeline/ClientApp/src/app/views/timeline-common/InfoCardTemplate.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import clsx from "clsx"; + +import { TimelineCardComponentProps } from "../timeline-common/TimelinePageTemplateUI"; +import SyncStatusBadge from "../timeline-common/SyncStatusBadge"; +import CollapseButton from "../timeline-common/CollapseButton"; + +const InfoCardTemplate: React.FC< + Pick< + TimelineCardComponentProps<"">, + "collapse" | "toggleCollapse" | "syncStatus" | "className" + > & { children: React.ReactElement[] } +> = ({ collapse, toggleCollapse, syncStatus, className, children }) => { + return ( + <div className={clsx("cru-card p-2 clearfix", className)}> + <div className="float-right d-flex align-items-center"> + <SyncStatusBadge status={syncStatus} className="mr-2" /> + <CollapseButton collapse={collapse} onClick={toggleCollapse} /> + </div> + + <div style={{ display: collapse ? "none" : "block" }}>{children}</div> + </div> + ); +}; + +export default InfoCardTemplate; diff --git a/Timeline/ClientApp/src/app/views/timeline/TimelineInfoCard.tsx b/Timeline/ClientApp/src/app/views/timeline/TimelineInfoCard.tsx index 9c1e7f1c..d764a275 100644 --- a/Timeline/ClientApp/src/app/views/timeline/TimelineInfoCard.tsx +++ b/Timeline/ClientApp/src/app/views/timeline/TimelineInfoCard.tsx @@ -1,5 +1,4 @@ import React from "react"; -import clsx from "clsx"; import { useTranslation } from "react-i18next"; import { Dropdown, Button } from "react-bootstrap"; @@ -8,8 +7,7 @@ import { timelineVisibilityTooltipTranslationMap } from "@/services/timeline"; import BlobImage from "../common/BlobImage"; import { TimelineCardComponentProps } from "../timeline-common/TimelinePageTemplateUI"; -import CollapseButton from "../timeline-common/CollapseButton"; -import SyncStatusBadge from "../timeline-common/SyncStatusBadge"; +import InfoCardTemplate from "../timeline-common/InfoCardTemplate"; export type OrdinaryTimelineManageItem = "delete"; @@ -32,57 +30,55 @@ const TimelineInfoCard: React.FC<TimelineInfoCardProps> = (props) => { const avatar = useAvatar(timeline?.owner?.username); return ( - <div className={clsx("cru-card p-2 clearfix", props.className)}> - <div className="float-right d-flex align-items-center"> - <SyncStatusBadge status={syncStatus} className="mr-2" /> - <CollapseButton collapse={collapse} onClick={toggleCollapse} /> - </div> - - <div style={{ display: collapse ? "none" : "block" }}> - <h3 className="text-primary mx-3 d-inline-block align-middle"> - {timeline.name} - </h3> - <div className="d-inline-block align-middle"> - <BlobImage blob={avatar} className="avatar small rounded-circle" /> - {timeline.owner.nickname} - <small className="ml-3 text-secondary"> - @{timeline.owner.username} - </small> - </div> - <p className="mb-0">{timeline.description}</p> - <small className="mt-1 d-block"> - {t(timelineVisibilityTooltipTranslationMap[timeline.visibility])} + <InfoCardTemplate + className={props.className} + syncStatus={syncStatus} + collapse={collapse} + toggleCollapse={toggleCollapse} + > + <h3 className="text-primary mx-3 d-inline-block align-middle"> + {timeline.name} + </h3> + <div className="d-inline-block align-middle"> + <BlobImage blob={avatar} className="avatar small rounded-circle" /> + {timeline.owner.nickname} + <small className="ml-3 text-secondary"> + @{timeline.owner.username} </small> - <div className="text-right mt-2"> - {onManage != null ? ( - <Dropdown> - <Dropdown.Toggle variant="outline-primary"> - {t("timeline.manage")} - </Dropdown.Toggle> - <Dropdown.Menu> - <Dropdown.Item onClick={() => onManage("property")}> - {t("timeline.manageItem.property")} - </Dropdown.Item> - <Dropdown.Item onClick={onMember}> - {t("timeline.manageItem.member")} - </Dropdown.Item> - <Dropdown.Divider /> - <Dropdown.Item - className="text-danger" - onClick={() => onManage("delete")} - > - {t("timeline.manageItem.delete")} - </Dropdown.Item> - </Dropdown.Menu> - </Dropdown> - ) : ( - <Button variant="outline-primary" onClick={onMember}> - {t("timeline.memberButton")} - </Button> - )} - </div> </div> - </div> + <p className="mb-0">{timeline.description}</p> + <small className="mt-1 d-block"> + {t(timelineVisibilityTooltipTranslationMap[timeline.visibility])} + </small> + <div className="text-right mt-2"> + {onManage != null ? ( + <Dropdown> + <Dropdown.Toggle variant="outline-primary"> + {t("timeline.manage")} + </Dropdown.Toggle> + <Dropdown.Menu> + <Dropdown.Item onClick={() => onManage("property")}> + {t("timeline.manageItem.property")} + </Dropdown.Item> + <Dropdown.Item onClick={onMember}> + {t("timeline.manageItem.member")} + </Dropdown.Item> + <Dropdown.Divider /> + <Dropdown.Item + className="text-danger" + onClick={() => onManage("delete")} + > + {t("timeline.manageItem.delete")} + </Dropdown.Item> + </Dropdown.Menu> + </Dropdown> + ) : ( + <Button variant="outline-primary" onClick={onMember}> + {t("timeline.memberButton")} + </Button> + )} + </div> + </InfoCardTemplate> ); }; diff --git a/Timeline/ClientApp/src/app/views/user/UserInfoCard.tsx b/Timeline/ClientApp/src/app/views/user/UserInfoCard.tsx index ac3a1361..4cf11e62 100644 --- a/Timeline/ClientApp/src/app/views/user/UserInfoCard.tsx +++ b/Timeline/ClientApp/src/app/views/user/UserInfoCard.tsx @@ -1,5 +1,4 @@ import React from "react"; -import clsx from "clsx"; import { useTranslation } from "react-i18next"; import { Dropdown, Button } from "react-bootstrap"; @@ -8,8 +7,7 @@ import { useAvatar } from "@/services/user"; import BlobImage from "../common/BlobImage"; import { TimelineCardComponentProps } from "../timeline-common/TimelinePageTemplateUI"; -import SyncStatusBadge from "../timeline-common/SyncStatusBadge"; -import CollapseButton from "../timeline-common/CollapseButton"; +import InfoCardTemplate from "../timeline-common/InfoCardTemplate"; export type PersonalTimelineManageItem = "avatar" | "nickname"; @@ -31,53 +29,51 @@ const UserInfoCard: React.FC<UserInfoCardProps> = (props) => { const avatar = useAvatar(timeline?.owner?.username); return ( - <div className={clsx("cru-card p-2 clearfix", props.className)}> - <div className="float-right d-flex align-items-center"> - <SyncStatusBadge status={syncStatus} className="mr-2" /> - <CollapseButton collapse={collapse} onClick={toggleCollapse} /> - </div> - - <div style={{ display: collapse ? "none" : "block" }}> - <div> - <BlobImage blob={avatar} className="avatar" /> - {timeline.owner.nickname} - <small className="ml-3 text-secondary"> - @{timeline.owner.username} - </small> - </div> - <p className="mb-0">{timeline.description}</p> - <small className="mt-1 d-block"> - {t(timelineVisibilityTooltipTranslationMap[timeline.visibility])} + <InfoCardTemplate + className={props.className} + syncStatus={syncStatus} + collapse={collapse} + toggleCollapse={toggleCollapse} + > + <div> + <BlobImage blob={avatar} className="avatar" /> + {timeline.owner.nickname} + <small className="ml-3 text-secondary"> + @{timeline.owner.username} </small> - <div className="text-right mt-2"> - {onManage != null ? ( - <Dropdown> - <Dropdown.Toggle variant="outline-primary"> - {t("timeline.manage")} - </Dropdown.Toggle> - <Dropdown.Menu> - <Dropdown.Item onClick={() => onManage("nickname")}> - {t("timeline.manageItem.nickname")} - </Dropdown.Item> - <Dropdown.Item onClick={() => onManage("avatar")}> - {t("timeline.manageItem.avatar")} - </Dropdown.Item> - <Dropdown.Item onClick={() => onManage("property")}> - {t("timeline.manageItem.property")} - </Dropdown.Item> - <Dropdown.Item onClick={onMember}> - {t("timeline.manageItem.member")} - </Dropdown.Item> - </Dropdown.Menu> - </Dropdown> - ) : ( - <Button variant="outline-primary" onClick={onMember}> - {t("timeline.memberButton")} - </Button> - )} - </div> </div> - </div> + <p className="mb-0">{timeline.description}</p> + <small className="mt-1 d-block"> + {t(timelineVisibilityTooltipTranslationMap[timeline.visibility])} + </small> + <div className="text-right mt-2"> + {onManage != null ? ( + <Dropdown> + <Dropdown.Toggle variant="outline-primary"> + {t("timeline.manage")} + </Dropdown.Toggle> + <Dropdown.Menu> + <Dropdown.Item onClick={() => onManage("nickname")}> + {t("timeline.manageItem.nickname")} + </Dropdown.Item> + <Dropdown.Item onClick={() => onManage("avatar")}> + {t("timeline.manageItem.avatar")} + </Dropdown.Item> + <Dropdown.Item onClick={() => onManage("property")}> + {t("timeline.manageItem.property")} + </Dropdown.Item> + <Dropdown.Item onClick={onMember}> + {t("timeline.manageItem.member")} + </Dropdown.Item> + </Dropdown.Menu> + </Dropdown> + ) : ( + <Button variant="outline-primary" onClick={onMember}> + {t("timeline.memberButton")} + </Button> + )} + </div> + </InfoCardTemplate> ); }; |