mirror of
https://github.com/astuto/astuto.git
synced 2025-12-15 19:27:52 +01:00
committed by
GitHub
parent
ba86e81aa0
commit
78049a820c
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import NewPostForm from './NewPostForm';
|
||||
import Spinner from '../shared/Spinner';
|
||||
@@ -86,7 +87,7 @@ class NewPost extends React.Component<Props, State> {
|
||||
|
||||
if (title === '') {
|
||||
this.setState({
|
||||
error: 'You forgot to enter a title!',
|
||||
error: I18n.t('board.new_post.no_title'),
|
||||
isLoading: false,
|
||||
});
|
||||
return;
|
||||
@@ -109,7 +110,7 @@ class NewPost extends React.Component<Props, State> {
|
||||
|
||||
if (res.status === HttpStatus.Created) {
|
||||
this.setState({
|
||||
success: 'Post published! You will be redirected soon...',
|
||||
success: I18n.t('board.new_post.submit_success'),
|
||||
|
||||
title: '',
|
||||
description: '',
|
||||
@@ -124,7 +125,7 @@ class NewPost extends React.Component<Props, State> {
|
||||
|
||||
} catch (e) {
|
||||
this.setState({
|
||||
error: 'An unknown error occurred, try again.'
|
||||
error: I18n.t('board.new_post.submit_error')
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -151,11 +152,16 @@ class NewPost extends React.Component<Props, State> {
|
||||
onClick={this.toggleForm}
|
||||
className="submitBtn"
|
||||
outline={showForm}>
|
||||
{ showForm ? 'Cancel' : 'Submit feedback' }
|
||||
{
|
||||
showForm ?
|
||||
I18n.t('board.new_post.cancel_button')
|
||||
:
|
||||
I18n.t('board.new_post.submit_button')
|
||||
}
|
||||
</Button>
|
||||
:
|
||||
<a href="/users/sign_in" className="btn btn-dark">
|
||||
Log in / Sign up
|
||||
{I18n.t('board.new_post.login_button')}
|
||||
</a>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import Button from '../shared/Button';
|
||||
|
||||
@@ -20,7 +21,7 @@ const NewPostForm = ({
|
||||
<div className="newPostForm">
|
||||
<form>
|
||||
<div className="form-group">
|
||||
<label htmlFor="postTitle">Title</label>
|
||||
<label htmlFor="postTitle">{I18n.t('board.new_post.title')}</label>
|
||||
<input
|
||||
type="text"
|
||||
value={title}
|
||||
@@ -33,7 +34,7 @@ const NewPostForm = ({
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="postDescription">Description (optional)</label>
|
||||
<label htmlFor="postDescription">{I18n.t('board.new_post.description')}</label>
|
||||
<textarea
|
||||
value={description}
|
||||
onChange={e => handleDescriptionChange(e.target.value)}
|
||||
@@ -44,7 +45,7 @@ const NewPostForm = ({
|
||||
></textarea>
|
||||
</div>
|
||||
<Button onClick={e => handleSubmit(e)} className="submitBtn d-block mx-auto">
|
||||
Submit feedback
|
||||
{I18n.t('board.new_post.submit_button')}
|
||||
</Button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import I18n from 'i18n-js';
|
||||
import InfiniteScroll from 'react-infinite-scroller';
|
||||
|
||||
import PostListItem from './PostListItem';
|
||||
@@ -64,7 +64,7 @@ const PostList = ({
|
||||
/>
|
||||
))
|
||||
:
|
||||
areLoading ? <p></p> : <CenteredMutedText>There are no posts.</CenteredMutedText>
|
||||
areLoading ? <p></p> : <CenteredMutedText>{I18n.t('board.posts_list.empty')}</CenteredMutedText>
|
||||
}
|
||||
</InfiniteScroll>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import PostStatusListItem from './PostStatusListItem';
|
||||
import Spinner from '../shared/Spinner';
|
||||
@@ -24,7 +25,7 @@ const PostStatusFilter = ({
|
||||
currentFilter,
|
||||
}: Props) => (
|
||||
<div className="postStatusFilterContainer sidebarCard">
|
||||
<BoxTitleText>Filter by status</BoxTitleText>
|
||||
<BoxTitleText>{I18n.t('board.filter_box.title')}</BoxTitleText>
|
||||
{
|
||||
postStatuses.map((postStatus, i) => (
|
||||
<PostStatusListItem
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import { BoxTitleText } from '../shared/CustomTexts';
|
||||
|
||||
@@ -9,7 +10,7 @@ interface Props {
|
||||
|
||||
const SearchFilter = ({ searchQuery, handleChange }: Props) => (
|
||||
<div className="sidebarCard">
|
||||
<BoxTitleText>Search</BoxTitleText>
|
||||
<BoxTitleText>{I18n.t('board.search_box.title')}</BoxTitleText>
|
||||
|
||||
<input
|
||||
type="search"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
import Gravatar from 'react-gravatar';
|
||||
|
||||
import NewComment from './NewComment';
|
||||
@@ -50,12 +51,24 @@ const Comment = ({
|
||||
<div className="commentHeader">
|
||||
<Gravatar email={userEmail} size={28} className="gravatar" />
|
||||
<span className="commentAuthor">{userFullName}</span>
|
||||
{ isPostUpdate ? <span className="postUpdateBadge">Post update</span> : null }
|
||||
{
|
||||
isPostUpdate ?
|
||||
<span className="postUpdateBadge">
|
||||
{I18n.t('post.comments.post_update_badge')}
|
||||
</span>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
<p className="commentBody">{body}</p>
|
||||
<div className="commentFooter">
|
||||
<a className="commentReplyButton commentLink" onClick={handleToggleCommentReply}>
|
||||
{ replyForm.isOpen ? 'Cancel' : 'Reply' }
|
||||
{
|
||||
replyForm.isOpen ?
|
||||
I18n.t('common.buttons.cancel')
|
||||
:
|
||||
I18n.t('post.comments.reply_button')
|
||||
}
|
||||
</a>
|
||||
{
|
||||
isPowerUser ?
|
||||
@@ -68,14 +81,18 @@ const Comment = ({
|
||||
{ 'Post update: ' + (isPostUpdate ? 'yes' : 'no') }
|
||||
</a>
|
||||
<Separator />
|
||||
<a href={`/admin/comments/${id}/edit`} className="commentLink" data-turbolinks="false">Edit</a>
|
||||
<a href={`/admin/comments/${id}/edit`} className="commentLink" data-turbolinks="false">
|
||||
{I18n.t('common.buttons.edit')}
|
||||
</a>
|
||||
<Separator />
|
||||
<a
|
||||
href={`/admin/comments/${id}`}
|
||||
className="commentLink"
|
||||
data-method="delete"
|
||||
data-confirm="Are you sure?"
|
||||
data-turbolinks="false">Delete</a>
|
||||
data-turbolinks="false">
|
||||
{I18n.t('common.buttons.delete')}
|
||||
</a>
|
||||
|
||||
</React.Fragment>
|
||||
:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import NewComment from './NewComment';
|
||||
import CommentList from './CommentList';
|
||||
@@ -7,6 +8,7 @@ import { DangerText } from '../shared/CustomTexts';
|
||||
|
||||
import IComment from '../../interfaces/IComment';
|
||||
import { ReplyFormState } from '../../reducers/replyFormReducer';
|
||||
import Separator from '../shared/Separator';
|
||||
|
||||
interface Props {
|
||||
postId: number;
|
||||
@@ -106,7 +108,9 @@ class CommentsP extends React.Component<Props> {
|
||||
{ error ? <DangerText>{error}</DangerText> : null }
|
||||
|
||||
<div className="commentsTitle">
|
||||
activity • {comments.length} comment{comments.length === 1 ? '' : 's'}
|
||||
{I18n.t('post.comments.title')}
|
||||
<Separator />
|
||||
{I18n.t('common.comments_number', { count: comments.length })}
|
||||
</div>
|
||||
|
||||
<CommentList
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
import Gravatar from 'react-gravatar';
|
||||
|
||||
import NewCommentUpdateSection from './NewCommentUpdateSection';
|
||||
@@ -50,13 +51,13 @@ const NewComment = ({
|
||||
<textarea
|
||||
value={body}
|
||||
onChange={handleChange}
|
||||
placeholder="Leave a comment"
|
||||
placeholder={I18n.t('post.new_comment.body_placeholder')}
|
||||
className="newCommentBody"
|
||||
/>
|
||||
<Button
|
||||
onClick={() => handleSubmit(body, parentId, postUpdateFlagValue)}
|
||||
className="submitCommentButton">
|
||||
{ isSubmitting ? <Spinner color="light" /> : 'Submit' }
|
||||
{ isSubmitting ? <Spinner color="light" /> : I18n.t('post.new_comment.submit_button') }
|
||||
</Button>
|
||||
</div>
|
||||
{
|
||||
@@ -70,9 +71,12 @@ const NewComment = ({
|
||||
}
|
||||
</React.Fragment>
|
||||
:
|
||||
<a href="/users/sign_in" className="loginInfo">You need to log in to post comments.</a>
|
||||
<a href="/users/sign_in" className="loginInfo">
|
||||
{I18n.t('post.new_comment.not_logged_in')}
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
|
||||
{ error ? <DangerText>{error}</DangerText> : null }
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import { MutedText } from '../shared/CustomTexts';
|
||||
|
||||
interface Props {
|
||||
@@ -19,11 +21,11 @@ const NewCommentUpdateSection = ({
|
||||
checked={postUpdateFlagValue || false}
|
||||
/>
|
||||
|
||||
<label htmlFor="isPostUpdateFlag">Mark as post update</label>
|
||||
<label htmlFor="isPostUpdateFlag">{I18n.t('post.new_comment.is_post_update')}</label>
|
||||
</div>
|
||||
{
|
||||
postUpdateFlagValue ?
|
||||
<MutedText>Users that follow this post will be notified</MutedText>
|
||||
<MutedText>{I18n.t('post.new_comment.user_notification')}</MutedText>
|
||||
:
|
||||
null
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import Button from '../shared/Button';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import Button from '../shared/Button';
|
||||
import { BoxTitleText, SmallMutedText } from '../shared/CustomTexts';
|
||||
|
||||
interface Props {
|
||||
@@ -13,17 +14,17 @@ interface Props {
|
||||
const ActionBox = ({followed, submitFollow, isLoggedIn}: Props) => (
|
||||
<div className="actionBoxContainer">
|
||||
<div className="actionBoxFollow">
|
||||
<BoxTitleText>Actions</BoxTitleText>
|
||||
<BoxTitleText>{I18n.t('post.action_box.title')}</BoxTitleText>
|
||||
<br />
|
||||
<Button onClick={isLoggedIn ? submitFollow : () => location.href = '/users/sign_in'} outline>
|
||||
{ followed ? 'Unfollow post' : 'Follow post' }
|
||||
{ followed ? I18n.t('post.action_box.unfollow_button') : I18n.t('post.action_box.follow_button') }
|
||||
</Button>
|
||||
<br />
|
||||
<SmallMutedText>
|
||||
{ followed ?
|
||||
'you\'re receiving notifications about new updates on this post'
|
||||
I18n.t('post.action_box.following_description')
|
||||
:
|
||||
'you won\'t receive notifications about this post'
|
||||
I18n.t('post.action_box.not_following_description')
|
||||
}
|
||||
</SmallMutedText>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
import Gravatar from 'react-gravatar';
|
||||
|
||||
import ILike from '../../interfaces/ILike';
|
||||
@@ -17,11 +18,13 @@ interface Props {
|
||||
|
||||
const LikeList = ({ likes, areLoading, error}: Props) => (
|
||||
<div className="likeListContainer">
|
||||
<BoxTitleText>Likes</BoxTitleText>
|
||||
<BoxTitleText>{I18n.t('post.likes_box.title')}</BoxTitleText>
|
||||
|
||||
{ areLoading ? <Spinner /> : null }
|
||||
{ error ? <DangerText>{error}</DangerText> : null }
|
||||
|
||||
<div className="likeList">
|
||||
{ likes.length === 0 ? <CenteredMutedText>There are no likes yet.</CenteredMutedText> : null }
|
||||
{ likes.length === 0 ? <CenteredMutedText>{I18n.t('post.likes_box.empty')}</CenteredMutedText> : null }
|
||||
{
|
||||
likes.map((like, i) => (
|
||||
<div className="likeListItem" key={i}>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import IPost from '../../interfaces/IPost';
|
||||
import IPostStatus from '../../interfaces/IPostStatus';
|
||||
@@ -135,7 +136,11 @@ class PostP extends React.Component<Props> {
|
||||
<h2>{post.title}</h2>
|
||||
{
|
||||
isPowerUser && post ?
|
||||
<a href={`/admin/posts/${post.id}`} data-turbolinks="false">Edit</a> : null
|
||||
<a href={`/admin/posts/${post.id}`} data-turbolinks="false">
|
||||
{I18n.t('post.edit_button')}
|
||||
</a>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import IPostStatus from '../../interfaces/IPostStatus';
|
||||
|
||||
@@ -35,7 +36,7 @@ const PostStatusSelect = ({
|
||||
))}
|
||||
</optgroup>
|
||||
<optgroup label="No post status">
|
||||
<option value={NO_POST_STATUS_VALUE}>None</option>
|
||||
<option value={NO_POST_STATUS_VALUE}>{I18n.t('post.post_status_select.no_post_status')}</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
import Gravatar from 'react-gravatar';
|
||||
|
||||
import { BoxTitleText, DangerText, CenteredMutedText, MutedText } from '../shared/CustomTexts';
|
||||
@@ -25,11 +26,18 @@ const PostUpdateList = ({
|
||||
error,
|
||||
}: Props) => (
|
||||
<div className="postUpdateListContainer">
|
||||
<BoxTitleText>Updates</BoxTitleText>
|
||||
<BoxTitleText>{I18n.t('post.updates_box.title')}</BoxTitleText>
|
||||
|
||||
{ areLoading ? <Spinner /> : null }
|
||||
{ error ? <DangerText>{error}</DangerText> : null }
|
||||
|
||||
<div className="postUpdateList">
|
||||
{ postUpdates.length === 0 ? <CenteredMutedText>There are no updates yet.</CenteredMutedText> : null }
|
||||
{
|
||||
postUpdates.length === 0 ?
|
||||
<CenteredMutedText>{I18n.t('post.updates_box.empty')}</CenteredMutedText>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
postUpdates.map((postUpdate, i) => (
|
||||
<div className="postUpdateListItem" key={i}>
|
||||
@@ -43,7 +51,7 @@ const PostUpdateList = ({
|
||||
postUpdate.body
|
||||
:
|
||||
<React.Fragment>
|
||||
<i>changed status to</i>
|
||||
<i>{I18n.t('post.updates_box.status_change')}</i>
|
||||
<PostStatusLabel
|
||||
{...postStatuses.find(postStatus => postStatus.id === postUpdate.postStatusId)}
|
||||
/>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import { Draggable } from 'react-beautiful-dnd';
|
||||
import { DescriptionText } from '../../shared/CustomTexts';
|
||||
@@ -82,7 +83,7 @@ class BoardsEditable extends React.Component<Props, State> {
|
||||
</div>
|
||||
|
||||
<div className="boardEditableActions">
|
||||
<a onClick={this.toggleEditMode}>Edit</a>
|
||||
<a onClick={this.toggleEditMode}>{I18n.t('common.buttons.edit')}</a>
|
||||
|
||||
<Separator />
|
||||
|
||||
@@ -90,7 +91,7 @@ class BoardsEditable extends React.Component<Props, State> {
|
||||
onClick={() => handleDelete(id)}
|
||||
data-confirm="Are you sure?"
|
||||
>
|
||||
Delete
|
||||
{I18n.t('common.buttons.delete')}
|
||||
</a>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
@@ -107,7 +108,7 @@ class BoardsEditable extends React.Component<Props, State> {
|
||||
<a
|
||||
className="boardFormCancelButton"
|
||||
onClick={this.toggleEditMode}>
|
||||
Cancel
|
||||
{I18n.t('common.buttons.cancel')}
|
||||
</a>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import Button from '../../shared/Button';
|
||||
|
||||
@@ -83,7 +84,7 @@ class BoardForm extends React.Component<Props, State> {
|
||||
<div className="boardMandatoryForm">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Board name"
|
||||
placeholder={I18n.t('site_settings.boards.form.name')}
|
||||
value={name}
|
||||
onChange={e => this.onNameChange(e.target.value)}
|
||||
className="form-control"
|
||||
@@ -94,12 +95,17 @@ class BoardForm extends React.Component<Props, State> {
|
||||
className="newBoardButton"
|
||||
disabled={!this.isFormValid()}
|
||||
>
|
||||
{mode === 'create' ? 'Create' : 'Save'}
|
||||
{
|
||||
mode === 'create' ?
|
||||
I18n.t('common.buttons.create')
|
||||
:
|
||||
I18n.t('common.buttons.update')
|
||||
}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<textarea
|
||||
placeholder="Optional board description"
|
||||
placeholder={I18n.t('site_settings.boards.form.description')}
|
||||
value={description}
|
||||
onChange={e => this.onDescriptionChange(e.target.value)}
|
||||
className="form-control"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
|
||||
|
||||
@@ -90,7 +91,7 @@ class BoardsSiteSettingsP extends React.Component<Props> {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="content">
|
||||
<h2>Boards</h2>
|
||||
<h2>{I18n.t('site_settings.boards.title')}</h2>
|
||||
|
||||
{
|
||||
boards.items.length > 0 ?
|
||||
@@ -121,12 +122,12 @@ class BoardsSiteSettingsP extends React.Component<Props> {
|
||||
boards.areLoading ?
|
||||
<Spinner />
|
||||
:
|
||||
<CenteredMutedText>There are no boards. Create one below!</CenteredMutedText>
|
||||
<CenteredMutedText>{I18n.t('site_settings.boards.empty')}</CenteredMutedText>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="content">
|
||||
<h2>New</h2>
|
||||
<h2>{I18n.t('site_settings.boards.new')}</h2>
|
||||
|
||||
<BoardForm mode='create' handleSubmit={this.handleSubmit} />
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import { Draggable } from 'react-beautiful-dnd';
|
||||
|
||||
@@ -74,7 +75,7 @@ class PostStatusEditable extends React.Component<Props, State> {
|
||||
<PostStatusLabel name={name} color={color} />
|
||||
|
||||
<div className="postStatusEditableActions">
|
||||
<a onClick={this.toggleEditMode}>Edit</a>
|
||||
<a onClick={this.toggleEditMode}>{I18n.t('common.buttons.edit')}</a>
|
||||
|
||||
<Separator />
|
||||
|
||||
@@ -82,7 +83,7 @@ class PostStatusEditable extends React.Component<Props, State> {
|
||||
onClick={() => handleDelete(id)}
|
||||
data-confirm="Are you sure?"
|
||||
>
|
||||
Delete
|
||||
{I18n.t('common.buttons.delete')}
|
||||
</a>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
@@ -99,7 +100,7 @@ class PostStatusEditable extends React.Component<Props, State> {
|
||||
<a
|
||||
className="postStatusFormCancelButton"
|
||||
onClick={this.toggleEditMode}>
|
||||
Cancel
|
||||
{I18n.t('common.buttons.cancel')}
|
||||
</a>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import Button from '../../shared/Button';
|
||||
|
||||
@@ -89,7 +90,7 @@ class PostStatusForm extends React.Component<Props, State> {
|
||||
<div className="postStatusForm">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Post status name"
|
||||
placeholder={I18n.t('site_settings.post_statuses.form.name')}
|
||||
value={name}
|
||||
onChange={e => this.onNameChange(e.target.value)}
|
||||
className="form-control"
|
||||
@@ -107,7 +108,12 @@ class PostStatusForm extends React.Component<Props, State> {
|
||||
className="newPostStatusButton"
|
||||
disabled={!this.isFormValid()}
|
||||
>
|
||||
{mode === 'create' ? 'Create' : 'Save'}
|
||||
{
|
||||
mode === 'create' ?
|
||||
I18n.t('common.buttons.create')
|
||||
:
|
||||
I18n.t('common.buttons.update')
|
||||
}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
|
||||
import IPostStatus from '../../../interfaces/IPostStatus';
|
||||
@@ -85,7 +86,7 @@ class PostStatusesSiteSettingsP extends React.Component<Props> {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="content">
|
||||
<h2>Post statuses</h2>
|
||||
<h2>{I18n.t('site_settings.post_statuses.title')}</h2>
|
||||
|
||||
{
|
||||
postStatuses.items.length > 0 ?
|
||||
@@ -116,12 +117,12 @@ class PostStatusesSiteSettingsP extends React.Component<Props> {
|
||||
postStatuses.areLoading ?
|
||||
<Spinner />
|
||||
:
|
||||
<CenteredMutedText>There are no post statuses. Create one below!</CenteredMutedText>
|
||||
<CenteredMutedText>{I18n.t('site_settings.post_statuses.empty')}</CenteredMutedText>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="content">
|
||||
<h2>New</h2>
|
||||
<h2>{I18n.t('site_settings.post_statuses.new')}</h2>
|
||||
|
||||
<PostStatusForm mode='create' handleSubmit={this.handleSubmit} />
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
interface Props {
|
||||
number: number;
|
||||
}
|
||||
|
||||
const CommentsNumber = ({ number }: Props) => (
|
||||
<span className="badge badgeLight">{`${number} comment${number === 1 ? '' : 's'}`}</span>
|
||||
<span className="badge badgeLight">
|
||||
{I18n.t('common.comments_number', { count: number })}
|
||||
</span>
|
||||
);
|
||||
|
||||
export default CommentsNumber;
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@@ -10,7 +11,7 @@ const PostStatusLabel = ({
|
||||
color,
|
||||
}: Props) => (
|
||||
<span className="badge" style={{backgroundColor: color || 'black', color: 'white'}}>
|
||||
{(name || 'no status').toUpperCase()}
|
||||
{(name || I18n.t('common.no_status')).toUpperCase()}
|
||||
</span>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
import Spinner from './Spinner';
|
||||
|
||||
@@ -14,9 +15,11 @@ const SiteSettingsInfoBox = ({ areUpdating, error }: Props) => (
|
||||
<Spinner />
|
||||
:
|
||||
error ?
|
||||
<span className="error">An error occurred: {JSON.stringify(error)}</span>
|
||||
<span className="error">
|
||||
{I18n.t('site_settings.info_box.error', { message: JSON.stringify(error) })}
|
||||
</span>
|
||||
:
|
||||
<span>Everything up to date</span>
|
||||
<span>{I18n.t('site_settings.info_box.up_to_date')}</span>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
const Spinner = ({ color = 'dark' }) => (
|
||||
<div className={`spinner-grow d-block mx-auto text-${color}`} role="status">
|
||||
<span className="sr-only">Loading...</span>
|
||||
<span className="sr-only">{I18n.t('common.loading')}</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user