Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a42c414
commit 2bd109a
Showing
4 changed files
with
262 additions
and
0 deletions.
There are no files selected for viewing
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,142 @@ | ||
import * as React from "react"; | ||
import { useState } from "react"; | ||
import styled from "styled-components"; | ||
import { ActivityType, IActivity } from "../../../types/activity"; | ||
import { borderRadius, transitionDuration } from "../config"; | ||
import { Nullable } from "../state"; | ||
import { IThemeProps } from "../theme"; | ||
import { dateToString } from "../util"; | ||
import { DiffEditor } from "./diff-editor"; | ||
|
||
const Container = styled.div` | ||
margin-bottom: 1rem; | ||
`; | ||
|
||
interface IBodyProps { | ||
shown: boolean; | ||
} | ||
|
||
const Body = styled.div<IBodyProps>` | ||
opacity: 0; | ||
padding: 0rem 1rem; | ||
height: 0rem; | ||
overflow: hidden; | ||
${({ shown }) => shown && ` | ||
opacity: 1; | ||
height: calc(40vh + 2rem); | ||
padding: 1rem; | ||
`} | ||
border-radius: ${borderRadius}; | ||
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.05); | ||
transition-property: height, opacity, padding; | ||
transition-duration: ${transitionDuration}; | ||
`; | ||
|
||
interface ITitleProps { | ||
clickable: boolean; | ||
} | ||
|
||
const Title = styled.h3<ITitleProps>` | ||
margin: 0rem; | ||
font-weight: normal; | ||
font-size: 0.9rem; | ||
${({ clickable }) => clickable && ` | ||
cursor: pointer; | ||
`} | ||
`; | ||
|
||
const Accent = styled.span` | ||
color: ${({ theme }: IThemeProps) => theme.colorGradientEnd}; | ||
`; | ||
|
||
const Time = styled.div` | ||
margin-bottom: 1rem; | ||
font-size: 0.75; | ||
opacity: 0.5; | ||
`; | ||
|
||
interface IClickIndicatorProps { | ||
clicked: boolean; | ||
} | ||
|
||
const ClickIndicator = styled.button<IClickIndicatorProps>` | ||
display: inline-block; | ||
margin: 0rem 0.5rem; | ||
border: none; | ||
color: currentColor; | ||
background-color: transparent; | ||
cursor: pointer; | ||
transition-property: transform; | ||
transition-duration: ${transitionDuration}; | ||
${({ clicked }) => clicked && ` | ||
transform: rotateZ(90deg); | ||
`} | ||
`; | ||
|
||
const getActivityText = (type: ActivityType) => { | ||
switch (type) { | ||
case ActivityType.Signup: | ||
return "Signup"; | ||
|
||
case ActivityType.EmailVerified: | ||
return "E-mail verified"; | ||
|
||
case ActivityType.SettingsUpdate: | ||
return "Settings updated"; | ||
} | ||
}; | ||
|
||
interface IActivityEventProps { | ||
event: IActivity; | ||
} | ||
|
||
/** | ||
* An activity event. | ||
*/ | ||
export const ActivityEvent = ({ event }: IActivityEventProps) => { | ||
const [showBody, setShowBody] = useState(false); | ||
let body: Nullable<JSX.Element> = null; | ||
|
||
switch (event.data.type) { | ||
case ActivityType.SettingsUpdate: | ||
body = ( | ||
<DiffEditor | ||
language="json" | ||
left={event.data.previous} | ||
right={event.data.next} | ||
/> | ||
); | ||
break; | ||
} | ||
|
||
return ( | ||
<Container> | ||
<Title | ||
onClick={() => setShowBody((value) => !value)} | ||
clickable={!!body} | ||
> | ||
{getActivityText(event.data.type)} by <Accent>{event.user.email}</Accent> | ||
|
||
{body && ( | ||
<ClickIndicator clicked={showBody}>►</ClickIndicator> | ||
)} | ||
</Title> | ||
|
||
<Time> | ||
{dateToString(new Date(event.timestamp))} | ||
</Time> | ||
|
||
{body && ( | ||
<Body shown={showBody}> | ||
{body} | ||
</Body> | ||
)} | ||
</Container> | ||
); | ||
}; |
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,70 @@ | ||
import * as React from "react"; | ||
import { useEffect } from "react"; | ||
import { connect } from "react-redux"; | ||
import { bindActionCreators, Dispatch } from "redux"; | ||
import { IActivity } from "../../../types/activity"; | ||
import { fetchActivities } from "../actions/activity"; | ||
import { IState } from "../state"; | ||
import { groupByMonth } from "../util"; | ||
import { ActivityEvent } from "./activity-event"; | ||
import { Heading, Subheading } from "./headings"; | ||
import { Placeholder } from "./placeholder"; | ||
|
||
interface IActivityProps { | ||
activity: IActivity[] | null; | ||
dispatchFetchActivities: typeof fetchActivities; | ||
} | ||
|
||
/** | ||
* An overview over activities in tilt. | ||
*/ | ||
export const Activity = ({ activity, dispatchFetchActivities }: IActivityProps) => { | ||
useEffect(() => { | ||
if (!activity) { | ||
dispatchFetchActivities(); | ||
} | ||
}, []); | ||
|
||
const descendingActivities = (activity || []).sort((a, b) => b.timestamp - a.timestamp); | ||
const activityByMonth = | ||
groupByMonth(descendingActivities) | ||
.map(({ month, data }) => ( | ||
<> | ||
<Subheading>{month}</Subheading> | ||
{data.map((event) => ( | ||
<ActivityEvent event={event} /> | ||
))} | ||
</> | ||
)); | ||
|
||
return ( | ||
<> | ||
<Heading>Activity</Heading> | ||
|
||
{!activity && ( | ||
<> | ||
<Placeholder width="200px" height="0.7rem" /> | ||
<br /> | ||
<Placeholder width="100%" height="2rem" /> | ||
</> | ||
)} | ||
|
||
{activityByMonth} | ||
</> | ||
); | ||
}; | ||
|
||
const mapStateToProps = (state: IState) => ({ | ||
activity: state.activity, | ||
}); | ||
|
||
const mapDispatchToProps = (dispatch: Dispatch) => { | ||
return bindActionCreators({ | ||
dispatchFetchActivities: fetchActivities, | ||
}, dispatch); | ||
}; | ||
|
||
/** | ||
* The activity component connected to the redux store. | ||
*/ | ||
export const ConnectedActivity = connect(mapStateToProps, mapDispatchToProps)(Activity); |
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
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