add draft version of useConfirm (#149)

* add draft version of useConfirm

* Add resolveConfirm

* added translations

---------

Co-authored-by: ilya-bkv <i.yablokov@ccmp.me>
Co-authored-by: bniwredyc <bniwredyc@gmail.com>
This commit is contained in:
Arkadzi Rakouski 2023-08-01 00:24:41 +03:00 committed by GitHub
parent d37dd134b5
commit fd2841ab6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 218 additions and 25 deletions

View File

@ -21,6 +21,7 @@
"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 to proceed the action?": "Are you sure you want to to proceed the action?",
"Artist": "Artist",
"Artworks": "Artworks",
"Audio": "Audio",
@ -46,6 +47,7 @@
"By title": "By title",
"By updates": "By updates",
"By views": "By views",
"Cancel": "Cancel",
"Characters": "Знаков",
"Chat Title": "Chat Title",
"Choose a post type": "Choose a post type",
@ -54,6 +56,7 @@
"Collaborate": "Help Edit",
"Comments": "Comments",
"Communities": "Communities",
"Confirm": "Confirm",
"Cooperate": "Cooperate",
"Copy": "Copy",
"Copy link": "Copy link",
@ -70,6 +73,7 @@
"Create post": "Create post",
"Create video": "Create video",
"Date of Birth": "Date of Birth",
"Decline": "Decline",
"Delete": "Delete",
"Description": "Description...",
"Discours": "Discours",
@ -96,10 +100,6 @@
"Enter the Discours to subscribe": "Enter the Discours to subscribe",
"Enter the Discours to subscribe to new publications": "Enter the Discours to subscribe to new publications",
"Enter the Discours to vote": "Enter the Discours to vote",
"In&nbsp;bookmarks, you can save favorite discussions and&nbsp;materials that you want to return to": "In&nbsp;bookmarks, you can save favorite discussions and&nbsp;materials that you want to return to",
"You&nbsp;ll be able to participate in&nbsp;discussions, rate others' comments and&nbsp;learn about&nbsp;new responses": "You&nbsp;ll be able to participate in&nbsp;discussions, rate others' comments and&nbsp;learn about&nbsp;new responses",
"This way you&nbsp;ll be able to subscribe to&nbsp;authors, interesting topics and&nbsp;customize your feed": "This way you&nbsp;ll be able to subscribe to&nbsp;authors, interesting topics and&nbsp;customize your feed",
"This way we&nbsp;ll realize that you&nbsp;re a real person and&nbsp;ll take your vote into account. And&nbsp;you&nbsp;ll see how others voted": "This way we&nbsp;ll realize that you&nbsp;re a real person and&nbsp;ll take your vote into account. And&nbsp;you&nbsp;ll see how others voted",
"Enter the code or click the link from email to confirm": "Enter the code from the email or follow the link in the email to confirm registration",
"Enter your new password": "Enter your new password",
"Error": "Error",
@ -142,6 +142,7 @@
"I have no account yet": "I don't have an account yet",
"I know the password": "I know the password",
"Image format not supported": "Image format not supported",
"In&nbsp;bookmarks, you can save favorite discussions and&nbsp;materials that you want to return to": "In&nbsp;bookmarks, you can save favorite discussions and&nbsp;materials that you want to return to",
"Incut": "Incut",
"Independant magazine with an open horizontal cooperation about culture, science and society": "Independant magazine with an open horizontal cooperation about culture, science and society",
"Insert footnote": "Insert footnote",
@ -265,6 +266,7 @@
"Subscription": "Subscription",
"Subscriptions": "Subscriptions",
"Substrate": "Substrate",
"Success": "Success",
"Successfully authorized": "Authorization successful",
"Suggest an idea": "Suggest an idea",
"Support us": "Help the magazine",
@ -275,6 +277,8 @@
"This email is already taken. If it's you": "This email is already taken. If it's you",
"This functionality is currently not available, we would like to work on this issue. Use the download link.": "This functionality is currently not available, we would like to work on this issue. Use the download link.",
"This post has not been rated yet": "This post has not been rated yet",
"This way we&nbsp;ll realize that you&nbsp;re a real person and&nbsp;ll take your vote into account. And&nbsp;you&nbsp;ll see how others voted": "This way we&nbsp;ll realize that you&nbsp;re a real person and&nbsp;ll take your vote into account. And&nbsp;you&nbsp;ll see how others voted",
"This way you&nbsp;ll be able to subscribe to&nbsp;authors, interesting topics and&nbsp;customize your feed": "This way you&nbsp;ll be able to subscribe to&nbsp;authors, interesting topics and&nbsp;customize your feed",
"To leave a comment please": "To leave a comment please",
"To write a comment, you must": "To write a comment, you must",
"Top authors": "Authors rating",
@ -318,6 +322,7 @@
"You are subscribed": "You are subscribed",
"You can download multiple tracks at once in .mp3, .wav or .flac formats": "You can download multiple tracks at once in .mp3, .wav or .flac formats",
"You were successfully authorized": "You were successfully authorized",
"You&nbsp;ll be able to participate in&nbsp;discussions, rate others' comments and&nbsp;learn about&nbsp;new responses": "You&nbsp;ll be able to participate in&nbsp;discussions, rate others' comments and&nbsp;learn about&nbsp;new responses",
"You've confirmed email": "You've confirmed email",
"You've reached a non-existed page": "You've reached a non-existed page",
"Your name will appear on your profile page and as your signature in publications, comments and responses.": "Your name will appear on your profile page and as your signature in publications, comments and responses",
@ -331,7 +336,6 @@
"back to menu": "back to menu",
"bold": "bold",
"bookmarks": "bookmarks",
"Cancel": "Cancel",
"cancel": "cancel",
"collections": "collections",
"community": "community",

View File

@ -24,6 +24,7 @@
"All posts": "Все публикации",
"All topics": "Все темы",
"Almost done! Check your email.": "Почти готово! Осталось подтвердить вашу почту.",
"Are you sure you want to to proceed the action?": "Вы уверены, что хотите продолжить?",
"Artist": "Исполнитель",
"Artist...": "Исполнитель...",
"Artworks": "Артворки",
@ -50,6 +51,7 @@
"By title": "По названию",
"By updates": "По обновлениям",
"By views": "По просмотрам",
"Cancel": "Отмена",
"Characters": "Знаков",
"Chat Title": "Тема дискурса",
"Choose a post type": "Выберите тип публикации",
@ -58,6 +60,7 @@
"Collaborate": "Помочь редактировать",
"Comments": "Комментарии",
"Communities": "Сообщества",
"Confirm": "Подтвердить",
"Cooperate": "Соучаствовать",
"Copy": "Скопировать",
"Copy link": "Скопировать ссылку",
@ -74,6 +77,7 @@
"Create post": "Создать публикацию",
"Create video": "Создать видео",
"Date of Birth": "Дата рождения",
"Decline": "Отмена",
"Delete": "Удалить",
"Description": "Описание...",
"Discours": "Дискурс",
@ -98,13 +102,9 @@
"Enter the Discours": "Войти в Дискурс",
"Enter the Discours to add to your bookmarks": "Войдите в Дискурс, чтобы добавить в закладки",
"Enter the Discours to participate in discussions": "Войдите в Дискурс для участия в дискуссиях",
"Enter the Discours to subscribe to new publications": "Войдите в Дискурс, чтобы подписаться",
"Enter the Discours to subscribe": "Войдите в Дискурс для подписки на новые публикации",
"Enter the Discours to subscribe to new publications": "Войдите в Дискурс, чтобы подписаться",
"Enter the Discours to vote": "Войдите в Дискурс, чтобы голосовать",
"In&nbsp;bookmarks, you can save favorite discussions and&nbsp;materials that you want to return to": "В&nbsp;закладках можно сохранять избранные дискуссии и&nbsp;материалы, к&nbsp;которым хочется вернуться",
"You&nbsp;ll be able to participate in&nbsp;discussions, rate others' comments and&nbsp;learn about&nbsp;new responses": "Вы&nbsp;сможете участвовать в&nbsp;обсуждениях, оценивать комментарии других и&nbsp;узнавать о&nbsp;новых ответах",
"This way you&nbsp;ll be able to subscribe to&nbsp;authors, interesting topics and&nbsp;customize your feed": "Так вы&nbsp;сможете подписаться на&nbsp;авторов, интересные темы и&nbsp;настроить свою ленту",
"This way we&nbsp;ll realize that you&nbsp;re a real person and&nbsp;ll take your vote into account. And&nbsp;you&nbsp;ll see how others voted": "Так мы&nbsp;поймем, что вы&nbsp;реальный человек, и&nbsp;учтем ваш голос. А&nbsp;вы&nbsp;увидите, как проголосовали другие",
"Enter the code or click the link from email to confirm": "Введите код из письма или пройдите по ссылке в письме для подтверждения регистрации",
"Enter your new password": "Введите новый пароль",
"Error": "Ошибка",
@ -150,6 +150,7 @@
"I have no account yet": "У меня еще нет аккаунта",
"I know the password": "Я знаю пароль!",
"Image format not supported": "Тип изображения не поддерживается",
"In&nbsp;bookmarks, you can save favorite discussions and&nbsp;materials that you want to return to": "В&nbsp;закладках можно сохранять избранные дискуссии и&nbsp;материалы, к&nbsp;которым хочется вернуться",
"Incut": "Подверстка",
"Independant magazine with an open horizontal cooperation about culture, science and society": "Независимый журнал с открытой горизонтальной редакцией о культуре, науке и обществе",
"Insert footnote": "Вставить сноску",
@ -282,6 +283,7 @@
"Subscription": "Подписка",
"Subscriptions": "Подписки",
"Substrate": "Подложка",
"Success": "Успешно",
"Successfully authorized": "Авторизация успешна",
"Suggest an idea": "Предложить идею",
"Support us": "Помочь журналу",
@ -292,6 +294,8 @@
"This email is already taken. If it's you": "Такой email уже зарегистрирован. Если это вы",
"This functionality is currently not available, we would like to work on this issue. Use the download link.": "В данный момент этот функционал не доступен, бы работаем над этой проблемой. Воспользуйтесь загрузкой по ссылке.",
"This post has not been rated yet": "Эту публикацию еще пока никто не оценил",
"This way we&nbsp;ll realize that you&nbsp;re a real person and&nbsp;ll take your vote into account. And&nbsp;you&nbsp;ll see how others voted": "Так мы&nbsp;поймем, что вы&nbsp;реальный человек, и&nbsp;учтем ваш голос. А&nbsp;вы&nbsp;увидите, как проголосовали другие",
"This way you&nbsp;ll be able to subscribe to&nbsp;authors, interesting topics and&nbsp;customize your feed": "Так вы&nbsp;сможете подписаться на&nbsp;авторов, интересные темы и&nbsp;настроить свою ленту",
"To leave a comment please": "Чтобы оставить комментарий, необходимо",
"To write a comment, you must": "Чтобы написать комментарий, необходимо",
"Top authors": "Рейтинг авторов",
@ -336,6 +340,7 @@
"You are subscribed": "Вы подписаны",
"You can download multiple tracks at once in .mp3, .wav or .flac formats": "Можно загрузить сразу несколько треков в форматах .mp3, .wav или .flac",
"You was successfully authorized": "Вы были успешно авторизованы",
"You&nbsp;ll be able to participate in&nbsp;discussions, rate others' comments and&nbsp;learn about&nbsp;new responses": "Вы&nbsp;сможете участвовать в&nbsp;обсуждениях, оценивать комментарии других и&nbsp;узнавать о&nbsp;новых ответах",
"You've confirmed email": "Вы подтвердили почту",
"You've reached a non-existed page": "Вы попали на несуществующую страницу",
"You've successfully logged out": "Вы успешно вышли из аккаунта",
@ -349,7 +354,6 @@
"back to menu": "назад в меню",
"bold": "жирный",
"bookmarks": "закладки",
"Cancel": "Отмена",
"cancel": "отменить",
"collections": "коллекции",
"community": "сообщество",

View File

@ -38,6 +38,7 @@ import { ProfileSubscriptionsPage } from '../pages/profile/profileSubscriptions.
import { DraftsPage } from '../pages/drafts.page'
import { SnackbarProvider } from '../context/snackbar'
import { LocalizeProvider } from '../context/localize'
import { ConfirmProvider } from '../context/confirm'
import { EditorProvider } from '../context/editor'
// TODO: lazy load
@ -103,11 +104,13 @@ export const App = (props: PageProps) => {
return (
<LocalizeProvider>
<SnackbarProvider>
<ConfirmProvider>
<SessionProvider>
<EditorProvider>
<Dynamic component={pageComponent()} {...props} />
</EditorProvider>
</SessionProvider>
</ConfirmProvider>
</SnackbarProvider>
</LocalizeProvider>
)

View File

@ -5,6 +5,8 @@ import { Icon } from '../_shared/Icon'
import { formatDate } from '../../utils'
import formatDateTime from '../../utils/formatDateTime'
import { useLocalize } from '../../context/localize'
import { useConfirm } from '../../context/confirm'
import { useSnackbar } from '../../context/snackbar'
import { getPagePath } from '@nanostores/router'
import { router } from '../../stores/router'
@ -17,15 +19,28 @@ type Props = {
export const Draft = (props: Props) => {
const { t } = useLocalize()
const {
actions: { showConfirm }
} = useConfirm()
const {
actions: { showSnackbar }
} = useSnackbar()
const handlePublishLinkClick = (e) => {
e.preventDefault()
props.onPublish(props.shout)
}
const handleDeleteLinkClick = (e) => {
const handleDeleteLinkClick = async (e) => {
e.preventDefault()
const isConfirmed = await showConfirm()
if (isConfirmed) {
props.onDelete(props.shout)
await showSnackbar({ type: 'success', body: t('Success') })
}
}
return (

View File

@ -0,0 +1,52 @@
.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: rgba(0, 0, 0, 0.08);
}
}
.confirmModalButtonPrimary {
margin-right: 0;
background-color: black;
color: white;
border: none;
&:hover {
background-color: rgba(0, 0, 0, 0.6);
}
}

View File

@ -0,0 +1,33 @@
import { clsx } from 'clsx'
import { useConfirm } from '../../../context/confirm'
import styles from './ConfirmModal.module.scss'
import { useLocalize } from '../../../context/localize'
export const ConfirmModal = () => {
const { t } = useLocalize()
const {
confirmMessage,
actions: { resolveConfirm }
} = useConfirm()
return (
<div>
<h4 class={styles.confirmModalTitle}>
{confirmMessage().confirmBody ?? t('Are you sure you want to to proceed the action?')}
</h4>
<div class={styles.confirmModalActions}>
<button class={styles.confirmModalButton} onClick={() => resolveConfirm(false)}>
{confirmMessage().declineButtonLabel ?? t('Decline')}
</button>
<button
class={clsx(styles.confirmModalButton, styles.confirmModalButtonPrimary)}
onClick={() => resolveConfirm(true)}
>
{confirmMessage().confirmButtonLabel ?? t('Confirm')}
</button>
</div>
</div>
)
}

View File

@ -0,0 +1 @@
export { ConfirmModal } from './ConfirmModal'

View File

@ -1,18 +1,24 @@
import { Show, createSignal, createEffect, onMount, onCleanup } from 'solid-js'
import { Icon } from '../_shared/Icon'
import { Modal } from './Modal'
import { AuthModal } from './AuthModal'
import { useModalStore } from '../../stores/ui'
import { router, useRouter } from '../../stores/router'
import styles from './Header.module.scss'
import { getPagePath } from '@nanostores/router'
import { clsx } from 'clsx'
import { Modal } from './Modal'
import { AuthModal } from './AuthModal'
import { HeaderAuth } from './HeaderAuth'
import { ConfirmModal } from './ConfirmModal'
import { getShareUrl, SharePopup } from '../Article/SharePopup'
import { getDescription } from '../../utils/meta'
import { Snackbar } from './Snackbar'
import { Icon } from '../_shared/Icon'
import { useModalStore } from '../../stores/ui'
import { router, useRouter } from '../../stores/router'
import { getDescription } from '../../utils/meta'
import { useLocalize } from '../../context/localize'
import styles from './Header.module.scss'
type Props = {
title?: string
slug?: string
@ -95,6 +101,10 @@ export const Header = (props: Props) => {
<AuthModal />
</Modal>
<Modal variant="narrow" name="confirm">
<ConfirmModal />
</Modal>
<div class={clsx(styles.mainHeaderInner, 'wide-container')}>
<nav class={clsx('row', styles.headerInner, { ['fixed']: fixed() })}>
<div class={clsx('col-md-5 col-xl-4 col-auto', styles.mainLogo)}>

69
src/context/confirm.tsx Normal file
View File

@ -0,0 +1,69 @@
import { createContext, createSignal, useContext } from 'solid-js'
import type { Accessor, JSX } from 'solid-js'
import { hideModal, showModal } from '../stores/ui'
type ConfirmMessage = {
confirmBody?: string | JSX.Element
confirmButtonLabel?: string
declineButtonLabel?: string
}
type ConfirmContextType = {
confirmMessage: Accessor<ConfirmMessage>
actions: {
showConfirm: (message?: {
confirmBody?: ConfirmMessage['confirmBody']
confirmButtonLabel?: ConfirmMessage['confirmButtonLabel']
declineButtonLabel?: ConfirmMessage['declineButtonLabel']
}) => Promise<boolean>
resolveConfirm: (value: boolean) => void
}
}
const ConfirmContext = createContext<ConfirmContextType>()
export function useConfirm() {
return useContext(ConfirmContext)
}
export const ConfirmProvider = (props: { children: JSX.Element }) => {
const [confirmMessage, setConfirmMessage] = createSignal<ConfirmMessage>(null)
let resolveFn: (value: boolean) => void
const showConfirm = (
message: {
confirmBody?: ConfirmMessage['confirmBody']
confirmButtonLabel?: ConfirmMessage['confirmButtonLabel']
declineButtonLabel?: ConfirmMessage['declineButtonLabel']
} = {}
): Promise<boolean> => {
const messageToShow = {
confirmBody: message.confirmBody,
confirmButtonLabel: message.confirmButtonLabel,
declineButtonLabel: message.declineButtonLabel
}
setConfirmMessage(messageToShow)
showModal('confirm')
return new Promise((resolve) => {
resolveFn = resolve
})
}
const resolveConfirm = (value: boolean) => {
resolveFn(value)
hideModal()
}
const actions = {
showConfirm,
resolveConfirm
}
const value: ConfirmContextType = { confirmMessage, actions }
return <ConfirmContext.Provider value={value}>{props.children}</ConfirmContext.Provider>
}

View File

@ -12,6 +12,7 @@ export type ModalType =
| 'subscribe'
| 'feedback'
| 'thank'
| 'confirm'
| 'donate'
| 'inviteToChat'
| 'uploadImage'
@ -31,6 +32,7 @@ export const MODALS: Record<ModalType, ModalType> = {
subscribe: 'subscribe',
feedback: 'feedback',
thank: 'thank',
confirm: 'confirm',
donate: 'donate',
inviteToChat: 'inviteToChat',
uploadImage: 'uploadImage',