diff --git a/client/src/app-components/topic-edit-modal.js b/client/src/app-components/topic-edit-modal.js
new file mode 100644
index 00000000..a02c813e
--- /dev/null
+++ b/client/src/app-components/topic-edit-modal.js
@@ -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 (
+
+
+
+
+ );
+ }
+
+ 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;
\ No newline at end of file
diff --git a/client/src/app-components/topic-edit-modal.scss b/client/src/app-components/topic-edit-modal.scss
new file mode 100644
index 00000000..e69de29b
diff --git a/client/src/app-components/topic-viewer.js b/client/src/app-components/topic-viewer.js
index bf93ccbd..390a24b7 100644
--- a/client/src/app-components/topic-viewer.js
+++ b/client/src/app-components/topic-viewer.js
@@ -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 (
-
+
{this.props.name}
+ {(this.props.editable) ? this.renderEditButton() : null}
- {this.props.articles.map(function (article) {
- return - {article.title}
- })}
+ {this.props.articles.map(this.renderArticleItem.bind(this))}
);
}
+
+ renderEditButton() {
+ return (
+ {ModalContainer.openModal(this.renderEditModal());}}>
+
+
+ );
+ }
+
+ renderArticleItem(article) {
+ return (
+
+
+ {article.title}
+
+
+ );
+ }
+
+ renderEditModal() {
+ let props = {
+ topicId: this.props.topicId,
+ defaultValues: {
+ title: this.props.name,
+ icon: this.props.icon,
+ iconColor: this.props.iconColor
+ }
+ };
+
+ return (
+
+ );
+ }
}
export default TopicViewer;
\ No newline at end of file
diff --git a/client/src/app-components/topic-viewer.scss b/client/src/app-components/topic-viewer.scss
index abb13971..3bb483fc 100644
--- a/client/src/app-components/topic-viewer.scss
+++ b/client/src/app-components/topic-viewer.scss
@@ -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;
+ }
}
}
\ No newline at end of file
diff --git a/client/src/app/Routes.js b/client/src/app/Routes.js
index 534f9cda..9406720d 100644
--- a/client/src/app/Routes.js
+++ b/client/src/app/Routes.js
@@ -97,7 +97,7 @@ export default (
-
+
diff --git a/client/src/app/admin/panel/articles/admin-panel-list-articles.js b/client/src/app/admin/panel/articles/admin-panel-list-articles.js
index 401326e6..0899807b 100644
--- a/client/src/app/admin/panel/articles/admin-panel-list-articles.js
+++ b/client/src/app/admin/panel/articles/admin-panel-list-articles.js
@@ -29,7 +29,7 @@ class AdminPanelListArticles extends React.Component {
return (
{this.state.topics.map(function (topic) {
- return
+ return
})}
)
diff --git a/client/src/core-components/color-selector.js b/client/src/core-components/color-selector.js
new file mode 100644
index 00000000..8a8b510b
--- /dev/null
+++ b/client/src/core-components/color-selector.js
@@ -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 (
+
+
+
+
+
+ )
+ }
+
+ renderTooltipContent() {
+ return (
+
+ {colors.map(this.renderTooltipColor.bind(this))}
+
+ );
+ }
+
+ renderTooltipColor(color) {
+ return (
+
+ );
+ }
+
+ onColorClick(color) {
+ if(this.props.onChange) {
+ this.props.onChange({target: {value: color}});
+ }
+ }
+}
+
+
+export default ColorSelector;
\ No newline at end of file
diff --git a/client/src/core-components/color-selector.scss b/client/src/core-components/color-selector.scss
new file mode 100644
index 00000000..e69de29b
diff --git a/client/src/core-components/icon-selector.js b/client/src/core-components/icon-selector.js
new file mode 100644
index 00000000..87eb08f9
--- /dev/null
+++ b/client/src/core-components/icon-selector.js
@@ -0,0 +1,51 @@
+import React from 'react';
+
+import Icon from 'core-components/icon';
+import Tooltip from 'core-components/tooltip';
+
+const icons = ['address-book', 'address-book-o', 'address-card', 'address-card-o', 'adjust', 'american-sign-language-interpreting', 'anchor', 'archive', 'area-chart', 'arrows', 'arrows-h', 'arrows-v', 'asl-interpreting (alias)', 'assistive-listening-systems', 'asterisk', 'at', 'audio-description', 'automobile (alias)', 'balance-scale', 'ban', 'bank (alias)', 'bar-chart', 'bar-chart-o (alias)', 'barcode', 'bars', 'bath', 'bathtub (alias)', 'battery (alias)', 'battery-0 (alias)', 'battery-1 (alias)', 'battery-2 (alias)', 'battery-3 (alias)', 'battery-4 (alias)', 'battery-empty', 'battery-full', 'battery-half', 'battery-quarter', 'battery-three-quarters', 'bed', 'beer', 'bell', 'bell-o', 'bell-slash', 'bell-slash-o', 'bicycle', 'binoculars', 'birthday-cake', 'blind', 'bluetooth', 'bluetooth-b', 'bolt', 'bomb', 'book', 'bookmark', 'bookmark-o', 'braille', 'briefcase', 'bug', 'building', 'building-o', 'bullhorn', 'bullseye', 'bus', 'cab (alias)', 'calculator', 'calendar', 'calendar-check-o', 'calendar-minus-o', 'calendar-o', 'calendar-plus-o', 'calendar-times-o', 'camera', 'camera-retro', 'car', 'caret-square-o-down', 'caret-square-o-left', 'caret-square-o-right', 'caret-square-o-up', 'cart-arrow-down', 'cart-plus', 'cc', 'certificate', 'check', 'check-circle', 'check-circle-o', 'check-square', 'check-square-o', 'child', 'circle', 'circle-o', 'circle-o-notch', 'circle-thin', 'clock-o', 'clone', 'close (alias)', 'cloud', 'cloud-download', 'cloud-upload', 'code', 'code-fork', 'coffee', 'cog', 'cogs', 'comment', 'comment-o', 'commenting', 'commenting-o', 'comments', 'comments-o', 'compass', 'copyright', 'creative-commons', 'credit-card', 'credit-card-alt', 'crop', 'crosshairs', 'cube', 'cubes', 'cutlery', 'dashboard (alias)', 'database', 'deaf', 'deafness (alias)', 'desktop', 'diamond', 'dot-circle-o', 'download', 'drivers-license (alias)', 'drivers-license-o (alias)', 'edit (alias)', 'ellipsis-h', 'ellipsis-v', 'envelope', 'envelope-o', 'envelope-open', 'envelope-open-o', 'envelope-square', 'eraser', 'exchange', 'exclamation', 'exclamation-circle', 'exclamation-triangle', 'external-link', 'external-link-square', 'eye', 'eye-slash', 'eyedropper', 'fax', 'feed (alias)', 'female', 'fighter-jet', 'file-archive-o', 'file-audio-o', 'file-code-o', 'file-excel-o', 'file-image-o', 'file-movie-o (alias)', 'file-pdf-o', 'file-photo-o (alias)', 'file-picture-o (alias)', 'file-powerpoint-o', 'file-sound-o (alias)', 'file-video-o', 'file-word-o', 'file-zip-o (alias)', 'film', 'filter', 'fire', 'fire-extinguisher', 'flag', 'flag-checkered', 'flag-o', 'flash (alias)', 'flask', 'folder', 'folder-o', 'folder-open', 'folder-open-o', 'frown-o', 'futbol-o', 'gamepad', 'gavel', 'gear (alias)', 'gears (alias)', 'gift', 'glass', 'globe', 'graduation-cap', 'group (alias)', 'hand-grab-o (alias)', 'hand-lizard-o', 'hand-paper-o', 'hand-peace-o', 'hand-pointer-o', 'hand-rock-o', 'hand-scissors-o', 'hand-spock-o', 'hand-stop-o (alias)', 'handshake-o', 'hard-of-hearing (alias)', 'hashtag', 'hdd-o', 'headphones', 'heart', 'heart-o', 'heartbeat', 'history', 'home', 'hotel (alias)', 'hourglass', 'hourglass-1 (alias)', 'hourglass-2 (alias)', 'hourglass-3 (alias)', 'hourglass-end', 'hourglass-half', 'hourglass-o', 'hourglass-start', 'i-cursor', 'id-badge', 'id-card', 'id-card-o', 'image (alias)', 'inbox', 'industry', 'info', 'info-circle', 'institution (alias)', 'key', 'keyboard-o', 'language', 'laptop', 'leaf', 'legal (alias)', 'lemon-o', 'level-down', 'level-up', 'life-bouy (alias)', 'life-buoy (alias)', 'life-ring', 'life-saver (alias)', 'lightbulb-o', 'line-chart', 'location-arrow', 'lock', 'low-vision', 'magic', 'magnet', 'mail-forward (alias)', 'mail-reply (alias)', 'mail-reply-all (alias)', 'male', 'map', 'map-marker', 'map-o', 'map-pin', 'map-signs', 'meh-o', 'microchip', 'microphone', 'microphone-slash', 'minus', 'minus-circle', 'minus-square', 'minus-square-o', 'mobile', 'mobile-phone (alias)', 'money', 'moon-o', 'mortar-board (alias)', 'motorcycle', 'mouse-pointer', 'music', 'navicon (alias)', 'newspaper-o', 'object-group', 'object-ungroup', 'paint-brush', 'paper-plane', 'paper-plane-o', 'paw', 'pencil', 'pencil-square', 'pencil-square-o', 'percent', 'phone', 'phone-square', 'photo (alias)', 'picture-o', 'pie-chart', 'plane', 'plug', 'plus', 'plus-circle', 'plus-square', 'plus-square-o', 'podcast', 'power-off', 'print', 'puzzle-piece', 'qrcode', 'question', 'question-circle', 'question-circle-o', 'quote-left', 'quote-right', 'random', 'recycle', 'refresh', 'registered', 'remove (alias)', 'reorder (alias)', 'reply', 'reply-all', 'retweet', 'road', 'rocket', 'rss', 'rss-square', 's15 (alias)', 'search', 'search-minus', 'search-plus', 'send (alias)', 'send-o (alias)', 'server', 'share', 'share-alt', 'share-alt-square', 'share-square', 'share-square-o', 'shield', 'ship', 'shopping-bag', 'shopping-basket', 'shopping-cart', 'shower', 'sign-in', 'sign-language', 'sign-out', 'signal', 'signing (alias)', 'sitemap', 'sliders', 'smile-o', 'snowflake-o', 'soccer-ball-o (alias)', 'sort', 'sort-alpha-asc', 'sort-alpha-desc', 'sort-amount-asc', 'sort-amount-desc', 'sort-asc', 'sort-desc', 'sort-down (alias)', 'sort-numeric-asc', 'sort-numeric-desc', 'sort-up (alias)', 'space-shuttle', 'spinner', 'spoon', 'square', 'square-o', 'star', 'star-half', 'star-half-empty (alias)', 'star-half-full (alias)', 'star-half-o', 'star-o', 'sticky-note', 'sticky-note-o', 'street-view', 'suitcase', 'sun-o', 'support (alias)', 'tablet', 'tachometer', 'tag', 'tags', 'tasks', 'taxi', 'television', 'terminal', 'thermometer (alias)', 'thermometer-0 (alias)', 'thermometer-1 (alias)', 'thermometer-2 (alias)', 'thermometer-3 (alias)', 'thermometer-4 (alias)', 'thermometer-empty', 'thermometer-full', 'thermometer-half', 'thermometer-quarter', 'thermometer-three-quarters', 'thumb-tack', 'thumbs-down', 'thumbs-o-down', 'thumbs-o-up', 'thumbs-up', 'ticket', 'times', 'times-circle', 'times-circle-o', 'times-rectangle (alias)', 'times-rectangle-o (alias)', 'tint', 'toggle-down (alias)', 'toggle-left (alias)', 'toggle-off', 'toggle-on', 'toggle-right (alias)', 'toggle-up (alias)', 'trademark', 'trash', 'trash-o', 'tree', 'trophy', 'truck', 'tty', 'tv (alias)', 'umbrella', 'universal-access', 'university', 'unlock', 'unlock-alt', 'unsorted (alias)', 'upload', 'user', 'user-circle', 'user-circle-o', 'user-o', 'user-plus', 'user-secret', 'user-times', 'users', 'vcard (alias)', 'vcard-o (alias)', 'video-camera', 'volume-control-phone', 'volume-down', 'volume-off', 'volume-up', 'warning (alias)', 'wheelchair', 'wheelchair-alt', 'wifi', 'window-close', 'window-close-o', 'window-maximize', 'window-minimize', 'window-restore', 'wrench'];
+
+class IconSelector extends React.Component {
+ static propTypes = {
+ value: React.PropTypes.string,
+ onChange: React.PropTypes.func
+ };
+
+ static defaultProps = {
+ value: 'adjust'
+ };
+
+ render() {
+ return (
+
+
+
+
+
+ )
+ }
+
+ renderTooltipContent() {
+ return (
+
+ {icons.map(this.renderTooltipIcon.bind(this))}
+
+ );
+ }
+
+ renderTooltipIcon(name) {
+ return (
+
+
+
+ );
+ }
+
+ onIconClick(name) {
+ if(this.props.onChange) {
+ this.props.onChange({target: {value: name}});
+ }
+ }
+}
+
+export default IconSelector;
\ No newline at end of file
diff --git a/client/src/core-components/icon-selector.scss b/client/src/core-components/icon-selector.scss
new file mode 100644
index 00000000..3e845c37
--- /dev/null
+++ b/client/src/core-components/icon-selector.scss
@@ -0,0 +1,3 @@
+.icon-selector {
+
+}
\ No newline at end of file
diff --git a/client/src/data/fixtures/article-fixtures.js b/client/src/data/fixtures/article-fixtures.js
index e11c654b..a798c034 100644
--- a/client/src/data/fixtures/article-fixtures.js
+++ b/client/src/data/fixtures/article-fixtures.js
@@ -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: {}
+ };
+ }
}
];
\ No newline at end of file
diff --git a/client/src/scss/_vars.scss b/client/src/scss/_vars.scss
index 6bcdbf59..59793c65 100644
--- a/client/src/scss/_vars.scss
+++ b/client/src/scss/_vars.scss
@@ -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;
\ No newline at end of file