Dwayne Harris
5 years ago
13 changed files with 234 additions and 52 deletions
-
50src/actions/directory.ts
-
4src/api/errors.ts
-
39src/components/group-logs/group-logs.tsx
-
26src/components/group-logs/index.tsx
-
35src/components/member-list/index.tsx
-
25src/components/member-list/member-list.tsx
-
58src/components/pages/group-admin/group-admin.tsx
-
14src/components/pages/group-admin/index.ts
-
11src/components/pages/loading/index.tsx
-
6src/selectors/directory.ts
-
9src/store/schemas.ts
-
7src/types/entities.ts
-
2src/types/store.ts
@ -0,0 +1,39 @@ |
|||
import React, { FC, useEffect } from 'react' |
|||
import noop from 'lodash/noop' |
|||
import moment from 'moment' |
|||
import { GroupLog } from 'src/types' |
|||
|
|||
export interface Props { |
|||
group: string |
|||
logs?: GroupLog[] |
|||
fetchLogs?: () => void |
|||
} |
|||
|
|||
const MemberList: FC<Props> = ({ group, logs = [], fetchLogs = noop }) => { |
|||
useEffect(() => { |
|||
if (logs.length === 0) fetchLogs() |
|||
}, [group]) |
|||
|
|||
return ( |
|||
<table className="table"> |
|||
<thead> |
|||
<tr> |
|||
<th>Who</th> |
|||
<th>What</th> |
|||
<th>When</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
{logs.map(log => ( |
|||
<tr> |
|||
<td>{log.user.id}</td> |
|||
<td>{log.content}</td> |
|||
<td>{moment(log.created).format('MMMM Do YYYY, h:mm:ss a')}</td> |
|||
</tr> |
|||
))} |
|||
</tbody> |
|||
</table> |
|||
) |
|||
} |
|||
|
|||
export default MemberList |
@ -0,0 +1,26 @@ |
|||
import { connect } from 'react-redux' |
|||
import { handleApiError } from 'src/api/errors' |
|||
import { fetchLogs } from 'src/actions/directory' |
|||
import { getLogs } from 'src/selectors/directory' |
|||
import { AppState, AppThunkDispatch } from 'src/types' |
|||
|
|||
import GroupLogs, { Props } from './group-logs' |
|||
|
|||
const mapStateToProps = (state: AppState) => ({ |
|||
logs: getLogs(state), |
|||
}) |
|||
|
|||
const mapDispatchToProps = (dispatch: AppThunkDispatch, ownProps: Props) => ({ |
|||
fetchLogs: () => { |
|||
try { |
|||
dispatch(fetchLogs(ownProps.group)) |
|||
} catch (err) { |
|||
handleApiError(err, dispatch) |
|||
} |
|||
}, |
|||
}) |
|||
|
|||
export default connect( |
|||
mapStateToProps, |
|||
mapDispatchToProps |
|||
)(GroupLogs) |
@ -1,17 +1,26 @@ |
|||
import React, { FC } from 'react' |
|||
import { connect } from 'react-redux' |
|||
import { handleApiError } from 'src/api/errors' |
|||
import { fetchGroupMembers } from 'src/actions/directory' |
|||
import { getGroupMembers } from 'src/selectors/directory' |
|||
import { AppState, AppThunkDispatch } from 'src/types' |
|||
|
|||
import { User } from 'src/types' |
|||
import MemberList, { Props } from './member-list' |
|||
|
|||
import MemberListItem from './member-list-item' |
|||
const mapStateToProps = (state: AppState, ownProps: Props) => ({ |
|||
members: getGroupMembers(state, ownProps.group), |
|||
}) |
|||
|
|||
interface Props { |
|||
members: User[] |
|||
} |
|||
const mapDispatchToProps = (dispatch: AppThunkDispatch, ownProps: Props) => ({ |
|||
fetchGroupMembers: () => { |
|||
try { |
|||
dispatch(fetchGroupMembers(ownProps.group)) |
|||
} catch (err) { |
|||
handleApiError(err, dispatch) |
|||
} |
|||
}, |
|||
}) |
|||
|
|||
const MemberList: FC<Props> = ({ members }) => ( |
|||
<div className="is-flex"> |
|||
{members.map(member => <MemberListItem key={member.id} member={member} />)} |
|||
</div> |
|||
) |
|||
|
|||
export default MemberList |
|||
export default connect( |
|||
mapStateToProps, |
|||
mapDispatchToProps |
|||
)(MemberList) |
@ -0,0 +1,25 @@ |
|||
import React, { FC, useEffect } from 'react' |
|||
import noop from 'lodash/noop' |
|||
import { User } from 'src/types' |
|||
|
|||
import MemberListItem from './member-list-item' |
|||
|
|||
export interface Props { |
|||
group: string |
|||
members?: User[] |
|||
fetchGroupMembers?: () => void |
|||
} |
|||
|
|||
const MemberList: FC<Props> = ({ group, members = [], fetchGroupMembers = noop }) => { |
|||
useEffect(() => { |
|||
fetchGroupMembers() |
|||
}, [group]) |
|||
|
|||
return ( |
|||
<div className="is-flex"> |
|||
{members.map(member => <MemberListItem key={member.id} member={member} />)} |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
export default MemberList |
@ -0,0 +1,11 @@ |
|||
import React, { FC } from 'react' |
|||
import PageHeader from 'src/components/page-header' |
|||
|
|||
const Loading: FC = () => ( |
|||
<div> |
|||
<PageHeader title="Loading..." /> |
|||
<div className="main-content"></div> |
|||
</div> |
|||
) |
|||
|
|||
export default Loading |
@ -1,7 +1,12 @@ |
|||
import { schema } from 'normalizr' |
|||
import { EntityType } from 'src/types' |
|||
|
|||
export const groupSchema = new schema.Entity('groups') |
|||
export const groupSchema = new schema.Entity(EntityType.Group) |
|||
|
|||
export const userSchema = new schema.Entity('users', { |
|||
export const userSchema = new schema.Entity(EntityType.User, { |
|||
group: groupSchema, |
|||
}) |
|||
|
|||
export const logSchema = new schema.Entity(EntityType.Log, { |
|||
user: userSchema, |
|||
}) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue