drafts-view-refactoring+fix
This commit is contained in:
parent
217c027044
commit
6f26e09bef
|
@ -3,7 +3,7 @@ import { Component, Show, createEffect, createMemo } from 'solid-js'
|
||||||
import { Dynamic } from 'solid-js/web'
|
import { Dynamic } from 'solid-js/web'
|
||||||
|
|
||||||
import { useLocalize } from '~/context/localize'
|
import { useLocalize } from '~/context/localize'
|
||||||
import { AuthModalSource, useUI } from '~/context/ui'
|
import { ModalSource, useUI } from '~/context/ui'
|
||||||
import { isMobile } from '~/lib/mediaQuery'
|
import { isMobile } from '~/lib/mediaQuery'
|
||||||
import { ChangePasswordForm } from './ChangePasswordForm'
|
import { ChangePasswordForm } from './ChangePasswordForm'
|
||||||
import { EmailConfirm } from './EmailConfirm'
|
import { EmailConfirm } from './EmailConfirm'
|
||||||
|
@ -25,7 +25,7 @@ export type AuthModalMode =
|
||||||
|
|
||||||
export type AuthModalSearchParams = {
|
export type AuthModalSearchParams = {
|
||||||
mode: AuthModalMode
|
mode: AuthModalMode
|
||||||
source?: AuthModalSource
|
source?: ModalSource
|
||||||
token?: string
|
token?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
.draft {
|
||||||
|
margin-bottom: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
.created {
|
.created {
|
||||||
@include font-size(1.2rem);
|
@include font-size(1.2rem);
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
|
import { A } from '@solidjs/router'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
|
|
||||||
import { useLocalize } from '~/context/localize'
|
import { useLocalize } from '~/context/localize'
|
||||||
import { useSnackbar, useUI } from '~/context/ui'
|
import { useSnackbar, useUI } from '~/context/ui'
|
||||||
import type { Shout } from '~/graphql/schema/core.gen'
|
import type { Shout } from '~/graphql/schema/core.gen'
|
||||||
import { Icon } from '../_shared/Icon'
|
import { Icon } from '../_shared/Icon'
|
||||||
|
|
||||||
import { A } from '@solidjs/router'
|
|
||||||
import styles from './Draft.module.scss'
|
import styles from './Draft.module.scss'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
class?: string
|
|
||||||
shout: Shout
|
shout: Shout
|
||||||
onPublish: (shout: Shout) => void
|
onPublish: (shout: Shout) => void
|
||||||
onDelete: (shout: Shout) => void
|
onDelete: (shout: Shout) => void
|
||||||
|
@ -46,7 +44,7 @@ export const Draft = (props: Props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={clsx(props.class)}>
|
<div class={styles.draft}>
|
||||||
<div class={styles.created}>
|
<div class={styles.created}>
|
||||||
<Icon name="pencil-outline" class={styles.icon} />{' '}
|
<Icon name="pencil-outline" class={styles.icon} />{' '}
|
||||||
{formatDate(new Date(props.shout.created_at * 1000), { hour: '2-digit', minute: '2-digit' })}
|
{formatDate(new Date(props.shout.created_at * 1000), { hour: '2-digit', minute: '2-digit' })}
|
||||||
|
|
67
src/components/Draft/LayoutSelector.tsx
Normal file
67
src/components/Draft/LayoutSelector.tsx
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
import { useNavigate } from '@solidjs/router'
|
||||||
|
import clsx from 'clsx'
|
||||||
|
import { For } from 'solid-js'
|
||||||
|
import { useEditorContext } from '~/context/editor'
|
||||||
|
import { useLocalize } from '~/context/localize'
|
||||||
|
import { useSession } from '~/context/session'
|
||||||
|
import { useSnackbar } from '~/context/ui'
|
||||||
|
import createShoutMutation from '~/graphql/mutation/core/article-create'
|
||||||
|
import { LayoutType } from '~/types/common'
|
||||||
|
import { Button } from '../_shared/Button'
|
||||||
|
import { Icon } from '../_shared/Icon'
|
||||||
|
|
||||||
|
import styles from './LayoutSelector.module.scss'
|
||||||
|
|
||||||
|
export const LayoutSelector = () => {
|
||||||
|
const { t } = useLocalize()
|
||||||
|
const { client } = useSession()
|
||||||
|
const { saveDraftToLocalStorage } = useEditorContext()
|
||||||
|
const { showSnackbar } = useSnackbar()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
const handleCreate = async (layout: LayoutType) => {
|
||||||
|
console.debug('[routes : edit/new] handling create click...')
|
||||||
|
const result = await client()
|
||||||
|
?.mutation(createShoutMutation, { shout: { layout: layout } })
|
||||||
|
.toPromise()
|
||||||
|
if (result) {
|
||||||
|
console.debug(result)
|
||||||
|
const { shout, error } = result.data.create_shout
|
||||||
|
if (error) {
|
||||||
|
showSnackbar({
|
||||||
|
body: `${t('Error')}: ${t(error)}`,
|
||||||
|
type: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (shout?.id) {
|
||||||
|
saveDraftToLocalStorage({
|
||||||
|
shoutId: shout.id,
|
||||||
|
selectedTopics: shout.topics,
|
||||||
|
slug: shout.slug,
|
||||||
|
title: '',
|
||||||
|
body: ''
|
||||||
|
})
|
||||||
|
navigate(`/edit/${shout.id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<article class={clsx('wide-container', 'container--static-page', styles.Create)}>
|
||||||
|
<h1>{t('Choose a post type')}</h1>
|
||||||
|
<ul class={clsx('nodash', styles.list)}>
|
||||||
|
<For each={['Article', 'Literature', 'Image', 'Audio', 'Video']}>
|
||||||
|
{(layout: string) => (
|
||||||
|
<li onClick={() => handleCreate(layout.toLowerCase() as LayoutType)}>
|
||||||
|
<div class={styles.link}>
|
||||||
|
<Icon name={`create-${layout.toLowerCase()}`} class={styles.icon} />
|
||||||
|
<div>{t(layout)}</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</ul>
|
||||||
|
<Button value={t('Back')} onClick={() => window?.history.back()} />
|
||||||
|
</article>
|
||||||
|
)
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ import { Modal } from '../../_shared/Modal'
|
||||||
import { Menu } from './Menu'
|
import { Menu } from './Menu'
|
||||||
import type { MenuItem } from './Menu/Menu'
|
import type { MenuItem } from './Menu/Menu'
|
||||||
|
|
||||||
import styles from './EditorFloatingMenu.module.scss'
|
import styles from '../EditorFloatingMenu/EditorFloatingMenu.module.scss'
|
||||||
|
|
||||||
type FloatingMenuProps = {
|
type FloatingMenuProps = {
|
||||||
editor: Editor
|
editor: Editor
|
||||||
|
|
54
src/components/Feed/RandomTopicSwiper.tsx
Normal file
54
src/components/Feed/RandomTopicSwiper.tsx
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import { Show, createEffect, createSignal, on } from 'solid-js'
|
||||||
|
import { useAuthors } from '~/context/authors'
|
||||||
|
import { useLocalize } from '~/context/localize'
|
||||||
|
import { useTopics } from '~/context/topics'
|
||||||
|
import { loadShouts } from '~/graphql/api/public'
|
||||||
|
import { Author, Shout, Topic } from '~/graphql/schema/core.gen'
|
||||||
|
import { capitalize } from '~/utils/capitalize'
|
||||||
|
import { Icon } from '../_shared/Icon'
|
||||||
|
import Group from './Group'
|
||||||
|
|
||||||
|
import styles from './RandomTopicSwiper.module.scss'
|
||||||
|
|
||||||
|
export const RandomTopicSwiper = () => {
|
||||||
|
const { t } = useLocalize()
|
||||||
|
const { randomTopic } = useTopics()
|
||||||
|
const { addAuthors } = useAuthors()
|
||||||
|
const [randomTopicArticles, setRandomTopicArticles] = createSignal<Shout[]>([])
|
||||||
|
|
||||||
|
createEffect(
|
||||||
|
on(
|
||||||
|
() => randomTopic(), // NOTE: triggs once
|
||||||
|
async (topic?: Topic) => {
|
||||||
|
if (topic) {
|
||||||
|
const shoutsByTopicLoader = loadShouts({
|
||||||
|
filters: { topic: topic.slug, featured: true },
|
||||||
|
limit: 5,
|
||||||
|
offset: 0
|
||||||
|
})
|
||||||
|
const shouts = await shoutsByTopicLoader()
|
||||||
|
setRandomTopicArticles(shouts || [])
|
||||||
|
shouts?.forEach((s: Shout) => addAuthors((s?.authors || []) as Author[]))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ defer: true }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
<Show when={Boolean(randomTopic())}>
|
||||||
|
<Group
|
||||||
|
articles={randomTopicArticles() || []}
|
||||||
|
header={
|
||||||
|
<div class={styles.randomTopicHeaderContainer}>
|
||||||
|
<div class={styles.randomTopicHeader}>{capitalize(randomTopic()?.title || '', true)}</div>
|
||||||
|
<div>
|
||||||
|
<a class={styles.randomTopicHeaderLink} href={`/topic/${randomTopic()?.slug || ''}`}>
|
||||||
|
{t('All articles')} <Icon class={styles.icon} name="arrow-right" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Show>
|
||||||
|
)
|
||||||
|
}
|
|
@ -8,7 +8,6 @@ import { SharePopup, getShareUrl } from '../Article/SharePopup'
|
||||||
import { AuthModal } from '../AuthModal'
|
import { AuthModal } from '../AuthModal'
|
||||||
import { SearchModal } from '../SearchModal/SearchModal'
|
import { SearchModal } from '../SearchModal/SearchModal'
|
||||||
import { Snackbar } from '../Snackbar/Snackbar'
|
import { Snackbar } from '../Snackbar/Snackbar'
|
||||||
import { RandomTopics } from '../TopicsNav/TopicsNav'
|
|
||||||
import { ConfirmModal } from '../_shared/ConfirmModal'
|
import { ConfirmModal } from '../_shared/ConfirmModal'
|
||||||
import { Icon } from '../_shared/Icon'
|
import { Icon } from '../_shared/Icon'
|
||||||
import { Modal } from '../_shared/Modal'
|
import { Modal } from '../_shared/Modal'
|
||||||
|
@ -16,6 +15,7 @@ import { Newsletter } from '../_shared/Newsletter'
|
||||||
import styles from './Header.module.scss'
|
import styles from './Header.module.scss'
|
||||||
import { HeaderAuth } from './HeaderAuth'
|
import { HeaderAuth } from './HeaderAuth'
|
||||||
import { Link } from './HeaderLink'
|
import { Link } from './HeaderLink'
|
||||||
|
import { RandomTopics } from './TopicsNav'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
title?: string
|
title?: string
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { useTopics } from '~/context/topics'
|
||||||
import type { Topic } from '~/graphql/schema/core.gen'
|
import type { Topic } from '~/graphql/schema/core.gen'
|
||||||
import { notLatin } from '~/intl/chars'
|
import { notLatin } from '~/intl/chars'
|
||||||
import { getRandomItemsFromArray } from '~/utils/random'
|
import { getRandomItemsFromArray } from '~/utils/random'
|
||||||
|
|
||||||
import styles from './TopicsNav.module.scss'
|
import styles from './TopicsNav.module.scss'
|
||||||
|
|
||||||
export const RandomTopics = () => {
|
export const RandomTopics = () => {
|
|
@ -1 +0,0 @@
|
||||||
export { TopicsNav } from './TopicsNav'
|
|
|
@ -1,16 +1,26 @@
|
||||||
import { useNavigate } from '@solidjs/router'
|
import { useNavigate } from '@solidjs/router'
|
||||||
import { clsx } from 'clsx'
|
import { Client } from '@urql/core'
|
||||||
import { For, Show, createSignal } from 'solid-js'
|
import { For, Show, createEffect, createSignal, on, onMount } from 'solid-js'
|
||||||
import { Draft } from '~/components/Draft'
|
import { Draft } from '~/components/Draft'
|
||||||
import { useEditorContext } from '~/context/editor'
|
import { useEditorContext } from '~/context/editor'
|
||||||
import { useLocalize } from '~/context/localize'
|
import { useLocalize } from '~/context/localize'
|
||||||
|
import { useSession } from '~/context/session'
|
||||||
|
import getDraftsQuery from '~/graphql/query/core/articles-load-drafts'
|
||||||
import { Shout } from '~/graphql/schema/core.gen'
|
import { Shout } from '~/graphql/schema/core.gen'
|
||||||
import styles from './DraftsView.module.scss'
|
|
||||||
|
|
||||||
export const DraftsView = (props: { drafts: Shout[] }) => {
|
const fetchDrafts = async (client: Client) => {
|
||||||
const [drafts, setDrafts] = createSignal<Shout[]>(props.drafts || [])
|
const resp = await client?.query(getDraftsQuery, {}).toPromise()
|
||||||
|
const result = resp?.data?.get_shouts_drafts || []
|
||||||
|
if (resp.error || result.error) console.error(resp.error || result.error)
|
||||||
|
return result.shouts as Shout[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DraftsView = (props: { drafts?: Shout[] }) => {
|
||||||
|
const { client, requireAuthentication} = useSession()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const { publishShoutById, deleteShout } = useEditorContext()
|
const { publishShoutById, deleteShout } = useEditorContext()
|
||||||
|
const [drafts, setDrafts] = createSignal<Shout[]>(props.drafts || [])
|
||||||
|
|
||||||
const handleDraftDelete = async (shout: Shout) => {
|
const handleDraftDelete = async (shout: Shout) => {
|
||||||
const success = await deleteShout(shout.id)
|
const success = await deleteShout(shout.id)
|
||||||
if (success) {
|
if (success) {
|
||||||
|
@ -23,10 +33,20 @@ export const DraftsView = (props: { drafts: Shout[] }) => {
|
||||||
setTimeout(() => navigate('/feed'), 2000)
|
setTimeout(() => navigate('/feed'), 2000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
requireAuthentication(async () => {
|
||||||
|
const result = await fetchDrafts(client() as Client)
|
||||||
|
console.debug('fetchDrafts result: ', result)
|
||||||
|
if (result) {
|
||||||
|
setDrafts(result as Shout[])
|
||||||
|
}
|
||||||
|
}, 'edit')
|
||||||
|
})
|
||||||
|
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={clsx(styles.DraftsView)}>
|
<div>
|
||||||
<div class="wide-container">
|
<div class="wide-container">
|
||||||
<div class="row offset-md-5">
|
<div class="row offset-md-5">
|
||||||
<h2>{t('Drafts')}</h2>
|
<h2>{t('Drafts')}</h2>
|
||||||
|
@ -37,12 +57,7 @@ export const DraftsView = (props: { drafts: Shout[] }) => {
|
||||||
<div class="col-md-19 col-lg-18 col-xl-16 offset-md-5">
|
<div class="col-md-19 col-lg-18 col-xl-16 offset-md-5">
|
||||||
<For each={ddd()}>
|
<For each={ddd()}>
|
||||||
{(draft) => (
|
{(draft) => (
|
||||||
<Draft
|
<Draft shout={draft} onDelete={handleDraftDelete} onPublish={handleDraftPublish} />
|
||||||
class={styles.draft}
|
|
||||||
shout={draft}
|
|
||||||
onDelete={handleDraftDelete}
|
|
||||||
onPublish={handleDraftPublish}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
</div>
|
</div>
|
|
@ -1,7 +0,0 @@
|
||||||
.DraftsView {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.draft {
|
|
||||||
margin-bottom: 56px;
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
export { DraftsView } from './DraftsView'
|
|
|
@ -1,25 +1,21 @@
|
||||||
import { For, Show, createEffect, createMemo, createSignal, on } from 'solid-js'
|
import { For, Show, createMemo, onMount } from 'solid-js'
|
||||||
import { useAuthors } from '~/context/authors'
|
import { useAuthors } from '~/context/authors'
|
||||||
import { SHOUTS_PER_PAGE } from '~/context/feed'
|
import { SHOUTS_PER_PAGE } from '~/context/feed'
|
||||||
import { useLocalize } from '~/context/localize'
|
import { useLocalize } from '~/context/localize'
|
||||||
import { useTopics } from '~/context/topics'
|
import { useTopics } from '~/context/topics'
|
||||||
import { loadShouts } from '~/graphql/api/public'
|
|
||||||
import { Author, Shout, Topic } from '~/graphql/schema/core.gen'
|
import { Author, Shout, Topic } from '~/graphql/schema/core.gen'
|
||||||
import { capitalize } from '~/utils/capitalize'
|
|
||||||
import { paginate } from '~/utils/paginate'
|
import { paginate } from '~/utils/paginate'
|
||||||
import Banner from '../Discours/Banner'
|
import Banner from '../Discours/Banner'
|
||||||
import Hero from '../Discours/Hero'
|
import Hero from '../Discours/Hero'
|
||||||
import { Beside } from '../Feed/Beside'
|
import { Beside } from '../Feed/Beside'
|
||||||
import Group from '../Feed/Group'
|
import { RandomTopicSwiper } from '../Feed/RandomTopicSwiper'
|
||||||
import { Row1 } from '../Feed/Row1'
|
import { Row1 } from '../Feed/Row1'
|
||||||
import { Row2 } from '../Feed/Row2'
|
import { Row2 } from '../Feed/Row2'
|
||||||
import { Row3 } from '../Feed/Row3'
|
import { Row3 } from '../Feed/Row3'
|
||||||
import { Row5 } from '../Feed/Row5'
|
import { Row5 } from '../Feed/Row5'
|
||||||
import RowShort from '../Feed/RowShort'
|
import RowShort from '../Feed/RowShort'
|
||||||
import { TopicsNav } from '../TopicsNav'
|
import { TopicsNav } from '../HeaderNav/TopicsNav'
|
||||||
import { Icon } from '../_shared/Icon'
|
|
||||||
import { ArticleCardSwiper } from '../_shared/SolidSwiper/ArticleCardSwiper'
|
import { ArticleCardSwiper } from '../_shared/SolidSwiper/ArticleCardSwiper'
|
||||||
import styles from './Home.module.scss'
|
|
||||||
|
|
||||||
export const RANDOM_TOPICS_COUNT = 12
|
export const RANDOM_TOPICS_COUNT = 12
|
||||||
export const RANDOM_TOPIC_SHOUTS_COUNT = 7
|
export const RANDOM_TOPIC_SHOUTS_COUNT = 7
|
||||||
|
@ -38,28 +34,11 @@ export interface HomeViewProps {
|
||||||
export const HomeView = (props: HomeViewProps) => {
|
export const HomeView = (props: HomeViewProps) => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const { topAuthors, addAuthors } = useAuthors()
|
const { topAuthors, addAuthors } = useAuthors()
|
||||||
const { topTopics, randomTopic } = useTopics()
|
const { topTopics } = useTopics()
|
||||||
const [randomTopicArticles, setRandomTopicArticles] = createSignal<Shout[]>([])
|
onMount(() => {
|
||||||
createEffect(
|
props.featuredShouts?.forEach((s: Shout) => addAuthors((s?.authors || []) as Author[]))
|
||||||
on(
|
props.topRatedShouts?.forEach((s: Shout) => addAuthors((s?.authors || []) as Author[]))
|
||||||
() => randomTopic(),
|
})
|
||||||
async (topic?: Topic) => {
|
|
||||||
if (topic) {
|
|
||||||
const shoutsByTopicLoader = loadShouts({
|
|
||||||
filters: { topic: topic.slug, featured: true },
|
|
||||||
limit: 5,
|
|
||||||
offset: 0
|
|
||||||
})
|
|
||||||
const shouts = await shoutsByTopicLoader()
|
|
||||||
setRandomTopicArticles(shouts || [])
|
|
||||||
shouts?.forEach((s: Shout) => addAuthors((s?.authors || []) as Author[]))
|
|
||||||
props.featuredShouts?.forEach((s: Shout) => addAuthors((s?.authors || []) as Author[]))
|
|
||||||
props.topRatedShouts?.forEach((s: Shout) => addAuthors((s?.authors || []) as Author[]))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ defer: true }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
const pages = createMemo<Shout[][]>(() =>
|
const pages = createMemo<Shout[][]>(() =>
|
||||||
paginate(props.featuredShouts || [], SHOUTS_PER_PAGE + CLIENT_LOAD_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE)
|
paginate(props.featuredShouts || [], SHOUTS_PER_PAGE + CLIENT_LOAD_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE)
|
||||||
|
@ -99,21 +78,8 @@ export const HomeView = (props: HomeViewProps) => {
|
||||||
header={<h2>{t('Top commented')}</h2>}
|
header={<h2>{t('Top commented')}</h2>}
|
||||||
nodate={true}
|
nodate={true}
|
||||||
/>
|
/>
|
||||||
<Show when={Boolean(randomTopic())}>
|
|
||||||
<Group
|
<RandomTopicSwiper />
|
||||||
articles={randomTopicArticles() || []}
|
|
||||||
header={
|
|
||||||
<div class={styles.randomTopicHeaderContainer}>
|
|
||||||
<div class={styles.randomTopicHeader}>{capitalize(randomTopic()?.title || '', true)}</div>
|
|
||||||
<div>
|
|
||||||
<a class={styles.randomTopicHeaderLink} href={`/topic/${randomTopic()?.slug || ''}`}>
|
|
||||||
{t('All articles')} <Icon class={styles.icon} name="arrow-right" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Show>
|
|
||||||
|
|
||||||
<ArticleCardSwiper title={t('Favorite')} slides={props.topRatedShouts} />
|
<ArticleCardSwiper title={t('Favorite')} slides={props.topRatedShouts} />
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { useNavigate } from '@solidjs/router'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import { Show, createEffect, createSignal, lazy, onMount } from 'solid-js'
|
import { Show, createEffect, createSignal, lazy, onMount } from 'solid-js'
|
||||||
import { createStore } from 'solid-js/store'
|
import { createStore } from 'solid-js/store'
|
||||||
|
import { UploadModalContent } from '~/components/Upload/UploadModalContent/UploadModalContent'
|
||||||
import { Button } from '~/components/_shared/Button'
|
import { Button } from '~/components/_shared/Button'
|
||||||
import { Icon } from '~/components/_shared/Icon'
|
import { Icon } from '~/components/_shared/Icon'
|
||||||
import { Image } from '~/components/_shared/Image'
|
import { Image } from '~/components/_shared/Image'
|
||||||
|
@ -13,9 +14,8 @@ import { useSnackbar, useUI } from '~/context/ui'
|
||||||
import { Topic } from '~/graphql/schema/core.gen'
|
import { Topic } from '~/graphql/schema/core.gen'
|
||||||
import { UploadedFile } from '~/types/upload'
|
import { UploadedFile } from '~/types/upload'
|
||||||
import { Modal } from '../../_shared/Modal'
|
import { Modal } from '../../_shared/Modal'
|
||||||
|
import { TopicSelect } from './TopicSelect'
|
||||||
|
|
||||||
import { TopicSelect } from '~/components/TopicSelect/TopicSelect'
|
|
||||||
import { UploadModalContent } from '~/components/Upload/UploadModalContent/UploadModalContent'
|
|
||||||
import stylesBeside from '../../Feed/Beside.module.scss'
|
import stylesBeside from '../../Feed/Beside.module.scss'
|
||||||
import styles from './PublishSettings.module.scss'
|
import styles from './PublishSettings.module.scss'
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import {
|
||||||
onMount,
|
onMount,
|
||||||
useContext
|
useContext
|
||||||
} from 'solid-js'
|
} from 'solid-js'
|
||||||
import { type AuthModalSource, useSnackbar, useUI } from '~/context/ui'
|
import { type ModalSource, useSnackbar, useUI } from '~/context/ui'
|
||||||
import { graphqlClientCreate } from '~/graphql/client'
|
import { graphqlClientCreate } from '~/graphql/client'
|
||||||
import { authApiUrl, authorizerClientId, authorizerRedirectUrl, coreApiUrl } from '../config'
|
import { authApiUrl, authorizerClientId, authorizerRedirectUrl, coreApiUrl } from '../config'
|
||||||
import { useLocalize } from './localize'
|
import { useLocalize } from './localize'
|
||||||
|
@ -45,7 +45,7 @@ export type SessionContextType = {
|
||||||
setSession: (token: AuthToken) => void
|
setSession: (token: AuthToken) => void
|
||||||
requireAuthentication: (
|
requireAuthentication: (
|
||||||
callback: (() => Promise<void>) | (() => void),
|
callback: (() => Promise<void>) | (() => void),
|
||||||
modalSource: AuthModalSource
|
modalSource: ModalSource
|
||||||
) => void
|
) => void
|
||||||
signUp: (params: SignupInput) => Promise<boolean>
|
signUp: (params: SignupInput) => Promise<boolean>
|
||||||
signIn: (params: LoginInput) => Promise<boolean>
|
signIn: (params: LoginInput) => Promise<boolean>
|
||||||
|
@ -265,7 +265,7 @@ export const SessionProvider = (props: {
|
||||||
* @param callback - The function to execute after authentication.
|
* @param callback - The function to execute after authentication.
|
||||||
* @param modalSource - The source of the authentication modal.
|
* @param modalSource - The source of the authentication modal.
|
||||||
*/
|
*/
|
||||||
const requireAuthentication = (callback: () => void, modalSource: AuthModalSource) => {
|
const requireAuthentication = (callback: () => void, modalSource: ModalSource) => {
|
||||||
setAuthCallback(() => callback)
|
setAuthCallback(() => callback)
|
||||||
if (!session()) {
|
if (!session()) {
|
||||||
loadSession()
|
loadSession()
|
||||||
|
|
|
@ -70,7 +70,7 @@ export const SnackbarProvider = (props: { children: JSX.Element }) => {
|
||||||
return <SnackbarContext.Provider value={value}>{props.children}</SnackbarContext.Provider>
|
return <SnackbarContext.Provider value={value}>{props.children}</SnackbarContext.Provider>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AuthModalSource =
|
export type ModalSource =
|
||||||
| 'discussions'
|
| 'discussions'
|
||||||
| 'vote'
|
| 'vote'
|
||||||
| 'subscribe'
|
| 'subscribe'
|
||||||
|
@ -78,6 +78,7 @@ export type AuthModalSource =
|
||||||
| 'follow'
|
| 'follow'
|
||||||
| 'create'
|
| 'create'
|
||||||
| 'authguard'
|
| 'authguard'
|
||||||
|
| 'edit'
|
||||||
|
|
||||||
export type ModalType =
|
export type ModalType =
|
||||||
| 'auth'
|
| 'auth'
|
||||||
|
@ -128,7 +129,7 @@ type ConfirmMessage = {
|
||||||
|
|
||||||
type UIContextType = {
|
type UIContextType = {
|
||||||
modal: Accessor<ModalType | null>
|
modal: Accessor<ModalType | null>
|
||||||
showModal: (m: ModalType, source?: AuthModalSource) => void
|
showModal: (m: ModalType, source?: ModalSource) => void
|
||||||
hideModal: () => void
|
hideModal: () => void
|
||||||
confirmMessage: Accessor<ConfirmMessage>
|
confirmMessage: Accessor<ConfirmMessage>
|
||||||
showConfirm: (message?: ConfirmMessage) => Promise<boolean>
|
showConfirm: (message?: ConfirmMessage) => Promise<boolean>
|
||||||
|
@ -163,7 +164,7 @@ export const UIProvider = (props: { children: JSX.Element }) => {
|
||||||
hideModal()
|
hideModal()
|
||||||
}
|
}
|
||||||
|
|
||||||
const showModal = (modalType: ModalType, modalSource?: AuthModalSource) => {
|
const showModal = (modalType: ModalType, modalSource?: ModalSource) => {
|
||||||
// console.log('[context.ui] showModal()', modalType)
|
// console.log('[context.ui] showModal()', modalType)
|
||||||
if (modalSource) {
|
if (modalSource) {
|
||||||
setSearchParams({ source: modalSource })
|
setSearchParams({ source: modalSource })
|
||||||
|
|
|
@ -1,28 +1,15 @@
|
||||||
import { createAsync } from '@solidjs/router'
|
|
||||||
import { Client } from '@urql/core'
|
|
||||||
import { AuthGuard } from '~/components/AuthGuard'
|
import { AuthGuard } from '~/components/AuthGuard'
|
||||||
import { DraftsView } from '~/components/Views/DraftsView'
|
import { DraftsView } from '~/components/Views/DraftsView'
|
||||||
import { PageLayout } from '~/components/_shared/PageLayout'
|
import { PageLayout } from '~/components/_shared/PageLayout'
|
||||||
import { useLocalize } from '~/context/localize'
|
import { useLocalize } from '~/context/localize'
|
||||||
import { useSession } from '~/context/session'
|
|
||||||
import getDraftsQuery from '~/graphql/query/core/articles-load-drafts'
|
|
||||||
import { Shout } from '~/graphql/schema/core.gen'
|
|
||||||
|
|
||||||
const fetchDrafts = async (client: Client) => {
|
|
||||||
const resp = await client?.query(getDraftsQuery, {}).toPromise()
|
|
||||||
const result = resp?.data?.load_drafts || []
|
|
||||||
return result as Shout[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const { client } = useSession()
|
|
||||||
const drafts = createAsync(async () => client() && (await fetchDrafts(client() as Client)))
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout title={`${t('Discours')} :: ${t('Drafts')}`}>
|
<PageLayout title={`${t('Discours')} :: ${t('Drafts')}`}>
|
||||||
<AuthGuard>
|
<AuthGuard>
|
||||||
<DraftsView drafts={drafts() || []} />
|
<DraftsView />
|
||||||
</AuthGuard>
|
</AuthGuard>
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,53 +1,10 @@
|
||||||
import { useNavigate } from '@solidjs/router'
|
|
||||||
import { clsx } from 'clsx'
|
|
||||||
import { For } from 'solid-js'
|
|
||||||
import { AuthGuard } from '~/components/AuthGuard'
|
import { AuthGuard } from '~/components/AuthGuard'
|
||||||
import { Button } from '~/components/_shared/Button'
|
import { LayoutSelector } from '~/components/Draft/LayoutSelector'
|
||||||
import { Icon } from '~/components/_shared/Icon'
|
|
||||||
import { PageLayout } from '~/components/_shared/PageLayout'
|
import { PageLayout } from '~/components/_shared/PageLayout'
|
||||||
import { useEditorContext } from '~/context/editor'
|
|
||||||
import { useLocalize } from '~/context/localize'
|
import { useLocalize } from '~/context/localize'
|
||||||
import { useSession } from '~/context/session'
|
|
||||||
import { useSnackbar } from '~/context/ui'
|
|
||||||
import createShoutMutation from '~/graphql/mutation/core/article-create'
|
|
||||||
import { LayoutType } from '~/types/common'
|
|
||||||
|
|
||||||
import styles from '~/styles/Create.module.scss'
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const { client } = useSession()
|
|
||||||
const { saveDraftToLocalStorage } = useEditorContext()
|
|
||||||
|
|
||||||
const { showSnackbar } = useSnackbar()
|
|
||||||
const navigate = useNavigate()
|
|
||||||
const handleCreate = async (layout: LayoutType) => {
|
|
||||||
console.debug('[routes : edit/new] handling create click...')
|
|
||||||
const result = await client()
|
|
||||||
?.mutation(createShoutMutation, { shout: { layout: layout } })
|
|
||||||
.toPromise()
|
|
||||||
if (result) {
|
|
||||||
console.debug(result)
|
|
||||||
const { shout, error } = result.data.create_shout
|
|
||||||
if (error) {
|
|
||||||
showSnackbar({
|
|
||||||
body: `${t('Error')}: ${t(error)}`,
|
|
||||||
type: 'error'
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (shout?.id) {
|
|
||||||
saveDraftToLocalStorage({
|
|
||||||
shoutId: shout.id,
|
|
||||||
selectedTopics: shout.topics,
|
|
||||||
slug: shout.slug,
|
|
||||||
title: '',
|
|
||||||
body: ''
|
|
||||||
})
|
|
||||||
navigate(`/edit/${shout.id}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<PageLayout
|
<PageLayout
|
||||||
title={`${t('Discours')} :: ${t('Choose a post type')}`}
|
title={`${t('Discours')} :: ${t('Choose a post type')}`}
|
||||||
|
@ -55,22 +12,7 @@ export default () => {
|
||||||
desc={t('Participate in the Discours: share information, join the editorial team')}
|
desc={t('Participate in the Discours: share information, join the editorial team')}
|
||||||
>
|
>
|
||||||
<AuthGuard>
|
<AuthGuard>
|
||||||
<article class={clsx('wide-container', 'container--static-page', styles.Create)}>
|
<LayoutSelector />
|
||||||
<h1>{t('Choose a post type')}</h1>
|
|
||||||
<ul class={clsx('nodash', styles.list)}>
|
|
||||||
<For each={['Article', 'Literature', 'Image', 'Audio', 'Video']}>
|
|
||||||
{(layout: string) => (
|
|
||||||
<li onClick={() => handleCreate(layout.toLowerCase() as LayoutType)}>
|
|
||||||
<div class={styles.link}>
|
|
||||||
<Icon name={`create-${layout.toLowerCase()}`} class={styles.icon} />
|
|
||||||
<div>{t(layout)}</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</ul>
|
|
||||||
<Button value={t('Back')} onClick={() => window?.history.back()} />
|
|
||||||
</article>
|
|
||||||
</AuthGuard>
|
</AuthGuard>
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Params, RouteSectionProps, createAsync } from '@solidjs/router'
|
import { Params, RouteSectionProps, createAsync } from '@solidjs/router'
|
||||||
import { Show, createEffect, createSignal, on } from 'solid-js'
|
import { Show, createEffect, createSignal, on } from 'solid-js'
|
||||||
import { TopicsNav } from '~/components/TopicsNav'
|
import { TopicsNav } from '~/components/HeaderNav/TopicsNav'
|
||||||
import { Expo } from '~/components/Views/Expo'
|
import { Expo } from '~/components/Views/Expo'
|
||||||
import ExpoNav from '~/components/Views/Expo/ExpoNav'
|
import ExpoNav from '~/components/Views/Expo/ExpoNav'
|
||||||
import { LoadMoreItems, LoadMoreWrapper } from '~/components/_shared/LoadMoreWrapper'
|
import { LoadMoreItems, LoadMoreWrapper } from '~/components/_shared/LoadMoreWrapper'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user