mirror of
https://github.com/wassname/talk.git
synced 2026-07-31 12:50:48 +08:00
saving my place
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import React, {PropTypes} from 'react';
|
||||
import {Button, Drawer} from 'coral-ui';
|
||||
import styles from './UserDetail.js';
|
||||
|
||||
const UserDetail = ({user}) => {
|
||||
const localProfile = user.profiles.find(p => p.provider === 'local');
|
||||
const facebookProfile = user.profiles.find(p => p.provider === 'facebook');
|
||||
let profile;
|
||||
if (localProfile) {
|
||||
profile = profile.id;
|
||||
} else if (facebookProfile) {
|
||||
profile = <a href={`https://facebook.com/${facebookProfile.id}`}>{facebookProfile.id}</a>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Drawer>
|
||||
<h3>{user.username}</h3>
|
||||
<p>{profile}</p> <Button>Copy</Button>
|
||||
<strong>Member since</strong> {user.created_at}
|
||||
<hr/>
|
||||
<strong>Account summary</strong>
|
||||
<br/><span className={styles.small}>Data represents the last six months of activity</span>
|
||||
<div className={styles.stats}>
|
||||
</div>
|
||||
</Drawer>
|
||||
);
|
||||
};
|
||||
|
||||
UserDetail.propTypes = {
|
||||
user: PropTypes.shape({
|
||||
username: PropTypes.string.isRequired,
|
||||
profiles: PropTypes.arrayOf(PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
provider: PropTypes.string
|
||||
}))
|
||||
})
|
||||
};
|
||||
|
||||
export default UserDetail;
|
||||
@@ -5,7 +5,7 @@ import key from 'keymaster';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import styles from './components/styles.css';
|
||||
|
||||
import {modQueueQuery} from '../../graphql/queries';
|
||||
import {modQueueQuery, getUserDetail} from '../../graphql/queries';
|
||||
import {banUser, setCommentStatus} from '../../graphql/mutations';
|
||||
|
||||
import {fetchSettings} from 'actions/settings';
|
||||
@@ -19,6 +19,7 @@ import ModerationMenu from './components/ModerationMenu';
|
||||
import ModerationHeader from './components/ModerationHeader';
|
||||
import NotFoundAsset from './components/NotFoundAsset';
|
||||
import ModerationKeysModal from '../../components/ModerationKeysModal';
|
||||
import UserDetail from '../../components/UserDetail';
|
||||
|
||||
class ModerationContainer extends Component {
|
||||
state = {
|
||||
@@ -76,6 +77,15 @@ class ModerationContainer extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
viewUserDetail = (id) => {
|
||||
console.log('getting user detail', id, typeof getUserDetail);
|
||||
try {
|
||||
getUserDetail({id});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
selectSort = (sort) => {
|
||||
this.setState({sort});
|
||||
this.props.modQueueResort(sort);
|
||||
@@ -180,6 +190,7 @@ class ModerationContainer extends Component {
|
||||
assetId={providedAssetId}
|
||||
sort={this.state.sort}
|
||||
commentCount={activeTabCount}
|
||||
viewUserDetail={this.viewUserDetail}
|
||||
/>
|
||||
<BanUserDialog
|
||||
open={moderation.banDialog}
|
||||
@@ -190,11 +201,12 @@ class ModerationContainer extends Component {
|
||||
showRejectedNote={moderation.showRejectedNote}
|
||||
rejectComment={props.rejectComment}
|
||||
/>
|
||||
<ModerationKeysModal
|
||||
<ModerationKeysModal
|
||||
hideShortcutsNote={props.hideShortcutsNote}
|
||||
shortcutsNoteVisible={moderation.shortcutsNoteVisible}
|
||||
open={moderation.modalOpen}
|
||||
onClose={onClose}/>
|
||||
{data.user && <UserDetail user={data.user} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,16 @@ import translations from 'coral-admin/src/translations';
|
||||
import LoadMore from './components/LoadMore';
|
||||
|
||||
const lang = new I18n(translations);
|
||||
const ModerationQueue = ({comments, selectedIndex, commentCount, singleView, loadMore, activeTab, sort, ...props}) => {
|
||||
const ModerationQueue = ({
|
||||
comments,
|
||||
selectedIndex,
|
||||
commentCount,
|
||||
singleView,
|
||||
loadMore,
|
||||
activeTab,
|
||||
sort,
|
||||
viewUserDetail,
|
||||
...props}) => {
|
||||
return (
|
||||
<div id="moderationList" className={`${styles.list} ${singleView ? styles.singleView : ''}`}>
|
||||
<ul style={{paddingLeft: 0}}>
|
||||
@@ -26,6 +35,7 @@ const ModerationQueue = ({comments, selectedIndex, commentCount, singleView, loa
|
||||
bannedWords={props.bannedWords}
|
||||
actions={actionsMap[status]}
|
||||
showBanUserDialog={props.showBanUserDialog}
|
||||
viewUserDetail={viewUserDetail}
|
||||
acceptComment={props.acceptComment}
|
||||
rejectComment={props.rejectComment}
|
||||
currentAsset={props.currentAsset}
|
||||
@@ -47,6 +57,7 @@ const ModerationQueue = ({comments, selectedIndex, commentCount, singleView, loa
|
||||
};
|
||||
|
||||
ModerationQueue.propTypes = {
|
||||
viewUserDetail: PropTypes.func.isRequired,
|
||||
bannedWords: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
suspectWords: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
currentAsset: PropTypes.object,
|
||||
|
||||
@@ -18,7 +18,7 @@ import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from 'coral-admin/src/translations.json';
|
||||
const lang = new I18n(translations);
|
||||
|
||||
const Comment = ({actions = [], comment, ...props}) => {
|
||||
const Comment = ({actions = [], comment, viewUserDetail, ...props}) => {
|
||||
const links = linkify.getMatches(comment.body);
|
||||
const linkText = links ? links.map(link => link.raw) : [];
|
||||
const flagActionSummaries = getActionSummary('FlagActionSummary', comment);
|
||||
@@ -35,7 +35,10 @@ const Comment = ({actions = [], comment, ...props}) => {
|
||||
<div className={styles.container}>
|
||||
<div className={styles.itemHeader}>
|
||||
<div className={styles.author}>
|
||||
<span>
|
||||
<span className={styles.username} onClick={() => {
|
||||
console.log('clickt', comment.user.id);
|
||||
viewUserDetail(comment.user.id);
|
||||
}}>
|
||||
{comment.user.name}
|
||||
</span>
|
||||
<span className={styles.created}>
|
||||
@@ -89,6 +92,7 @@ const Comment = ({actions = [], comment, ...props}) => {
|
||||
};
|
||||
|
||||
Comment.propTypes = {
|
||||
viewUserDetail: PropTypes.func.isRequired,
|
||||
acceptComment: PropTypes.func.isRequired,
|
||||
rejectComment: PropTypes.func.isRequired,
|
||||
suspectWords: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
@@ -100,8 +104,9 @@ Comment.propTypes = {
|
||||
actions: PropTypes.array,
|
||||
created_at: PropTypes.string.isRequired,
|
||||
user: PropTypes.shape({
|
||||
id: PropTypes.string,
|
||||
status: PropTypes.string
|
||||
}),
|
||||
}).isRequired,
|
||||
asset: PropTypes.shape({
|
||||
title: PropTypes.string,
|
||||
id: PropTypes.string
|
||||
|
||||
@@ -423,3 +423,14 @@ span {
|
||||
position: relative;
|
||||
top: 7px;
|
||||
}
|
||||
|
||||
.username {
|
||||
color: blue;
|
||||
text-decoration: underline;
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 0, 0, .1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import MOD_QUEUE_QUERY from './modQueueQuery.graphql';
|
||||
import MOD_QUEUE_LOAD_MORE from './loadMore.graphql';
|
||||
import MOD_USER_FLAGGED_QUERY from './modUserFlaggedQuery.graphql';
|
||||
import METRICS from './metricsQuery.graphql';
|
||||
import USER_DETAIL from './userDetail.graphql';
|
||||
|
||||
export const modQueueQuery = graphql(MOD_QUEUE_QUERY, {
|
||||
options: ({params: {id = null}}) => {
|
||||
@@ -93,3 +94,17 @@ export const modQueueResort = (id, fetchMore) => (sort) => {
|
||||
updateQuery: (oldData, {fetchMoreResult:{data}}) => data
|
||||
});
|
||||
};
|
||||
|
||||
export const getUserDetail = ({id}) => {
|
||||
console.log('close', id);
|
||||
return graphql(USER_DETAIL, {
|
||||
options: () => {
|
||||
console.log('so close!', id);
|
||||
return {
|
||||
variables: {
|
||||
id
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
query UserDetail ($id: ID!) {
|
||||
user(id: $id) {
|
||||
id
|
||||
username
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
.wrapper {
|
||||
transition: opacity 250ms;
|
||||
position: fixed;
|
||||
z-index: 10000;
|
||||
background-color: rgba(0, 0, 0, .2);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.drawer {
|
||||
transition: transform 500ms ease-in-out;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import React, {PropTypes} from 'react';
|
||||
import styles from './Drawer.css';
|
||||
|
||||
const Drawer = (props) => {
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<div className={styles.drawer}>{props.children}</div>
|
||||
<div className={styles.closeButton} onClick={props.close}>×</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Drawer.propTypes = {
|
||||
active: PropTypes.bool
|
||||
};
|
||||
|
||||
export default Drawer;
|
||||
@@ -23,3 +23,4 @@ export {default as Select} from './components/Select';
|
||||
export {default as Option} from './components/Option';
|
||||
export {default as SnackBar} from './components/SnackBar';
|
||||
export {default as TextArea} from './components/TextArea';
|
||||
export {default as Drawer} from './components/Drawer';
|
||||
|
||||
@@ -96,6 +96,16 @@ const RootQuery = {
|
||||
return await Users.getByQuery({ids: currentUser.ignoresUsers});
|
||||
},
|
||||
|
||||
// this returns an arbitrary user
|
||||
user(_, {id}, {user, loaders: {Users}}) {
|
||||
console.log("user id!", id);
|
||||
if (user == null || !user.hasRoles('ADMIN')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Users.getByID.load(id);
|
||||
},
|
||||
|
||||
// This endpoint is used for loading the user moderation queues (users whose username has been flagged),
|
||||
// so hide it in the event that we aren't an admin.
|
||||
users(_, {query: {action_type, limit, cursor, sort}}, {user, loaders: {Users, Actions}}) {
|
||||
|
||||
@@ -585,6 +585,9 @@ type RootQuery {
|
||||
# Users returned based on a query.
|
||||
users(query: UsersQuery): [User]
|
||||
|
||||
# a single User by id
|
||||
user(id: ID!): User
|
||||
|
||||
# Asset metrics related to user actions are saturated into the assets
|
||||
# returned. Parameters `from` and `to` are related to the action created_at field.
|
||||
assetMetrics(from: Date!, to: Date!, sort: ASSET_METRICS_SORT!, limit: Int = 10): [Asset!]
|
||||
|
||||
Reference in New Issue
Block a user