mirror of
https://github.com/Steffo99/festa.git
synced 2024-12-22 14:44:21 +00:00
Make ViewContent a flex-based component
This commit is contained in:
parent
13d60aa4be
commit
9d18308642
7 changed files with 48 additions and 45 deletions
|
@ -28,20 +28,20 @@ export const EventsActionEdit = ({ data, mutate, save, setEditing }: EventsActio
|
||||||
setEditing(false)
|
setEditing(false)
|
||||||
}}>
|
}}>
|
||||||
<ViewContent
|
<ViewContent
|
||||||
title={
|
|
||||||
useMemo(
|
|
||||||
() => (
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={name}
|
|
||||||
onChange={e => mutate((prev) => ({ ...prev!, name: e.target.value }), { revalidate: false })}
|
|
||||||
placeholder={t("eventNamePlaceholder")}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
[t, mutate, name]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
content={<>
|
content={<>
|
||||||
|
<h1>
|
||||||
|
{useMemo(
|
||||||
|
() => (
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={name}
|
||||||
|
onChange={e => mutate((prev) => ({ ...prev!, name: e.target.value }), { revalidate: false })}
|
||||||
|
placeholder={t("eventNamePlaceholder")}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
[t, mutate, name]
|
||||||
|
)}
|
||||||
|
</h1>
|
||||||
{useMemo(
|
{useMemo(
|
||||||
() => (
|
() => (
|
||||||
<textarea
|
<textarea
|
||||||
|
|
3
components/events/actions/view.module.css
Normal file
3
components/events/actions/view.module.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.padAsInput {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import { Event } from "@prisma/client"
|
||||||
import { memo } from "react"
|
import { memo } from "react"
|
||||||
import { FestaMarkdownRenderer } from "../../generic/renderers/markdown"
|
import { FestaMarkdownRenderer } from "../../generic/renderers/markdown"
|
||||||
import { ViewContent } from "../../generic/views/content"
|
import { ViewContent } from "../../generic/views/content"
|
||||||
|
import style from "./view.module.css"
|
||||||
|
|
||||||
|
|
||||||
export type EventsActionViewProps = {
|
export type EventsActionViewProps = {
|
||||||
|
@ -13,12 +14,15 @@ export const EventsActionView = memo(({ data }: EventsActionViewProps) => {
|
||||||
return (
|
return (
|
||||||
<form>
|
<form>
|
||||||
<ViewContent
|
<ViewContent
|
||||||
title={<div style={{ padding: "10px" }}>
|
content={<>
|
||||||
{data.name}
|
<h1 className={style.padAsInput}>
|
||||||
</div>}
|
{data.name}
|
||||||
content={<div>
|
</h1>
|
||||||
<FestaMarkdownRenderer code={data.description} />
|
<FestaMarkdownRenderer
|
||||||
</div>}
|
className={style.padAsInput}
|
||||||
|
code={data.description}
|
||||||
|
/>
|
||||||
|
</>}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { memo } from "react"
|
import { memo } from "react"
|
||||||
import { default as ReactMarkdown } from "react-markdown"
|
import { default as ReactMarkdown } from "react-markdown"
|
||||||
|
import { ReactMarkdownOptions } from "react-markdown/lib/react-markdown"
|
||||||
|
|
||||||
type FestaMarkdownRendererProps = {
|
type FestaMarkdownRendererProps = Omit<ReactMarkdownOptions, "children"> & {
|
||||||
code: string,
|
code: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,9 +11,10 @@ type FestaMarkdownRendererProps = {
|
||||||
*
|
*
|
||||||
* Currently, it converts `h1` and `h2` into `h3`, and disables the rendering of `img` elements.
|
* Currently, it converts `h1` and `h2` into `h3`, and disables the rendering of `img` elements.
|
||||||
*/
|
*/
|
||||||
export const FestaMarkdownRenderer = memo(({ code }: FestaMarkdownRendererProps) => {
|
export const FestaMarkdownRenderer = memo(({ code, ...props }: FestaMarkdownRendererProps) => {
|
||||||
return (
|
return (
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
|
{...props}
|
||||||
components={{
|
components={{
|
||||||
h1: "h2", // h1 is reserved for the page name
|
h1: "h2", // h1 is reserved for the page name
|
||||||
h2: "h3",
|
h2: "h3",
|
||||||
|
@ -20,6 +22,7 @@ export const FestaMarkdownRenderer = memo(({ code }: FestaMarkdownRendererProps)
|
||||||
h4: "h5",
|
h4: "h5",
|
||||||
h5: "h6",
|
h5: "h6",
|
||||||
img: undefined, // images reveal the IP of the user to third parties!
|
img: undefined, // images reveal the IP of the user to third parties!
|
||||||
|
...props.components,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{code}
|
{code}
|
||||||
|
|
|
@ -1,25 +1,11 @@
|
||||||
.viewContent {
|
.viewContent {
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-areas:
|
flex-direction: column;
|
||||||
"title"
|
|
||||||
"content"
|
|
||||||
;
|
|
||||||
grid-template-columns: auto;
|
|
||||||
grid-template-rows: auto 1fr;
|
|
||||||
|
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
|
||||||
justify-content: stretch;
|
align-content: stretch;
|
||||||
|
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
|
||||||
|
|
||||||
.viewContentTitle {
|
|
||||||
grid-area: title;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.viewContentContent {
|
|
||||||
grid-area: content;
|
|
||||||
}
|
}
|
|
@ -3,7 +3,6 @@ import style from "./content.module.css"
|
||||||
|
|
||||||
|
|
||||||
export type ViewContentProps = {
|
export type ViewContentProps = {
|
||||||
title: ReactNode
|
|
||||||
content: ReactNode
|
content: ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,12 +12,7 @@ export type ViewContentProps = {
|
||||||
export const ViewContent = memo((props: ViewContentProps) => {
|
export const ViewContent = memo((props: ViewContentProps) => {
|
||||||
return (
|
return (
|
||||||
<main className={style.viewContent}>
|
<main className={style.viewContent}>
|
||||||
<h1 className={style.viewContentTitle}>
|
{props.content}
|
||||||
{props.title}
|
|
||||||
</h1>
|
|
||||||
<div className={style.viewContentContent}>
|
|
||||||
{props.content}
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -19,6 +19,10 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: var(--anchor);
|
color: var(--anchor);
|
||||||
}
|
}
|
||||||
|
@ -70,8 +74,17 @@ textarea {
|
||||||
border-radius: 16px 16px 0 16px;
|
border-radius: 16px 16px 0 16px;
|
||||||
|
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
p:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
}
|
}
|
Loading…
Reference in a new issue