From 4da78d2e687f53048abe5694859e09f74102417b Mon Sep 17 00:00:00 2001
From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com>
Date: Mon, 16 Oct 2023 18:57:29 +0300
Subject: [PATCH 1/2] Feature/update confirm modal (#264)
Update confirm modal
---
public/locales/en/translation.json | 5 +-
public/locales/ru/translation.json | 3 +
src/components/Article/Comment.tsx | 7 ++-
src/components/Article/CommentsTree.tsx | 2 +-
src/components/Draft/Draft.tsx | 9 ++-
src/components/Inbox/Message.tsx | 1 -
.../Nav/ConfirmModal/ConfirmModal.module.scss | 60 ++++++-------------
.../Nav/ConfirmModal/ConfirmModal.tsx | 27 +++++----
src/components/Nav/Modal/Modal.module.scss | 4 +-
src/components/Nav/Modal/Modal.tsx | 3 +-
.../NotificationView/NotificationView.tsx | 2 -
.../NotificationsPanel/NotificationsPanel.tsx | 2 +-
src/components/Views/Author/Author.tsx | 1 -
.../_shared/Button/Button.module.scss | 11 ++++
src/components/_shared/Button/Button.tsx | 3 +-
src/context/confirm.tsx | 11 +++-
16 files changed, 81 insertions(+), 70 deletions(-)
diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index d277ae8c..1f5e43b4 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -28,6 +28,8 @@
"All posts": "All posts",
"All topics": "All topics",
"Almost done! Check your email.": "Almost done! Just checking your email.",
+ "Are you sure you want to delete this comment?": "Are you sure you want to delete this comment?",
+ "Are you sure you want to delete this draft?": "Are you sure you want to delete this draft?",
"Are you sure you want to to proceed the action?": "Are you sure you want to to proceed the action?",
"Art": "Art",
"Artist": "Artist",
@@ -100,6 +102,7 @@
"Discussion rules": "Discussion rules",
"Discussions": "Discussions",
"Dogma": "Dogma",
+ "Draft successfully deleted": "Draft successfully deleted",
"Drafts": "Drafts",
"Drag the image to this area": "Drag the image to this area",
"Each image must be no larger than 5 MB.": "Each image must be no larger than 5 MB.",
@@ -193,6 +196,7 @@
"Manifesto": "Manifesto",
"Many files, choose only one": "Many files, choose only one",
"Material card": "Material card",
+ "Message": "Message",
"More": "More",
"Most commented": "Commented",
"Most read": "Readable",
@@ -353,7 +357,6 @@
"Where": "From",
"Words": "Слов",
"Work with us": "Cooperate with Discourse",
- "Message": "Message",
"Write a comment...": "Write a comment...",
"Write a short introduction": "Write a short introduction",
"Write about the topic": "Write about the topic",
diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json
index 2a983fa3..cb2559b3 100644
--- a/public/locales/ru/translation.json
+++ b/public/locales/ru/translation.json
@@ -31,6 +31,8 @@
"All posts": "Все публикации",
"All topics": "Все темы",
"Almost done! Check your email.": "Почти готово! Осталось подтвердить вашу почту.",
+ "Are you sure you want to delete this comment?": "Уверены, что хотите удалить этот комментарий?",
+ "Are you sure you want to delete this draft?": "Уверены, что хотите удалить этот черновик?",
"Are you sure you want to to proceed the action?": "Вы уверены, что хотите продолжить?",
"Art": "Искусство",
"Artist": "Исполнитель",
@@ -104,6 +106,7 @@
"Discussion rules": "Правила сообществ самиздата в соцсетях",
"Discussions": "Дискуссии",
"Dogma": "Догма",
+ "Draft successfully deleted": "Черновик успешно удален",
"Drafts": "Черновики",
"Drag the image to this area": "Перетащите изображение в эту область",
"Each image must be no larger than 5 MB.": "Каждое изображение должно быть размером не больше 5 мб.",
diff --git a/src/components/Article/Comment.tsx b/src/components/Article/Comment.tsx
index 35788445..823a59f7 100644
--- a/src/components/Article/Comment.tsx
+++ b/src/components/Article/Comment.tsx
@@ -62,7 +62,12 @@ export const Comment = (props: Props) => {
const remove = async () => {
if (comment()?.id) {
try {
- const isConfirmed = await showConfirm()
+ const isConfirmed = await showConfirm({
+ confirmBody: t('Are you sure you want to delete this comment?'),
+ confirmButtonLabel: t('Delete'),
+ confirmButtonVariant: 'danger',
+ declineButtonVariant: 'primary'
+ })
if (isConfirmed) {
await deleteReaction(comment().id)
diff --git a/src/components/Article/CommentsTree.tsx b/src/components/Article/CommentsTree.tsx
index 0122f626..96340312 100644
--- a/src/components/Article/CommentsTree.tsx
+++ b/src/components/Article/CommentsTree.tsx
@@ -1,4 +1,4 @@
-import { Show, createMemo, createSignal, onMount, For, createEffect } from 'solid-js'
+import { Show, createMemo, createSignal, onMount, For } from 'solid-js'
import { Comment } from './Comment'
import styles from './Article.module.scss'
import { clsx } from 'clsx'
diff --git a/src/components/Draft/Draft.tsx b/src/components/Draft/Draft.tsx
index f5095a65..7ee25154 100644
--- a/src/components/Draft/Draft.tsx
+++ b/src/components/Draft/Draft.tsx
@@ -35,11 +35,16 @@ export const Draft = (props: Props) => {
const handleDeleteLinkClick = async (e) => {
e.preventDefault()
- const isConfirmed = await showConfirm()
+ const isConfirmed = await showConfirm({
+ confirmBody: t('Are you sure you want to delete this draft?'),
+ confirmButtonLabel: t('Delete'),
+ confirmButtonVariant: 'danger',
+ declineButtonVariant: 'primary'
+ })
if (isConfirmed) {
props.onDelete(props.shout)
- await showSnackbar({ type: 'success', body: t('Success') })
+ await showSnackbar({ body: t('Draft successfully deleted') })
}
}
diff --git a/src/components/Inbox/Message.tsx b/src/components/Inbox/Message.tsx
index bdcf0b9d..9a345cf4 100644
--- a/src/components/Inbox/Message.tsx
+++ b/src/components/Inbox/Message.tsx
@@ -7,7 +7,6 @@ import formattedTime from '../../utils/formatDateTime'
import { Icon } from '../_shared/Icon'
import { MessageActionsPopup } from './MessageActionsPopup'
import QuotedMessage from './QuotedMessage'
-import MD from '../Article/MD'
type Props = {
content: MessageType
diff --git a/src/components/Nav/ConfirmModal/ConfirmModal.module.scss b/src/components/Nav/ConfirmModal/ConfirmModal.module.scss
index deb8f946..b955ec59 100644
--- a/src/components/Nav/ConfirmModal/ConfirmModal.module.scss
+++ b/src/components/Nav/ConfirmModal/ConfirmModal.module.scss
@@ -1,48 +1,22 @@
.confirmModal {
- background: #fff;
- min-height: 550px;
position: relative;
- @include media-breakpoint-up(md) {
- min-height: 710px;
- }
-}
-
-.confirmModalTitle {
- font-size: 26px;
- line-height: 32px;
- font-weight: 700;
- color: #141414;
- text-align: left;
-}
-
-.confirmModalActions {
- display: flex;
- justify-content: space-between;
- margin-top: 16px;
-}
-
-.confirmModalButton {
- display: block;
- width: 100%;
- margin-right: 12px;
- font-weight: 700;
- margin-top: 32px;
- padding: 1.6rem !important;
- border: 1px solid black;
-
- &:hover {
- background-color: rgb(0 0 0 / 8%);
- }
-}
-
-.confirmModalButtonPrimary {
- margin-right: 0;
- background-color: black;
- color: white;
- border: none;
-
- &:hover {
- background-color: rgb(0 0 0 / 60%);
+ .confirmModalTitle {
+ @include font-size(2rem);
+
+ font-weight: 700;
+ color: var(--default-color);
+ text-align: center;
+ }
+
+ .confirmModalActions {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 4rem;
+ gap: 2rem;
+
+ .confirmAction {
+ flex: 1;
+ }
}
}
diff --git a/src/components/Nav/ConfirmModal/ConfirmModal.tsx b/src/components/Nav/ConfirmModal/ConfirmModal.tsx
index b224f0f0..63f6a767 100644
--- a/src/components/Nav/ConfirmModal/ConfirmModal.tsx
+++ b/src/components/Nav/ConfirmModal/ConfirmModal.tsx
@@ -1,7 +1,7 @@
-import { clsx } from 'clsx'
import { useConfirm } from '../../../context/confirm'
-import styles from './ConfirmModal.module.scss'
import { useLocalize } from '../../../context/localize'
+import { Button } from '../../_shared/Button'
+import styles from './ConfirmModal.module.scss'
export const ConfirmModal = () => {
const { t } = useLocalize()
@@ -12,21 +12,26 @@ export const ConfirmModal = () => {
} = useConfirm()
return (
-
+
{confirmMessage().confirmBody ?? t('Are you sure you want to to proceed the action?')}
-
-
)
diff --git a/src/components/Nav/Modal/Modal.module.scss b/src/components/Nav/Modal/Modal.module.scss
index ebc49a08..f69f99c2 100644
--- a/src/components/Nav/Modal/Modal.module.scss
+++ b/src/components/Nav/Modal/Modal.module.scss
@@ -71,8 +71,8 @@
}
.close {
- right: 3.6rem;
- top: 12px;
+ right: 1.6rem;
+ top: 1.6rem;
}
}
}
diff --git a/src/components/Nav/Modal/Modal.tsx b/src/components/Nav/Modal/Modal.tsx
index 929c7ab1..0b6e1415 100644
--- a/src/components/Nav/Modal/Modal.tsx
+++ b/src/components/Nav/Modal/Modal.tsx
@@ -1,4 +1,4 @@
-import { createEffect, createMemo, createSignal, on, Show } from 'solid-js'
+import { createEffect, createMemo, createSignal, Show } from 'solid-js'
import type { JSX } from 'solid-js'
import { clsx } from 'clsx'
import { hideModal, useModalStore } from '../../../stores/ui'
@@ -8,7 +8,6 @@ import styles from './Modal.module.scss'
import { redirectPage } from '@nanostores/router'
import { router } from '../../../stores/router'
import { Icon } from '../../_shared/Icon'
-import { resetSortedArticles } from '../../../stores/zine/articles'
interface Props {
name: string
diff --git a/src/components/NotificationsPanel/NotificationView/NotificationView.tsx b/src/components/NotificationsPanel/NotificationView/NotificationView.tsx
index 397572fb..079d3a73 100644
--- a/src/components/NotificationsPanel/NotificationView/NotificationView.tsx
+++ b/src/components/NotificationsPanel/NotificationView/NotificationView.tsx
@@ -1,7 +1,6 @@
import { clsx } from 'clsx'
import styles from './NotificationView.module.scss'
import type { Notification } from '../../../graphql/types.gen'
-import { formatDate } from '../../../utils'
import { createMemo, createSignal, onMount, Show } from 'solid-js'
import { NotificationType } from '../../../graphql/types.gen'
import { openPage } from '@nanostores/router'
@@ -9,7 +8,6 @@ import { router } from '../../../stores/router'
import { useNotifications } from '../../../context/notifications'
import { Userpic } from '../../Author/Userpic'
import { useLocalize } from '../../../context/localize'
-import notifications from '../../../graphql/query/notifications'
type Props = {
notification: Notification
diff --git a/src/components/NotificationsPanel/NotificationsPanel.tsx b/src/components/NotificationsPanel/NotificationsPanel.tsx
index ddfc66b2..4041dbed 100644
--- a/src/components/NotificationsPanel/NotificationsPanel.tsx
+++ b/src/components/NotificationsPanel/NotificationsPanel.tsx
@@ -4,7 +4,7 @@ import { useEscKeyDownHandler } from '../../utils/useEscKeyDownHandler'
import { useOutsideClickHandler } from '../../utils/useOutsideClickHandler'
import { useLocalize } from '../../context/localize'
import { Icon } from '../_shared/Icon'
-import { createEffect, For, onCleanup, onMount } from 'solid-js'
+import { createEffect, For } from 'solid-js'
import { useNotifications } from '../../context/notifications'
import { NotificationView } from './NotificationView'
diff --git a/src/components/Views/Author/Author.tsx b/src/components/Views/Author/Author.tsx
index d9ff4217..2eafec93 100644
--- a/src/components/Views/Author/Author.tsx
+++ b/src/components/Views/Author/Author.tsx
@@ -16,7 +16,6 @@ import { apiClient } from '../../../utils/apiClient'
import { Comment } from '../../Article/Comment'
import { useLocalize } from '../../../context/localize'
import { AuthorRatingControl } from '../../Author/AuthorRatingControl'
-import { hideModal } from '../../../stores/ui'
import { getPagePath } from '@nanostores/router'
import { useSession } from '../../../context/session'
import { Loading } from '../../_shared/Loading'
diff --git a/src/components/_shared/Button/Button.module.scss b/src/components/_shared/Button/Button.module.scss
index 5a6c786b..cb20f387 100644
--- a/src/components/_shared/Button/Button.module.scss
+++ b/src/components/_shared/Button/Button.module.scss
@@ -31,6 +31,17 @@
}
}
+ &.danger {
+ border: 3px solid var(--danger-color);
+ background: var(--background-color);
+ color: var(--danger-color);
+
+ &:hover {
+ background: var(--danger-color);
+ color: #fff;
+ }
+ }
+
&.inline {
font-weight: 700;
font-size: 16px;
diff --git a/src/components/_shared/Button/Button.tsx b/src/components/_shared/Button/Button.tsx
index 42d7d5ec..e892ef5e 100644
--- a/src/components/_shared/Button/Button.tsx
+++ b/src/components/_shared/Button/Button.tsx
@@ -2,10 +2,11 @@ import type { JSX } from 'solid-js'
import { clsx } from 'clsx'
import styles from './Button.module.scss'
+export type ButtonVariant = 'primary' | 'secondary' | 'bordered' | 'inline' | 'light' | 'outline' | 'danger'
type Props = {
value: string | JSX.Element
size?: 'S' | 'M' | 'L'
- variant?: 'primary' | 'secondary' | 'bordered' | 'inline' | 'light' | 'outline'
+ variant?: ButtonVariant
type?: 'submit' | 'button'
loading?: boolean
disabled?: boolean
diff --git a/src/context/confirm.tsx b/src/context/confirm.tsx
index 61c6875a..a4a4f745 100644
--- a/src/context/confirm.tsx
+++ b/src/context/confirm.tsx
@@ -2,11 +2,14 @@ import { createContext, createSignal, useContext } from 'solid-js'
import type { Accessor, JSX } from 'solid-js'
import { hideModal, showModal } from '../stores/ui'
+import { ButtonVariant } from '../components/_shared/Button/Button'
type ConfirmMessage = {
confirmBody?: string | JSX.Element
confirmButtonLabel?: string
+ confirmButtonVariant?: ButtonVariant
declineButtonLabel?: string
+ declineButtonVariant?: ButtonVariant
}
type ConfirmContextType = {
@@ -15,7 +18,9 @@ type ConfirmContextType = {
showConfirm: (message?: {
confirmBody?: ConfirmMessage['confirmBody']
confirmButtonLabel?: ConfirmMessage['confirmButtonLabel']
+ confirmButtonVariant?: ConfirmMessage['confirmButtonVariant']
declineButtonLabel?: ConfirmMessage['declineButtonLabel']
+ declineButtonVariant?: ConfirmMessage['declineButtonVariant']
}) => Promise
resolveConfirm: (value: boolean) => void
}
@@ -36,13 +41,17 @@ export const ConfirmProvider = (props: { children: JSX.Element }) => {
message: {
confirmBody?: ConfirmMessage['confirmBody']
confirmButtonLabel?: ConfirmMessage['confirmButtonLabel']
+ confirmButtonVariant?: ConfirmMessage['confirmButtonVariant']
declineButtonLabel?: ConfirmMessage['declineButtonLabel']
+ declineButtonVariant?: ConfirmMessage['declineButtonVariant']
} = {}
): Promise => {
const messageToShow = {
confirmBody: message.confirmBody,
confirmButtonLabel: message.confirmButtonLabel,
- declineButtonLabel: message.declineButtonLabel
+ confirmButtonVariant: message.confirmButtonVariant,
+ declineButtonLabel: message.declineButtonLabel,
+ declineButtonVariant: message.declineButtonVariant
}
setConfirmMessage(messageToShow)
From 9262367f688d31b92f1ea9f5b6573bf18e45b570 Mon Sep 17 00:00:00 2001
From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com>
Date: Mon, 16 Oct 2023 20:24:33 +0300
Subject: [PATCH 2/2] notification system update (#265)
* notification system update
Co-authored-by: Igor Lobanov
---
public/locales/en/translation.json | 15 +++-
public/locales/ru/translation.json | 14 +++-
src/components/Article/Comment.tsx | 4 +-
src/components/Article/CommentsTree.tsx | 2 +-
src/components/Article/FullArticle.tsx | 31 +++++--
src/components/Nav/Header/Header.tsx | 2 +-
.../EmptyMessage/EmptyMessage.module.scss | 12 +++
.../EmptyMessage/EmptyMessage.tsx | 14 ++++
.../NotificationsPanel/EmptyMessage/index.ts | 1 +
.../NotificationView.module.scss | 7 ++
.../NotificationView/NotificationView.tsx | 83 +++++++++++++------
.../NotificationsPanel/NotificationsPanel.tsx | 20 ++++-
src/context/notifications.tsx | 7 +-
src/pages/article.page.tsx | 13 +--
14 files changed, 162 insertions(+), 63 deletions(-)
create mode 100644 src/components/NotificationsPanel/EmptyMessage/EmptyMessage.module.scss
create mode 100644 src/components/NotificationsPanel/EmptyMessage/EmptyMessage.tsx
create mode 100644 src/components/NotificationsPanel/EmptyMessage/index.ts
diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index 1f5e43b4..577ddfcf 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -210,12 +210,19 @@
"New only": "New only",
"New password": "New password",
"New stories every day and even more!": "New stories and more are waiting for you every day!",
- "NewCommentNotificationText": "{commentsCount, plural, one {New comment} other {{commentsCount} comments}} to your publication {shoutTitle} from {lastCommenterName}{restUsersCount, plural, =0 {} one { one more user} other { and more {restUsersCount} users}}",
- "NewReplyNotificationText": "{commentsCount, plural, one {New reply} other {{commentsCount} replays} other {{commentsCount} новых ответов}} to your publication {shoutTitle} от {lastCommenterName}{restUsersCount, plural, =0 {} one { and one more user} other { and more {restUsersCount} users}}",
+
+ "NotificationNewCommentText1": "{commentsCount, plural, one {New comment} other {{commentsCount} comments}} to your publication",
+ "NotificationNewCommentText2": "from",
+ "NotificationNewCommentText3": "{restUsersCount, plural, =0 {} one { one more user} other { and more {restUsersCount} users}}",
+
+ "NotificationNewReplyText1": "{commentsCount, plural, one {New reply} other {{commentsCount} replays}} to your publication",
+ "NotificationNewReplyText2": "from",
+ "NotificationNewReplyText3": "{restUsersCount, plural, =0 {} one { and one more user} other { and more {restUsersCount} users}}",
+
"Newsletter": "Newsletter",
"Night mode": "Night mode",
- "No notifications, yet": "No notifications, yet",
- "No such account, please try to register": "No such account found, please try to register",
+ "No notifications yet": "No notifications yet",
+ "Write good articles, comment\nand it won't be so empty here": "Write good articles, comment\nand it won't be so empty here",
"Nothing here yet": "There's nothing here yet",
"Nothing is here": "There is nothing here",
"Notifications": "Notifications",
diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json
index cb2559b3..a263456e 100644
--- a/public/locales/ru/translation.json
+++ b/public/locales/ru/translation.json
@@ -220,11 +220,19 @@
"New only": "Только новые",
"New password": "Новый пароль",
"New stories every day and even more!": "Каждый день вас ждут новые истории и ещё много всего интересного!",
- "NewCommentNotificationText": "{commentsCount, plural, one {Новый комментарий} few {{commentsCount} новых комментария} other {{commentsCount} новых комментариев}} к вашей публикации {shoutTitle} от {lastCommenterName}{restUsersCount, plural, =0 {} one { и ещё 1 пользователя} few { и ещё {restUsersCount} пользователей} other { и ещё {restUsersCount} пользователей}}",
- "NewReplyNotificationText": "{commentsCount, plural, one {Новый ответ} few {{commentsCount} новых ответа} other {{commentsCount} новых ответов}} к вашему комментарию к публикации {shoutTitle} от {lastCommenterName}{restUsersCount, plural, =0 {} one { и ещё 1 пользователя} few { и ещё {restUsersCount} пользователей} other { и ещё {restUsersCount} пользователей}}",
+
+ "NotificationNewCommentText1": "{commentsCount, plural, one {Новый комментарий} few {{commentsCount} новых комментария} other {{commentsCount} новых комментариев}} к вашей публикации",
+ "NotificationNewCommentText2": "от",
+ "NotificationNewCommentText3": "{restUsersCount, plural, =0 {} one { и ещё 1 пользователя} few { и ещё {restUsersCount} пользователей} other { и ещё {restUsersCount} пользователей}}",
+
+ "NotificationNewReplyText1": "{commentsCount, plural, one {Новый ответ} few {{commentsCount} новых ответа} other {{commentsCount} новых ответов}} к вашему комментарию к публикации",
+ "NotificationNewReplyText2": "от",
+ "NotificationNewReplyText3": "{restUsersCount, plural, =0 {} one { и ещё 1 пользователя} few { и ещё {restUsersCount} пользователей} other { и ещё {restUsersCount} пользователей}}",
+
"Newsletter": "Рассылка",
"Night mode": "Ночная тема",
- "No notifications, yet": "Тут пока пусто",
+ "No notifications yet": "Уведомлений пока нет",
+ "Write good articles, comment\nand it won't be so empty here": "Пишите хорошие статьи, комментируйте,\nи здесь станет не так пусто",
"No such account, please try to register": "Такой адрес не найден, попробуйте зарегистрироваться",
"Nothing here yet": "Здесь пока ничего нет",
"Nothing is here": "Здесь ничего нет",
diff --git a/src/components/Article/Comment.tsx b/src/components/Article/Comment.tsx
index 823a59f7..3405b49b 100644
--- a/src/components/Article/Comment.tsx
+++ b/src/components/Article/Comment.tsx
@@ -141,7 +141,7 @@ export const Comment = (props: Props) => {
})}
/>
- {comment()?.shout.title || ''}
+ {comment()?.shout.title || ''}
}
@@ -179,7 +179,7 @@ export const Comment = (props: Props) => {
- }
- >
+ }>
{(notification) => (
actions: {
showNotificationsPanel: () => void
+ hideNotificationsPanel: () => void
markNotificationAsRead: (notification: Notification) => Promise
}
}
@@ -80,7 +81,11 @@ export const NotificationsProvider = (props: { children: JSX.Element }) => {
setIsNotificationsPanelOpen(true)
}
- const actions = { showNotificationsPanel, markNotificationAsRead }
+ const hideNotificationsPanel = () => {
+ setIsNotificationsPanelOpen(false)
+ }
+
+ const actions = { showNotificationsPanel, hideNotificationsPanel, markNotificationAsRead }
const value: NotificationsContextType = {
notificationEntities,
diff --git a/src/pages/article.page.tsx b/src/pages/article.page.tsx
index c522b76d..c5ed9aac 100644
--- a/src/pages/article.page.tsx
+++ b/src/pages/article.page.tsx
@@ -11,18 +11,9 @@ import { setPageLoadManagerPromise } from '../utils/pageLoadManager'
export const ArticlePage = (props: PageProps) => {
const shouts = props.article ? [props.article] : []
+ const { page } = useRouter()
- const slug = createMemo(() => {
- const { page: getPage } = useRouter()
-
- const page = getPage()
-
- if (page.route !== 'article') {
- throw new Error('ts guard')
- }
-
- return page.params.slug
- })
+ const slug = createMemo(() => page().params['slug'] as string)
const { articleEntities } = useArticlesStore({
shouts