Web: Components: filling-status-line
This commit is contained in:
parent
840ddd80c5
commit
b5f0b25515
@ -1,211 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import ArrowReactSvgUrl from "PUBLIC_DIR/images/arrow.react.svg?url";
|
||||
|
||||
import IconButton from "../icon-button";
|
||||
import Text from "../text";
|
||||
import Box from "../box";
|
||||
import Avatar from "../avatar";
|
||||
|
||||
const AccordionItem = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
const AccordionItemInfo = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
height: 38px;
|
||||
padding: 18px 0;
|
||||
|
||||
.user-avatar {
|
||||
padding 1px;
|
||||
border: 2px solid ${(props) => (props.finished ? "#4781D1" : "#A3A9AE")};
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.icon-button-rotate {
|
||||
path {
|
||||
fill: #4781d1;
|
||||
}
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
`;
|
||||
|
||||
const AccordionItemHistory = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 15px;
|
||||
`;
|
||||
|
||||
const AccordionItemDetailHistory = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 15px;
|
||||
`;
|
||||
|
||||
const ItemWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-left: 2px ${(props) => (props.finished ? "solid" : "dashed")};
|
||||
border-color: ${(props) => (props.finished ? "#4781D1" : "#A3A9AE")};
|
||||
min-height: 40px;
|
||||
margin: ${(props) => (props.finished ? "0" : "2px 0")};
|
||||
|
||||
.filled-status-text {
|
||||
color: ${(props) => (props.finished ? "#4781D1" : "#657077")};
|
||||
}
|
||||
`;
|
||||
|
||||
const Accordion = ({
|
||||
avatar,
|
||||
displayName,
|
||||
role,
|
||||
startFillingStatus,
|
||||
startFillingDate,
|
||||
filledAndSignedStatus,
|
||||
filledAndSignedDate,
|
||||
returnedByUser,
|
||||
returnedByUserDate,
|
||||
comment,
|
||||
finished,
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<AccordionItem>
|
||||
<AccordionItemInfo finished={finished} onClick={() => setIsOpen(!isOpen)}>
|
||||
<Box displayProp="flex" alignItems="center">
|
||||
<Avatar
|
||||
className="user-avatar"
|
||||
size="min"
|
||||
role="user"
|
||||
source={avatar}
|
||||
userName={displayName}
|
||||
/>
|
||||
|
||||
<Box
|
||||
displayProp="flex"
|
||||
flexDirection="column"
|
||||
marginProp="0 0 0 10px"
|
||||
>
|
||||
<Text
|
||||
className="accordion-displayname"
|
||||
fontSize="14px"
|
||||
color="#333333"
|
||||
lineHeight="16px"
|
||||
fontWeight="bold"
|
||||
>
|
||||
{displayName}
|
||||
</Text>
|
||||
<Text
|
||||
as="span"
|
||||
className="accordion-role"
|
||||
fontSize="12px"
|
||||
color="#657077"
|
||||
lineHeight="16px"
|
||||
>
|
||||
{role}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
<IconButton
|
||||
className={isOpen ? "icon-button-rotate" : "icon-button"}
|
||||
size={16}
|
||||
iconName={ArrowReactSvgUrl}
|
||||
/>
|
||||
</AccordionItemInfo>
|
||||
|
||||
<AccordionItemHistory>
|
||||
<ItemWrapper finished={finished}>
|
||||
<Text
|
||||
fontSize="12px"
|
||||
lineHeight="16px"
|
||||
className="filled-status-text"
|
||||
style={{ marginLeft: "15px" }}
|
||||
>
|
||||
{filledAndSignedStatus}
|
||||
</Text>
|
||||
</ItemWrapper>
|
||||
|
||||
<Text fontSize="12px" lineHeight="16px" color="#657077">
|
||||
{filledAndSignedDate}
|
||||
</Text>
|
||||
</AccordionItemHistory>
|
||||
|
||||
{isOpen && (
|
||||
<>
|
||||
<AccordionItemDetailHistory>
|
||||
<ItemWrapper finished={finished}>
|
||||
<Text
|
||||
fontSize="12px"
|
||||
lineHeight="16px"
|
||||
color="#657077"
|
||||
className="status-text"
|
||||
style={{ marginLeft: "15px" }}
|
||||
>
|
||||
{startFillingStatus}
|
||||
</Text>
|
||||
</ItemWrapper>
|
||||
|
||||
<Text fontSize="12px" lineHeight="16px" color="#657077">
|
||||
{startFillingDate}
|
||||
</Text>
|
||||
</AccordionItemDetailHistory>
|
||||
|
||||
{returnedByUser && (
|
||||
<AccordionItemDetailHistory>
|
||||
<ItemWrapper finished={finished}>
|
||||
<Text
|
||||
fontSize="12px"
|
||||
lineHeight="16px"
|
||||
color="#657077"
|
||||
className="status-text"
|
||||
style={{ marginLeft: "15px" }}
|
||||
>
|
||||
{returnedByUser}
|
||||
</Text>
|
||||
</ItemWrapper>
|
||||
|
||||
<Text fontSize="12px" lineHeight="16px" color="#657077">
|
||||
{returnedByUserDate}
|
||||
</Text>
|
||||
</AccordionItemDetailHistory>
|
||||
)}
|
||||
|
||||
{comment && (
|
||||
<AccordionItemDetailHistory>
|
||||
<ItemWrapper finished={finished}>
|
||||
<Text
|
||||
fontSize="12px"
|
||||
lineHeight="16px"
|
||||
color="#657077"
|
||||
className="status-text"
|
||||
style={{ marginLeft: "15px" }}
|
||||
>
|
||||
{comment}
|
||||
</Text>
|
||||
</ItemWrapper>
|
||||
</AccordionItemDetailHistory>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</AccordionItem>
|
||||
);
|
||||
};
|
||||
export default Accordion;
|
@ -0,0 +1,148 @@
|
||||
import React, { useState } from "react";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import { AccordionItem } from "./styled-filling-status-line";
|
||||
|
||||
import ArrowReactSvgUrl from "PUBLIC_DIR/images/arrow.react.svg?url";
|
||||
import Text from "../text";
|
||||
import Box from "../box";
|
||||
import Avatar from "../avatar";
|
||||
|
||||
const FillingStatusAccordion = ({
|
||||
avatar,
|
||||
displayName,
|
||||
role,
|
||||
startFilling,
|
||||
startFillingDate,
|
||||
filledAndSigned,
|
||||
filledAndSignedDate,
|
||||
returnedByUser,
|
||||
returnedDate,
|
||||
comment,
|
||||
isDone,
|
||||
isInterrupted,
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const onClickHandler = () => {
|
||||
setIsOpen((prev) => !prev);
|
||||
};
|
||||
|
||||
return (
|
||||
<AccordionItem
|
||||
isOpen={isOpen}
|
||||
isDone={isDone}
|
||||
isInterrupted={isInterrupted}
|
||||
>
|
||||
<div className="accordion-item-info" onClick={onClickHandler}>
|
||||
<Box displayProp="flex" alignItems="center">
|
||||
<Avatar
|
||||
className="user-avatar"
|
||||
size="min"
|
||||
role="user"
|
||||
source={avatar}
|
||||
userName={displayName}
|
||||
/>
|
||||
|
||||
<Box
|
||||
displayProp="flex"
|
||||
flexDirection="column"
|
||||
marginProp="0 0 0 10px"
|
||||
>
|
||||
<Text
|
||||
className="accordion-displayname"
|
||||
fontSize="14px"
|
||||
lineHeight="16px"
|
||||
fontWeight="bold"
|
||||
>
|
||||
{displayName}
|
||||
</Text>
|
||||
<Text
|
||||
as="span"
|
||||
className="accordion-role"
|
||||
fontSize="12px"
|
||||
lineHeight="16px"
|
||||
>
|
||||
{role}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
<ReactSVG src={ArrowReactSvgUrl} className="arrow-icon" />
|
||||
</div>
|
||||
|
||||
{isOpen ? (
|
||||
<>
|
||||
<div className="accordion-item-history">
|
||||
<div className="accordion-item-wrapper">
|
||||
<Text fontSize="12px" lineHeight="16px" className="status-text">
|
||||
{startFilling}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Text fontSize="12px" lineHeight="16px" className="status-date">
|
||||
{startFillingDate}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
{returnedByUser && (
|
||||
<div className="accordion-item-history">
|
||||
<div className="accordion-item-wrapper">
|
||||
<Text fontSize="12px" lineHeight="16px" className="status-text">
|
||||
{returnedByUser}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Text fontSize="12px" lineHeight="16px" className="status-date">
|
||||
{returnedDate}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{comment && (
|
||||
<div className="accordion-item-history">
|
||||
<div className="accordion-item-wrapper">
|
||||
<Text fontSize="12px" lineHeight="16px" className="status-text">
|
||||
{comment}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isDone && (
|
||||
<div className="accordion-item-history">
|
||||
<div className="accordion-item-wrapper">
|
||||
<Text
|
||||
fontSize="12px"
|
||||
lineHeight="16px"
|
||||
className="filled-status-text"
|
||||
>
|
||||
{filledAndSigned}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Text fontSize="12px" lineHeight="16px" className="status-date">
|
||||
{filledAndSignedDate}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="accordion-item-history">
|
||||
<div className="accordion-item-wrapper">
|
||||
<Text
|
||||
fontSize="12px"
|
||||
lineHeight="16px"
|
||||
className="filled-status-text"
|
||||
>
|
||||
{filledAndSigned}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Text fontSize="12px" lineHeight="16px" className="status-date">
|
||||
{filledAndSignedDate}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
</AccordionItem>
|
||||
);
|
||||
};
|
||||
export default FillingStatusAccordion;
|
@ -1,46 +1,97 @@
|
||||
import React from "react";
|
||||
import Accordion from "./accordion.js";
|
||||
import PropTypes from "prop-types";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import { mockData } from "./mockData.js";
|
||||
import { FillingStatusContainer } from "./styled-filling-status-line.js";
|
||||
import FillingStatusAccordion from "./filling-status-accordion.js";
|
||||
import StatusDoneReactSvgUrl from "PUBLIC_DIR/images/done.react.svg?url";
|
||||
import StatusInterruptedSvgUrl from "PUBLIC_DIR/images/interrupted.react.svg?url";
|
||||
|
||||
import DoneReactSvg from "PUBLIC_DIR/images/done.react.svg";
|
||||
import { StyledFillingStatusContainer } from "./styled-filling-status-line.js";
|
||||
import Text from "../text";
|
||||
import Box from "../box";
|
||||
import { Data } from "./data.js";
|
||||
|
||||
const FillingStatusLine = () => {
|
||||
const FillingStatusLine = ({
|
||||
statusDoneText,
|
||||
statusInterruptedText,
|
||||
statusDone,
|
||||
statusInterrupted,
|
||||
}) => {
|
||||
return (
|
||||
<StyledFillingStatusContainer>
|
||||
{Data.map((data) => {
|
||||
<FillingStatusContainer
|
||||
isDone={statusDone}
|
||||
isInterrupted={statusInterrupted}
|
||||
>
|
||||
{mockData.map((data) => {
|
||||
return (
|
||||
<Accordion
|
||||
<FillingStatusAccordion
|
||||
key={data.id}
|
||||
displayName={data.displayName}
|
||||
avatar={data.avatar}
|
||||
role={data.role}
|
||||
startFillingStatus={data.startFillingStatus}
|
||||
startFilling={data.startFillingStatus}
|
||||
startFillingDate={data.startFillingDate}
|
||||
filledAndSignedStatus={data.filledAndSignedStatus}
|
||||
filledAndSigned={data.filledAndSignedStatus}
|
||||
filledAndSignedDate={data.filledAndSignedDate}
|
||||
returnedByUser={data.returnedByUser}
|
||||
returnedByUserDate={data.returnedByUserDate}
|
||||
returnedDate={data.returnedByUserDate}
|
||||
comment={data.comment}
|
||||
avatar={data.avatar}
|
||||
finished={data.finished}
|
||||
isDone={statusDone}
|
||||
isInterrupted={statusInterrupted}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<Box displayProp="flex" alignItems="center" marginProp="15px 0 0">
|
||||
<DoneReactSvg className="done-icon" />
|
||||
<Text
|
||||
fontSize="14px"
|
||||
lineHeight="16px"
|
||||
color="#A3A9AE"
|
||||
fontWeight="bold"
|
||||
>
|
||||
Done
|
||||
</Text>
|
||||
</Box>
|
||||
</StyledFillingStatusContainer>
|
||||
{statusInterrupted ? (
|
||||
<Box displayProp="flex" alignItems="center" marginProp="15px 0 0">
|
||||
<ReactSVG
|
||||
src={StatusInterruptedSvgUrl}
|
||||
className="status-interrupted-icon"
|
||||
/>
|
||||
<Text
|
||||
fontSize="14px"
|
||||
lineHeight="16px"
|
||||
fontWeight="bold"
|
||||
className="status-interrupted-text"
|
||||
>
|
||||
{statusInterruptedText}
|
||||
</Text>
|
||||
</Box>
|
||||
) : (
|
||||
<Box displayProp="flex" alignItems="center" marginProp="15px 0 0">
|
||||
<ReactSVG src={StatusDoneReactSvgUrl} className="status-done-icon" />
|
||||
<Text
|
||||
fontSize="14px"
|
||||
lineHeight="16px"
|
||||
fontWeight="bold"
|
||||
className="status-done-text"
|
||||
>
|
||||
{statusDoneText}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</FillingStatusContainer>
|
||||
);
|
||||
};
|
||||
|
||||
FillingStatusLine.propTypes = {
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
/** Accepts class */
|
||||
className: PropTypes.string,
|
||||
/** Filling status done text*/
|
||||
statusDoneText: PropTypes.string,
|
||||
/** Filling status interrupted text*/
|
||||
statusInterruptedText: PropTypes.string,
|
||||
/** Filling status done*/
|
||||
statusDone: PropTypes.bool,
|
||||
/** Filling status interrupted*/
|
||||
statusInterrupted: PropTypes.bool,
|
||||
};
|
||||
|
||||
FillingStatusLine.defaultProps = {
|
||||
statusDoneText: "Done",
|
||||
statusInterruptedText: "Interrupted",
|
||||
statusDone: true,
|
||||
statusInterrupted: false,
|
||||
};
|
||||
|
||||
export default FillingStatusLine;
|
||||
|
@ -1,4 +1,4 @@
|
||||
export const Data = [
|
||||
export const mockData = [
|
||||
{
|
||||
id: 0,
|
||||
displayName: "Lydia Calzoni",
|
||||
@ -9,10 +9,8 @@ export const Data = [
|
||||
filledAndSignedDate: "26.01.2023 13:56",
|
||||
returnedByUser: "Returned by Teacher",
|
||||
returnedByUserDate: "25.01.2023 13:56",
|
||||
comment:
|
||||
"The registration block is filled in incorrectly. It is necessary to specify the user ID, and the email is specified. The user ID can be viewed on the profile page.",
|
||||
comment: "The registration block is filled in incorrectly. It is necessary to specify the user ID, and the email is specified. The user ID can be viewed on the profile page.",
|
||||
avatar: null,
|
||||
finished: true,
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
@ -26,7 +24,6 @@ export const Data = [
|
||||
returnedByUserDate: "22.01.2023 13:56",
|
||||
comment: null,
|
||||
avatar: null,
|
||||
finished: true,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
@ -40,6 +37,5 @@ export const Data = [
|
||||
returnedByUserDate: null,
|
||||
comment: null,
|
||||
avatar: null,
|
||||
finished: false,
|
||||
},
|
||||
];
|
@ -1,13 +1,105 @@
|
||||
import styled from "styled-components";
|
||||
|
||||
export const StyledFillingStatusContainer = styled.div`
|
||||
const FillingStatusContainer = styled.div`
|
||||
width: 100%;
|
||||
max-width: 425px;
|
||||
padding: 10px;
|
||||
|
||||
.done-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
.status-done-text {
|
||||
color: ${(props) => (props.isDone ? "#4781D1" : "#A3A9AE")};
|
||||
}
|
||||
|
||||
.status-done-icon {
|
||||
circle,
|
||||
path {
|
||||
stroke: ${(props) => (props.isDone ? "#4781D1" : "#A3A9AE")};
|
||||
}
|
||||
}
|
||||
|
||||
.status-interrupted-text {
|
||||
color: ${(props) => props.isInterrupted && "#F2675A"};
|
||||
}
|
||||
|
||||
.status-interrupted-icon {
|
||||
circle,
|
||||
path {
|
||||
stroke: ${(props) => props.isInterrupted && "#F2675A"};
|
||||
}
|
||||
}
|
||||
|
||||
.status-done-icon,
|
||||
.status-interrupted-icon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
`;
|
||||
|
||||
const AccordionItem = styled.div`
|
||||
width: 100%;
|
||||
|
||||
.accordion-item-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
height: 38px;
|
||||
padding: 18px 0;
|
||||
|
||||
.user-avatar {
|
||||
padding 1px;
|
||||
border: 2px solid #A3A9AE;
|
||||
border-color: ${(props) => (props.isDone && "#4781D1") || (props.isInterrupted && "#F2675A")};
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.accordion-displayname {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.accordion-role {
|
||||
color: #657077;
|
||||
}
|
||||
|
||||
.arrow-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transform: ${(props) => props.isOpen ? "rotate(270deg)" : "rotate(90deg)"};
|
||||
path {
|
||||
fill: ${(props) => (props.isOpen ? "#4781d1" : "#A3A9AE")};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.accordion-item-history {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.accordion-item-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 40px;
|
||||
margin: ${(props) => (props.isDone || props.isInterrupted ? "0" : "2px 0")};
|
||||
border-left: 2px ${(props) => props.isDone || props.isInterrupted ? "solid" : "dashed"} #A3A9AE;
|
||||
border-color: ${(props) => (props.isDone && "#4781D1") || (props.isInterrupted && "#F2675A")};
|
||||
|
||||
.status-text {
|
||||
margin-left: 15px;
|
||||
color: #657077;
|
||||
}
|
||||
|
||||
.status-date {
|
||||
color: #657077;
|
||||
}
|
||||
|
||||
.filled-status-text {
|
||||
margin-left: 15px;
|
||||
color: ${(props) => (props.isDone ? "#4781D1" : "#657077")};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export { FillingStatusContainer, AccordionItem };
|
||||
|
4
public/images/interrupted.react.svg
Normal file
4
public/images/interrupted.react.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="19" cy="19" r="18" stroke="#F2675A" stroke-width="2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.2929 13.2929C23.6834 12.9024 24.3166 12.9024 24.7071 13.2929C25.0976 13.6834 25.0976 14.3166 24.7071 14.7071L20.4142 19L24.7071 23.2929C25.0976 23.6834 25.0976 24.3166 24.7071 24.7071C24.3166 25.0976 23.6834 25.0976 23.2929 24.7071L19 20.4142L14.7071 24.7071C14.3166 25.0976 13.6834 25.0976 13.2929 24.7071C12.9024 24.3166 12.9024 23.6834 13.2929 23.2929L17.5858 19L13.2929 14.7071C12.9024 14.3166 12.9024 13.6834 13.2929 13.2929C13.6834 12.9024 14.3166 12.9024 14.7071 13.2929L19 17.5858L23.2929 13.2929Z" fill="#F2675A"/>
|
||||
</svg>
|
After Width: | Height: | Size: 747 B |
Loading…
Reference in New Issue
Block a user