Ivan - WIP [skip ci]
This commit is contained in:
parent
88f7e82e77
commit
7b9b3392a3
|
@ -0,0 +1,72 @@
|
|||
import React from 'react';
|
||||
|
||||
import i18n from 'lib-app/i18n';
|
||||
import API from 'lib-app/api-call';
|
||||
|
||||
import Header from 'core-components/header';
|
||||
import Button from 'core-components/button';
|
||||
import Form from 'core-components/form';
|
||||
import FormField from 'core-components/form-field';
|
||||
import SubmitButton from 'core-components/submit-button';
|
||||
import IconSelector from 'core-components/icon-selector';
|
||||
import ColorSelector from 'core-components/color-selector';
|
||||
|
||||
class TopicEditModal extends React.Component {
|
||||
|
||||
static contextTypes = {
|
||||
closeModal: React.PropTypes.func
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
defaultValues: React.PropTypes.object,
|
||||
topicId: React.PropTypes.number
|
||||
};
|
||||
|
||||
state = {
|
||||
values: this.props.defaultValues
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="topic-edit-modal">
|
||||
<Header title={i18n('EDIT_TOPIC')} description={i18n('EDIT_TOPIC_DESCRIPTION')} />
|
||||
<Form values={this.state.values} onChange={this.onFormChange.bind(this)} onSubmit={this.onSubmit.bind(this)}>
|
||||
<FormField name="title" label={i18n('TITLE')} />
|
||||
<FormField name="icon" label={i18n('ICON')} decorator={IconSelector} />
|
||||
<FormField name="color" label={i18n('COLOR')} decorator={ColorSelector} />
|
||||
|
||||
<SubmitButton type="secondary" size="small">
|
||||
{i18n('SAVE')}
|
||||
</SubmitButton>
|
||||
<Button onDiscardClick={this.onDiscardClick.bind(this)}>{i18n('DISCARD_CHANGES')}</Button>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
API.call({
|
||||
path: '/article/edit-topic',
|
||||
data: {
|
||||
topicId: this.props.topicId,
|
||||
name: this.state.values['name'],
|
||||
icon: this.state.values['icon'],
|
||||
iconColor: this.state.values['color']
|
||||
}
|
||||
}).then(this.context.closeModal);
|
||||
}
|
||||
|
||||
onFormChange(form) {
|
||||
this.setState({
|
||||
values: form
|
||||
});
|
||||
}
|
||||
|
||||
onDiscardClick() {
|
||||
this.setState({
|
||||
values: this.props.defaultValues
|
||||
}, this.context.closeModal);
|
||||
}
|
||||
}
|
||||
|
||||
export default TopicEditModal;
|
|
@ -1,29 +1,78 @@
|
|||
import React from 'react'
|
||||
import Icon from 'core-components/icon'
|
||||
import React from 'react';
|
||||
import {Link} from 'react-router';
|
||||
|
||||
import i18n from 'lib-app/i18n';
|
||||
import API from 'lib-app/api-call';
|
||||
import ModalContainer from 'app-components/modal-container';
|
||||
import TopicEditModal from 'app-components/topic-edit-modal';
|
||||
|
||||
import Header from 'core-components/header';
|
||||
import Icon from 'core-components/icon';
|
||||
import Button from 'core-components/button';
|
||||
|
||||
class TopicViewer extends React.Component {
|
||||
static propTypes = {
|
||||
topicId: React.PropTypes.number.isRequired,
|
||||
name: React.PropTypes.string.isRequired,
|
||||
icon: React.PropTypes.string.isRequired,
|
||||
iconColor: React.PropTypes.string.isRequired,
|
||||
articles: React.PropTypes.array.isRequired
|
||||
articles: React.PropTypes.array.isRequired,
|
||||
articlePath: React.PropTypes.string,
|
||||
editable: React.PropTypes.bool
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
articlePath: '/admin/panel/articles/view-article/',
|
||||
editable: true
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="topic-viewer">
|
||||
<div className="topic-viewer__header">
|
||||
<Icon className="topic-viewer__icon" name={this.props.icon} size="2x" color={this.props.iconColor}/>
|
||||
<Icon className="topic-viewer__icon" name={this.props.icon} color={this.props.iconColor}/>
|
||||
<span className="topic-viewer__title">{this.props.name}</span>
|
||||
{(this.props.editable) ? this.renderEditButton() : null}
|
||||
</div>
|
||||
<ul className="topic-viewer__list">
|
||||
{this.props.articles.map(function (article) {
|
||||
return <li className="topic-viewer__list-item">{article.title}</li>
|
||||
})}
|
||||
{this.props.articles.map(this.renderArticleItem.bind(this))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderEditButton() {
|
||||
return (
|
||||
<span onClick={() => {ModalContainer.openModal(this.renderEditModal());}}>
|
||||
<Icon className="topic-viewer__edit-icon" name="pencil" />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
renderArticleItem(article) {
|
||||
return (
|
||||
<li className="topic-viewer__list-item">
|
||||
<Link className="topic-viewer__list-item-button" to={this.props.articlePath + article.id}>
|
||||
{article.title}
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
renderEditModal() {
|
||||
let props = {
|
||||
topicId: this.props.topicId,
|
||||
defaultValues: {
|
||||
title: this.props.name,
|
||||
icon: this.props.icon,
|
||||
iconColor: this.props.iconColor
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<TopicEditModal {...props} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TopicViewer;
|
|
@ -2,17 +2,35 @@
|
|||
|
||||
.topic-viewer {
|
||||
text-align: left;
|
||||
//font-weight: bold;
|
||||
|
||||
&__header {
|
||||
cursor: default;
|
||||
margin-bottom: 15px;
|
||||
font-size: $font-size--bg;
|
||||
|
||||
&:hover {
|
||||
.topic-viewer__edit-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__icon {
|
||||
color: $primary-green;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: $font-size--lg;
|
||||
font-size: $font-size--md;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
&__edit-icon {
|
||||
color: $grey;
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&__list {
|
||||
&-item {
|
||||
display: inline-block;
|
||||
|
@ -31,5 +49,9 @@
|
|||
&-item:nth-child(odd) {
|
||||
//background: green;
|
||||
}
|
||||
|
||||
&-item-button {
|
||||
color: $secondary-blue;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -97,7 +97,7 @@ export default (
|
|||
<Route path="articles">
|
||||
<IndexRedirect to="list-articles" />
|
||||
<Route path="list-articles" component={AdminPanelListArticles} />
|
||||
<Route path="view-article" component={AdminPanelViewArticle} />
|
||||
<Route path="view-article/:articleId" component={AdminPanelViewArticle} />
|
||||
</Route>
|
||||
|
||||
<Route path="staff">
|
||||
|
|
|
@ -29,7 +29,7 @@ class AdminPanelListArticles extends React.Component {
|
|||
return (
|
||||
<div>
|
||||
{this.state.topics.map(function (topic) {
|
||||
return <TopicViewer {...topic} />
|
||||
return <TopicViewer {...topic} topicId={topic.id} />
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import React from 'react';
|
||||
|
||||
import Tooltip from 'core-components/tooltip';
|
||||
|
||||
const colors = ['#ff6900', '#fcb900', '#7bdcb5', '#00d084', '#8ed1fc', '#0693e3', '#abb8c3', '#eb144c', '#f78da7', '#9900ef'];
|
||||
|
||||
class ColorSelector extends React.Component {
|
||||
static propTypes = {
|
||||
value: React.PropTypes.string,
|
||||
onChange: React.PropTypes.func
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
value: '#ff6900'
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="color-selector">
|
||||
<Tooltip content={this.renderTooltipContent()}>
|
||||
<span className="color-selector__current" style={{backgroundColor: this.props.value}} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderTooltipContent() {
|
||||
return (
|
||||
<div className="color-selector__tooltip">
|
||||
{colors.map(this.renderTooltipColor.bind(this))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderTooltipColor(color) {
|
||||
return (
|
||||
<span className="color-selector__tooltip-color" onClick={this.onColorClick.bind(this, color)} style={{backgroundColor: color}}/>
|
||||
);
|
||||
}
|
||||
|
||||
onColorClick(color) {
|
||||
if(this.props.onChange) {
|
||||
this.props.onChange({target: {value: color}});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default ColorSelector;
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,3 @@
|
|||
.icon-selector {
|
||||
|
||||
}
|
|
@ -10,7 +10,7 @@ module.exports = [
|
|||
id: 1,
|
||||
name: 'Membership Settings',
|
||||
icon: 'user',
|
||||
iconColor: 'green',
|
||||
iconColor: '#82CA9C',
|
||||
articles: [
|
||||
{
|
||||
id: 1,
|
||||
|
@ -95,5 +95,45 @@ module.exports = [
|
|||
]
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/article/edit-topic',
|
||||
time: 100,
|
||||
response: function () {
|
||||
return {
|
||||
status: 'success',
|
||||
data: {}
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/article/edit',
|
||||
time: 100,
|
||||
response: function () {
|
||||
return {
|
||||
status: 'success',
|
||||
data: {}
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/article/add',
|
||||
time: 100,
|
||||
response: function () {
|
||||
return {
|
||||
status: 'success',
|
||||
data: {}
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/article/add-topic',
|
||||
time: 100,
|
||||
response: function () {
|
||||
return {
|
||||
status: 'success',
|
||||
data: {}
|
||||
};
|
||||
}
|
||||
}
|
||||
];
|
|
@ -23,5 +23,6 @@ $half-space: 20px;
|
|||
$font-size--xs: 11px;
|
||||
$font-size--sm: 13px;
|
||||
$font-size--md: 16px;
|
||||
$font-size--bg: 19px;
|
||||
$font-size--lg: 24px;
|
||||
$font-size--xl: 32px;
|
Loading…
Reference in New Issue