Skip to content

Commit e6c87a3

Browse files
authored
Merge pull request #18 from toggle-corp/feature/add-conductor-in-standup
Add standup conductors
2 parents ad5beed + e7946d5 commit e6c87a3

File tree

18 files changed

+346
-65
lines changed

18 files changed

+346
-65
lines changed

src/App/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const ME_QUERY = gql`
5757
id
5858
lastName
5959
isStaff
60+
loginExpire
6061
}
6162
}
6263
}

src/components/Clock/index.tsx

Lines changed: 0 additions & 52 deletions
This file was deleted.

src/components/Navbar/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ function Navbar(props: Props) {
102102
{isNotDefined(userAuth) && (
103103
<Link
104104
external
105-
href={`${import.meta.env.APP_GRAPHQL_DOMAIN}/dev/sign_in/?redirect_to=${window.location.href}`}
105+
href={`${import.meta.env.APP_GRAPHQL_DOMAIN}/?redirect_to=${window.location.href}`}
106106
>
107107
Login
108108
</Link>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import {
2+
_cs,
3+
encodeDate,
4+
} from '@togglecorp/fujs';
5+
import {
6+
gql,
7+
useQuery,
8+
} from 'urql';
9+
10+
import DisplayPicture from '#components/DisplayPicture';
11+
import TextOutput from '#components/TextOutput';
12+
import {
13+
type StandupConductorsQuery,
14+
type StandupConductorsQueryVariables,
15+
} from '#generated/types/graphql';
16+
17+
import styles from './styles.module.css';
18+
19+
const STANDUP_CONDUCTORS = gql`
20+
query StandupConductors($date: Date!){
21+
private {
22+
dailyStandup(date: $date) {
23+
conductor {
24+
id
25+
displayName
26+
displayPicture
27+
}
28+
fallbackConductor {
29+
id
30+
displayName
31+
displayPicture
32+
}
33+
}
34+
}
35+
}
36+
`;
37+
38+
const todayDate = encodeDate(new Date());
39+
40+
function StandupConductors() {
41+
const [conductorsResponse] = useQuery<StandupConductorsQuery, StandupConductorsQueryVariables>({
42+
query: STANDUP_CONDUCTORS,
43+
variables: { date: todayDate },
44+
requestPolicy: 'cache-and-network',
45+
});
46+
47+
const standupConductors = conductorsResponse.data?.private.dailyStandup;
48+
49+
return (
50+
<div className={styles.conductors}>
51+
<TextOutput
52+
className={_cs(
53+
styles.conductorItem,
54+
!standupConductors && styles.hidden,
55+
)}
56+
label="Standup Lead"
57+
valueContainerClassName={styles.conductorValue}
58+
value={(
59+
<>
60+
<DisplayPicture
61+
imageUrl={standupConductors?.conductor?.displayPicture}
62+
displayName={standupConductors?.conductor?.displayName ?? 'Anonymous'}
63+
/>
64+
<span>
65+
{standupConductors?.conductor?.displayName
66+
?? 'Anonymous'}
67+
</span>
68+
</>
69+
)}
70+
block
71+
hideLabelColon
72+
/>
73+
<TextOutput
74+
className={_cs(
75+
styles.conductorItem,
76+
!standupConductors && styles.hidden,
77+
)}
78+
label="Acting Lead"
79+
valueContainerClassName={styles.conductorValue}
80+
value={(
81+
<>
82+
<DisplayPicture
83+
imageUrl={standupConductors
84+
?.fallbackConductor?.displayPicture}
85+
displayName={standupConductors?.fallbackConductor?.displayName ?? 'Anonymous'}
86+
/>
87+
<span>
88+
{standupConductors?.fallbackConductor?.displayName
89+
?? 'Anonymous'}
90+
</span>
91+
</>
92+
)}
93+
block
94+
hideLabelColon
95+
/>
96+
</div>
97+
);
98+
}
99+
100+
export default StandupConductors;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.conductors {
2+
display: flex;
3+
flex-direction: column;
4+
gap: var(--spacing-md);
5+
6+
.conductor-item {
7+
display: flex;
8+
justify-content: center;
9+
gap: var(--spacing-xs);
10+
11+
&.hidden {
12+
visibility: hidden;
13+
}
14+
15+
.conductor-value {
16+
display: flex;
17+
align-items: center;
18+
justify-content: center;
19+
font-size: var(--font-size-lg);
20+
font-weight: var(--font-weight-normal);
21+
gap: var(--spacing-xs);
22+
}
23+
}
24+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React from 'react';
2+
import { _cs } from '@togglecorp/fujs';
3+
4+
import styles from './styles.module.css';
5+
6+
interface Props {
7+
className?: string;
8+
label?: React.ReactNode;
9+
labelContainerClassName?: string;
10+
description?: React.ReactNode;
11+
descriptionContainerClassName?: string;
12+
valueContainerClassName?: string;
13+
hideLabelColon?: boolean;
14+
block?: boolean;
15+
value?: React.ReactNode;
16+
}
17+
18+
function TextOutput(props: Props) {
19+
const {
20+
className,
21+
label,
22+
labelContainerClassName,
23+
valueContainerClassName,
24+
description,
25+
descriptionContainerClassName,
26+
hideLabelColon,
27+
block,
28+
value,
29+
} = props;
30+
31+
return (
32+
<div
33+
className={_cs(
34+
styles.textOutput,
35+
!hideLabelColon && styles.withLabelColon,
36+
// NOTE:
37+
// styles.blok is supposed to be styles.block
38+
// but we encountered a strange behavior
39+
block && styles.blok,
40+
className,
41+
)}
42+
>
43+
{label && (
44+
<div className={_cs(styles.label, labelContainerClassName)}>
45+
{label}
46+
</div>
47+
)}
48+
<div className={_cs(styles.value, valueContainerClassName)}>
49+
{value}
50+
</div>
51+
{description && (
52+
<div className={_cs(styles.description, descriptionContainerClassName)}>
53+
{description}
54+
</div>
55+
)}
56+
</div>
57+
);
58+
}
59+
60+
export default TextOutput;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
.text-output {
2+
--spacing: var(--spacing-md);
3+
display: flex;
4+
align-items: baseline;
5+
font-size: var(--font-size-md);
6+
gap: var(--spacing-sm);
7+
8+
&.blok {
9+
align-items: initial;
10+
flex-direction: column;
11+
}
12+
13+
>.label {
14+
color: var(--color-text);
15+
}
16+
17+
>.value {
18+
font-weight: var(--font-weight-bold);
19+
20+
/* Useful for nested text outputs */
21+
.text-output {
22+
font-weight: var(--font-weight-semibold);
23+
}
24+
}
25+
26+
>.description {
27+
color: var(--color-text-light);
28+
}
29+
30+
&.with-label-colon {
31+
>.label {
32+
&:after {
33+
content: ':';
34+
}
35+
}
36+
}
37+
}

src/contexts/user.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { UserMeType } from '#generated/types/graphql';
44

55
export type UserAuth = Pick<
66
UserMeType,
7-
'displayName' | 'displayPicture' | 'email' | 'firstName' | 'id' | 'lastName' | 'isStaff'
7+
'displayName' | 'displayPicture' | 'email' | 'firstName' | 'id' | 'lastName' | 'isStaff' | 'loginExpire'
88
>;
99

1010
export interface UserContextProps {

src/hooks/useCurrentDate.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {
2+
useEffect,
3+
useState,
4+
} from 'react';
5+
6+
function useCurrentDate() {
7+
const [dateStr, setDateStr] = useState(() => {
8+
const date = new Date();
9+
return date;
10+
});
11+
12+
useEffect(
13+
() => {
14+
const timeout = window.setInterval(
15+
() => {
16+
const date = new Date();
17+
setDateStr(date);
18+
},
19+
5000,
20+
);
21+
return () => {
22+
window.clearInterval(timeout);
23+
};
24+
},
25+
[],
26+
);
27+
return dateStr;
28+
}
29+
30+
export default useCurrentDate;

0 commit comments

Comments
 (0)