Skip to content

Commit

Permalink
feat: Develop Activities Component (#142)
Browse files Browse the repository at this point in the history
Co-authored-by: dongwon8247 <[email protected]>
  • Loading branch information
juntaepark and dongwon8247 authored Jul 24, 2023
1 parent 854f4ff commit 5e4537e
Show file tree
Hide file tree
Showing 14 changed files with 695 additions and 65 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { fonts } from "@constants/font.constant";
import styled from "@emotion/styled";
import mixins from "@styles/mixins";

export const TokenInfoWrapper = styled.div`
${mixins.flexbox("row", "center", "flex-start")};
height: 66px;
width: 100%;
${fonts.body11};
&:not(:first-of-type) {
border-top: 1px solid ${({ theme }) => theme.color.border02};
}
`;

export const HoverSection = styled.div`
${mixins.flexbox("row", "center", "center", false)};
background-color: ${({ theme }) => theme.color.background01};
transition: background-color 0.3s ease;
cursor: pointer;
height: 100%;
overflow: hidden;
&:hover {
background-color: ${({ theme }) => theme.color.hover04};
}
`;

export const TableColumn = styled.div<{ tdWidth: number }>`
width: ${({ tdWidth }) => `${tdWidth}px`};
min-width: ${({ tdWidth }) => `${tdWidth}px`};
padding: 16px;
height: 100%;
color: ${({ theme }) => theme.color.text01};
${mixins.flexbox("row", "center", "flex-end")};
&.left {
flex-shrink: 0;
justify-content: flex-start;
}
.token-index {
${mixins.flexbox("row", "flex-start", "flex-start")};
gap: 4px;
${fonts.body11};
color: ${({ theme }) => theme.color.text02};
}
`;
export const IconButton = styled.button`
${mixins.flexbox("row", "center", "center")};
width: 16px;
height: 16px;
margin-top: 2px;
svg * {
fill: ${({ theme }) => theme.color.icon03};
}
:hover {
svg * {
fill: ${({ theme }) => theme.color.icon07};
}
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// TODO : remove eslint-disable after work
/* eslint-disable */
import React from "react";
import { MATH_NEGATIVE_TYPE } from "@constants/option.constant";
import { type Activity } from "@containers/dashboard-activities-container/DashboardActivitiesContainer";
import IconOpenLink from "@components/common/icons/IconOpenLink";
import {
HoverSection,
TableColumn,
TokenInfoWrapper,
IconButton,
} from "./ActivityInfo.styles";
import { ACTIVITY_TD_WIDTH } from "@constants/skeleton.constant";

interface ActivityInfoProps {
item: Activity;
idx: number;
}

const ActivityInfo: React.FC<ActivityInfoProps> = ({ item, idx }) => {
const { action, totalValue, tokenAmountOne, tokenAmountTwo, account, time } =
item;
return (
<TokenInfoWrapper>
<HoverSection>
<TableColumn className="left" tdWidth={ACTIVITY_TD_WIDTH[0]}>
<span className="token-index">
{action}
<IconButton
onClick={() => {
alert("open Link");
}}
>
<IconOpenLink className="action-icon" />
</IconButton>
</span>
</TableColumn>
<TableColumn className="right" tdWidth={ACTIVITY_TD_WIDTH[1]}>
<span className="token-index">{totalValue}</span>
</TableColumn>
<TableColumn className="right" tdWidth={ACTIVITY_TD_WIDTH[2]}>
<span className="token-index">{tokenAmountOne}</span>
</TableColumn>
<TableColumn className="right" tdWidth={ACTIVITY_TD_WIDTH[3]}>
<span className="token-index">{tokenAmountTwo}</span>
</TableColumn>
<TableColumn className="right" tdWidth={ACTIVITY_TD_WIDTH[4]}>
<span className="token-index">{account}</span>
</TableColumn>
<TableColumn className="right" tdWidth={ACTIVITY_TD_WIDTH[5]}>
<span className="token-index">{time}</span>
</TableColumn>
</HoverSection>
</TokenInfoWrapper>
);
};

export default ActivityInfo;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { fonts } from "@constants/font.constant";
import { css, Theme } from "@emotion/react";
import mixins from "@styles/mixins";

export const wrapper = (theme: Theme) => css`
${mixins.flexbox("row", "center", "flex-start")};
width: 100%;
h2 {
${fonts.h5};
color: ${theme.color.text02};
margin-right: 36px;
}
.tokens-search {
margin-left: auto;
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react";
import SelectTab from "@components/common/select-tab/SelectTab";
import { ACTIVITY_TYPE } from "@containers/dashboard-activities-container/DashboardActivitiesContainer";
import { wrapper } from "./ActivityListHeader.styles";

interface ActivityListHeaderProps {
activityType: ACTIVITY_TYPE;
changeActivityType: (newType: string) => void;
}

const ActivityListHeader: React.FC<ActivityListHeaderProps> = ({
activityType,
changeActivityType,
}) => (
<div css={wrapper}>
<h2>Activities</h2>
<SelectTab
selectType={activityType}
list={Object.values(ACTIVITY_TYPE)}
onClick={changeActivityType}
/>
</div>
);

export default ActivityListHeader;
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { fonts } from "@constants/font.constant";
import { css, Theme } from "@emotion/react";
import styled from "@emotion/styled";
import mixins from "@styles/mixins";

export const TableWrapper = styled.div`
${mixins.flexbox("column", "flex-start", "flex-start")};
width: 100%;
border: 1px solid ${({ theme }) => theme.color.border01};
border-radius: 8px;
margin: 24px 0px;
color: ${({ theme }) => theme.color.text04};
${fonts.body11};
overflow-x: auto;
.scroll-wrapper {
${mixins.flexbox("column", "flex-start", "flex-start")};
width: 100%;
}
.activity-list-head {
width: 100%;
${mixins.flexbox("row", "center", "flex-start")};
height: 49px;
${fonts.body12};
border-bottom: 1px solid ${({ theme }) => theme.color.border02};
}
.activity-list-body {
${mixins.flexbox("column", "flex-start", "center")};
width: 100%;
}
`;

export const TableHeader = styled.div<{ tdWidth: number }>`
width: ${({ tdWidth }) => `${tdWidth}px`};
height: 100%;
padding: 16px;
${mixins.flexbox("row", "center", "flex-end")};
&.left {
flex-shrink: 0;
justify-content: flex-start;
}
.index,
.name {
flex-shrink: 0;
justify-content: flex-start;
}
span {
display: inline-flex;
align-items: center;
white-space: pre;
}
&.left span {
flex-direction: row-reverse;
}
&.sort span {
cursor: pointer;
}
.icon {
width: 20px;
height: 20px;
align-items: center;
* {
fill: ${({ theme }) => theme.color.text04};
}
}
`;

export const noDataText = (theme: Theme) => css`
${mixins.flexbox("row", "center", "center")};
color: ${theme.color.text04};
${fonts.body12};
width: 100%;
height: 300px;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import React, { useCallback } from "react";
import {
SortOption,
TABLE_HEAD,
type Activity,
} from "@containers/dashboard-activities-container/DashboardActivitiesContainer";
import ActivityInfo from "@components/dashboard/activity-info/ActivityInfo";
import { cx } from "@emotion/css";
import TableSkeleton from "@components/common/table-skeleton/TableSkeleton";
import {
noDataText,
TableHeader,
TableWrapper,
} from "./ActivityListTable.styles";
import { ACTIVITY_INFO, ACTIVITY_TD_WIDTH } from "@constants/skeleton.constant";
import IconTriangleArrowDown from "@components/common/icons/IconTriangleArrowDown";
import IconTriangleArrowUp from "@components/common/icons/IconTriangleArrowUp";

interface ActivityListTableProps {
activities: Activity[];
isFetched: boolean;
isSortOption: (head: TABLE_HEAD) => boolean;
sortOption?: SortOption;
sort: (head: TABLE_HEAD) => void;
}

const ActivityListTable: React.FC<ActivityListTableProps> = ({
activities,
sortOption,
isSortOption,
sort,
isFetched,
}) => {
const isAscendingOption = useCallback(
(head: TABLE_HEAD) => {
return sortOption?.key === head && sortOption.direction === "asc";
},
[sortOption],
);

const isDescendingOption = useCallback(
(head: TABLE_HEAD) => {
return sortOption?.key === head && sortOption.direction === "desc";
},
[sortOption],
);

const onClickTableHead = (head: TABLE_HEAD) => {
if (!isSortOption(head)) {
return;
}
sort(head);
};

const isAlignLeft = (head: TABLE_HEAD) => {
return TABLE_HEAD.ACTION === head;
};

return (
<TableWrapper>
<div className="scroll-wrapper">
<div className="activity-list-head">
{Object.values(TABLE_HEAD).map((head, idx) => (
<TableHeader
key={idx}
className={cx({
left: isAlignLeft(head),
sort: isSortOption(head),
})}
tdWidth={ACTIVITY_TD_WIDTH[idx]}
>
<span
className={Object.keys(TABLE_HEAD)[idx].toLowerCase()}
onClick={() => onClickTableHead(head)}
>
{isAscendingOption(head) && (
<IconTriangleArrowUp className="icon asc" />
)}
{isDescendingOption(head) && (
<IconTriangleArrowDown className="icon desc" />
)}
{head}
</span>
</TableHeader>
))}
</div>
<div className="activity-list-body">
{isFetched && activities.length === 0 && (
<div css={noDataText}>No tokens found</div>
)}
{isFetched &&
activities.length > 0 &&
activities.map((item, idx) => (
<ActivityInfo item={item} idx={idx + 1} key={idx} />
))}
{!isFetched && <TableSkeleton info={ACTIVITY_INFO} />}
</div>
</div>
</TableWrapper>
);
};

export default ActivityListTable;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import styled from "@emotion/styled";
import mixins from "@styles/mixins";

export const ActivityListWrapper = styled.div`
${mixins.flexbox("column", "center", "center")};
width: 100%;
`;
Loading

0 comments on commit 5e4537e

Please sign in to comment.