2024-09-15 15:37:27 +00:00
|
|
|
/**
|
|
|
|
* Placeholder component displays different placeholder content based on type and mode.
|
|
|
|
*
|
|
|
|
* @param {PlaceholderProps} props - The properties for the component.
|
|
|
|
* @returns {JSX.Element | null} The rendered placeholder or null if data is missing.
|
|
|
|
*/
|
|
|
|
|
2024-05-10 16:52:13 +00:00
|
|
|
import { clsx } from 'clsx'
|
2024-06-24 17:50:27 +00:00
|
|
|
import { For, Show, createMemo } from 'solid-js'
|
2024-05-10 16:52:13 +00:00
|
|
|
|
2024-07-04 07:51:15 +00:00
|
|
|
import { Icon } from '~/components/_shared/Icon'
|
|
|
|
import { useLocalize } from '~/context/localize'
|
|
|
|
import { useSession } from '~/context/session'
|
2024-05-10 16:52:13 +00:00
|
|
|
import styles from './Placeholder.module.scss'
|
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
type ProfileLink = {
|
|
|
|
href: string
|
|
|
|
label: string
|
|
|
|
}
|
|
|
|
|
|
|
|
type PlaceholderData = {
|
|
|
|
[key: string]: {
|
|
|
|
image: string
|
|
|
|
header: string
|
|
|
|
text: string
|
|
|
|
buttonLabel?: string
|
|
|
|
buttonLabelAuthor?: string
|
|
|
|
buttonLabelFeed?: string
|
|
|
|
href: string
|
|
|
|
profileLinks?: ProfileLink[]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-10 16:52:13 +00:00
|
|
|
export type PlaceholderProps = {
|
2024-06-24 17:50:27 +00:00
|
|
|
type: keyof PlaceholderData
|
2024-05-11 17:27:57 +00:00
|
|
|
mode: 'feed' | 'profile'
|
2024-05-10 16:52:13 +00:00
|
|
|
}
|
|
|
|
|
2024-06-24 17:50:27 +00:00
|
|
|
const data: PlaceholderData = {
|
|
|
|
feedMy: {
|
|
|
|
image: 'placeholder-feed.webp',
|
|
|
|
header: 'Feed settings',
|
|
|
|
text: 'Placeholder feed',
|
|
|
|
buttonLabelAuthor: 'Popular authors',
|
|
|
|
buttonLabelFeed: 'Create own feed',
|
2024-07-03 21:25:03 +00:00
|
|
|
href: '/author?by=followers'
|
2024-06-24 17:50:27 +00:00
|
|
|
},
|
|
|
|
feedCollaborations: {
|
|
|
|
image: 'placeholder-experts.webp',
|
|
|
|
header: 'Find collaborators',
|
|
|
|
text: 'Placeholder feedCollaborations',
|
|
|
|
buttonLabel: 'Find co-authors',
|
2024-07-03 21:25:03 +00:00
|
|
|
href: '/author?by=name'
|
2024-06-24 17:50:27 +00:00
|
|
|
},
|
|
|
|
feedDiscussions: {
|
|
|
|
image: 'placeholder-discussions.webp',
|
|
|
|
header: 'Participate in discussions',
|
|
|
|
text: 'Placeholder feedDiscussions',
|
|
|
|
buttonLabelAuthor: 'Current discussions',
|
|
|
|
buttonLabelFeed: 'Enter',
|
2024-07-15 20:35:33 +00:00
|
|
|
href: '/feed/hot'
|
2024-06-24 17:50:27 +00:00
|
|
|
},
|
|
|
|
author: {
|
|
|
|
image: 'placeholder-join.webp',
|
|
|
|
header: 'Join our team of authors',
|
|
|
|
text: 'Join our team of authors text',
|
|
|
|
buttonLabel: 'Create post',
|
2024-07-03 21:25:03 +00:00
|
|
|
href: '/edit/new',
|
2024-06-24 17:50:27 +00:00
|
|
|
profileLinks: [
|
|
|
|
{
|
|
|
|
href: '/how-to-write-a-good-article',
|
2024-06-26 08:22:05 +00:00
|
|
|
label: 'How to write a good article'
|
|
|
|
}
|
|
|
|
]
|
2024-06-24 17:50:27 +00:00
|
|
|
},
|
|
|
|
authorComments: {
|
|
|
|
image: 'placeholder-discussions.webp',
|
|
|
|
header: 'Join discussions',
|
|
|
|
text: 'Placeholder feedDiscussions',
|
|
|
|
buttonLabel: 'Go to discussions',
|
2024-07-15 20:35:33 +00:00
|
|
|
href: '/feed/hot',
|
2024-06-24 17:50:27 +00:00
|
|
|
profileLinks: [
|
|
|
|
{
|
2024-07-05 19:40:54 +00:00
|
|
|
href: '/debate',
|
2024-06-26 08:22:05 +00:00
|
|
|
label: 'Discussion rules'
|
2024-06-24 17:50:27 +00:00
|
|
|
},
|
|
|
|
{
|
2024-07-05 19:40:54 +00:00
|
|
|
href: '/debate#ban',
|
2024-06-26 08:22:05 +00:00
|
|
|
label: 'Block rules'
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
2024-06-24 17:50:27 +00:00
|
|
|
}
|
|
|
|
|
2024-05-10 16:52:13 +00:00
|
|
|
export const Placeholder = (props: PlaceholderProps) => {
|
|
|
|
const { t } = useLocalize()
|
2024-06-24 17:50:27 +00:00
|
|
|
const { session } = useSession()
|
2024-05-10 16:52:13 +00:00
|
|
|
|
2024-09-15 15:37:27 +00:00
|
|
|
// dufok (^-^') mem for placeholder data without a fallback, it will be `undefined` if not found
|
|
|
|
|
2024-09-14 16:30:47 +00:00
|
|
|
const placeholderData = createMemo(() => {
|
|
|
|
const dataForType = data[props.type];
|
|
|
|
if (!dataForType) {
|
|
|
|
console.warn(`No placeholder data found for type: ${props.type}`);
|
|
|
|
}
|
2024-09-15 15:37:27 +00:00
|
|
|
return dataForType;
|
|
|
|
// (^-^') No fallback to ensure it is empty when data is missing
|
2024-09-14 16:30:47 +00:00
|
|
|
});
|
|
|
|
|
2024-09-15 15:37:27 +00:00
|
|
|
// (^-^') Return null if no placeholder data is found
|
2024-09-14 16:30:47 +00:00
|
|
|
if (!placeholderData()) {
|
|
|
|
return null;
|
|
|
|
}
|
2024-05-10 16:52:13 +00:00
|
|
|
|
|
|
|
return (
|
2024-05-11 17:33:40 +00:00
|
|
|
<div
|
|
|
|
class={clsx(
|
|
|
|
styles.placeholder,
|
2024-06-24 17:50:27 +00:00
|
|
|
styles[`placeholder--${props.type}` as keyof typeof styles],
|
2024-06-26 08:22:05 +00:00
|
|
|
styles[`placeholder--${props.mode}-mode` as keyof typeof styles]
|
2024-05-11 17:33:40 +00:00
|
|
|
)}
|
|
|
|
>
|
2024-05-10 16:52:13 +00:00
|
|
|
<div class={styles.placeholderCover}>
|
2024-09-14 16:30:47 +00:00
|
|
|
<img src={`/${placeholderData()?.image}`} alt={placeholderData()?.header} />
|
2024-05-10 16:52:13 +00:00
|
|
|
</div>
|
|
|
|
<div class={styles.placeholderContent}>
|
2024-05-11 17:27:57 +00:00
|
|
|
<div>
|
2024-09-14 16:30:47 +00:00
|
|
|
<h3 innerHTML={t(placeholderData()?.header)} />
|
|
|
|
<p innerHTML={t(placeholderData()?.text)} />
|
2024-05-11 17:27:57 +00:00
|
|
|
</div>
|
|
|
|
|
2024-09-14 16:30:47 +00:00
|
|
|
<Show when={placeholderData()?.profileLinks}>
|
2024-05-11 17:27:57 +00:00
|
|
|
<div class={styles.bottomLinks}>
|
2024-09-14 16:30:47 +00:00
|
|
|
<For each={placeholderData()?.profileLinks}>
|
2024-05-11 17:27:57 +00:00
|
|
|
{(link) => (
|
|
|
|
<a href={link.href}>
|
2024-05-11 17:33:40 +00:00
|
|
|
<Icon name="link-white" class={styles.icon} />
|
2024-06-24 17:50:27 +00:00
|
|
|
{t(link.label)}
|
2024-05-11 17:27:57 +00:00
|
|
|
</a>
|
|
|
|
)}
|
|
|
|
</For>
|
|
|
|
</div>
|
|
|
|
</Show>
|
2024-05-10 16:52:13 +00:00
|
|
|
|
|
|
|
<Show
|
2024-06-24 17:50:27 +00:00
|
|
|
when={session()?.access_token}
|
2024-05-10 16:52:13 +00:00
|
|
|
fallback={
|
|
|
|
<a class={styles.button} href="?m=auth&mode=login">
|
2024-06-24 17:50:27 +00:00
|
|
|
{t(
|
|
|
|
session()?.access_token
|
|
|
|
? placeholderData()?.buttonLabelAuthor || ''
|
2024-06-26 08:22:05 +00:00
|
|
|
: placeholderData()?.buttonLabelFeed || ''
|
2024-06-24 17:50:27 +00:00
|
|
|
)}
|
2024-05-10 16:52:13 +00:00
|
|
|
</a>
|
|
|
|
}
|
|
|
|
>
|
2024-09-14 16:30:47 +00:00
|
|
|
<a class={styles.button} href={placeholderData()?.href}>
|
2024-06-24 17:50:27 +00:00
|
|
|
{t(
|
|
|
|
session()?.access_token
|
|
|
|
? placeholderData()?.buttonLabelAuthor || ''
|
2024-06-26 08:22:05 +00:00
|
|
|
: placeholderData()?.buttonLabelFeed || ''
|
2024-06-24 17:50:27 +00:00
|
|
|
)}
|
2024-05-11 17:27:57 +00:00
|
|
|
<Show when={props.mode === 'profile'}>
|
2024-05-11 17:33:40 +00:00
|
|
|
<Icon name="arrow-right-2" class={styles.icon} />
|
2024-05-11 17:27:57 +00:00
|
|
|
</Show>
|
|
|
|
</a>
|
2024-05-10 16:52:13 +00:00
|
|
|
</Show>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|