mirror of
https://github.com/Steffo99/festa.git
synced 2024-12-22 14:44:21 +00:00
Fix postcard quirks
This commit is contained in:
parent
7f366c8f09
commit
6412472d3e
13 changed files with 145 additions and 113 deletions
|
@ -1,31 +0,0 @@
|
|||
import { useEffect } from "react"
|
||||
import { PostcardContext } from "./PostcardContext"
|
||||
import { useDefinedContext } from "../../utils/definedContext"
|
||||
import { StaticImageData } from "next/image"
|
||||
|
||||
type PostcardProps = {
|
||||
src?: string | StaticImageData
|
||||
}
|
||||
|
||||
export function Postcard({ src }: PostcardProps) {
|
||||
const { setPostcard } = useDefinedContext(PostcardContext)
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
if (src) {
|
||||
if (src === undefined) {
|
||||
return
|
||||
}
|
||||
if (typeof src === "object") {
|
||||
setPostcard(src.src)
|
||||
}
|
||||
else {
|
||||
setPostcard(src)
|
||||
}
|
||||
}
|
||||
},
|
||||
[src, setPostcard]
|
||||
)
|
||||
|
||||
return null
|
||||
}
|
|
@ -1,11 +1,36 @@
|
|||
import { createDefinedContext } from "../../utils/definedContext";
|
||||
|
||||
|
||||
export type PostcardContextValue = {
|
||||
postcard: string,
|
||||
setPostcard: React.Dispatch<React.SetStateAction<string>>,
|
||||
visible: boolean,
|
||||
setVisible: React.Dispatch<React.SetStateAction<boolean>>,
|
||||
/**
|
||||
* The string to be used as the [`background-image`](https://developer.mozilla.org/en-US/docs/Web/CSS/background-image) CSS property of the postcard.
|
||||
*/
|
||||
export type PostcardImage = string;
|
||||
|
||||
|
||||
/**
|
||||
* How the postcard is displayed on the page.
|
||||
*/
|
||||
export enum PostcardVisibility {
|
||||
/**
|
||||
* The postcard is filtered, blurred, and rendered behind all elements on the page.
|
||||
*/
|
||||
BACKGROUND = "background",
|
||||
|
||||
/**
|
||||
* The postcard is fully visible and rendered above all other elements.
|
||||
*/
|
||||
FOREGROUND = "foreground",
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Contents of the {@link PostcardContext}.
|
||||
*/
|
||||
type PostcardContextValue = {
|
||||
image: PostcardImage,
|
||||
setImage: React.Dispatch<React.SetStateAction<PostcardImage>>,
|
||||
visibility: PostcardVisibility,
|
||||
setVisibility: React.Dispatch<React.SetStateAction<PostcardVisibility>>,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,16 +4,15 @@ import classNames from "classnames";
|
|||
|
||||
|
||||
export function PostcardRenderer() {
|
||||
const {postcard, visible} = useDefinedContext(PostcardContext)
|
||||
const { image, visibility } = useDefinedContext(PostcardContext)
|
||||
|
||||
console.debug("[PostcardRenderer] Re-rendering with:", image)
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames({
|
||||
"postcard": true,
|
||||
"postcard-visible": visible,
|
||||
})}
|
||||
className={classNames("postcard", `postcard-vis-${visibility}`)}
|
||||
style={{
|
||||
backgroundImage: `url(${postcard})`
|
||||
backgroundImage: image,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
|
14
components/postcard/usePostcardImage.ts
Normal file
14
components/postcard/usePostcardImage.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { useEffect } from "react"
|
||||
import { useDefinedContext } from "../../utils/definedContext"
|
||||
import { PostcardContext } from "./PostcardContext"
|
||||
|
||||
export function usePostcardImage(image: string) {
|
||||
const { setImage } = useDefinedContext(PostcardContext)
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
setImage(image)
|
||||
},
|
||||
[image]
|
||||
)
|
||||
}
|
14
components/postcard/useStatePostcard.ts
Normal file
14
components/postcard/useStatePostcard.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { useState } from "react";
|
||||
import { PostcardImage, PostcardVisibility } from "./PostcardContext";
|
||||
|
||||
export function useStatePostcard() {
|
||||
const [visibility, setVisibility] = useState<PostcardVisibility>(PostcardVisibility.BACKGROUND)
|
||||
const [image, setImage] = useState<PostcardImage>("none")
|
||||
|
||||
return {
|
||||
visibility,
|
||||
setVisibility,
|
||||
image,
|
||||
setImage,
|
||||
}
|
||||
}
|
|
@ -2,19 +2,32 @@ import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons"
|
|||
import { useTranslation } from "next-i18next"
|
||||
import { useDefinedContext } from "../../utils/definedContext"
|
||||
import { FestaIcon } from "../extensions/FestaIcon"
|
||||
import { PostcardContext } from "../postcard/PostcardContext"
|
||||
import { PostcardContext, PostcardVisibility } from "../postcard/PostcardContext"
|
||||
|
||||
export function ToolToggleVisible() {
|
||||
const {t} = useTranslation()
|
||||
const {visible, setVisible} = useDefinedContext(PostcardContext)
|
||||
const { t } = useTranslation()
|
||||
const { visibility, setVisibility } = useDefinedContext(PostcardContext)
|
||||
|
||||
return (
|
||||
<button
|
||||
aria-label={visible ? t("toggleVisibleHide") : t("toggleVisibleShow")}
|
||||
onClick={() => setVisible(!visible)}
|
||||
className="toolbar-tool"
|
||||
>
|
||||
<FestaIcon icon={visible ? faEyeSlash : faEye}/>
|
||||
</button>
|
||||
)
|
||||
if (visibility === PostcardVisibility.BACKGROUND) {
|
||||
return (
|
||||
<button
|
||||
aria-label={t("toggleVisibleShow")}
|
||||
onClick={() => setVisibility(PostcardVisibility.FOREGROUND)}
|
||||
className="toolbar-tool"
|
||||
>
|
||||
<FestaIcon icon={faEye} />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
else {
|
||||
return (
|
||||
<button
|
||||
aria-label={t("toggleVisibleHide")}
|
||||
onClick={() => setVisibility(PostcardVisibility.BACKGROUND)}
|
||||
className="toolbar-tool"
|
||||
>
|
||||
<FestaIcon icon={faEyeSlash} />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ import { useTranslation } from "next-i18next";
|
|||
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
||||
import { default as Link } from "next/link";
|
||||
import { ErrorBlock } from "../components/errors/ErrorBlock";
|
||||
import { Postcard } from "../components/postcard/Postcard";
|
||||
import { usePostcardImage } from "../components/postcard/usePostcardImage";
|
||||
import { ViewNotice } from "../components/view/ViewNotice";
|
||||
import errorPostcard from "../public/postcards/markus-spiske-iar-afB0QQw-unsplash-red.jpg"
|
||||
|
||||
|
@ -18,10 +18,11 @@ export async function getStaticProps(context: NextPageContext) {
|
|||
|
||||
|
||||
export default function Page404() {
|
||||
const {t} = useTranslation()
|
||||
const { t } = useTranslation()
|
||||
|
||||
usePostcardImage(`url(${errorPostcard.src})`)
|
||||
|
||||
return <>
|
||||
<Postcard src={errorPostcard.src}/>
|
||||
<ViewNotice
|
||||
notice={<>
|
||||
<ErrorBlock
|
||||
|
|
|
@ -2,7 +2,7 @@ import { NextPageContext } from "next";
|
|||
import { useTranslation } from "next-i18next";
|
||||
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
||||
import { ErrorBlock } from "../components/errors/ErrorBlock";
|
||||
import { Postcard } from "../components/postcard/Postcard";
|
||||
import { usePostcardImage } from "../components/postcard/usePostcardImage";
|
||||
import { ViewNotice } from "../components/view/ViewNotice";
|
||||
import errorPostcard from "../public/postcards/markus-spiske-iar-afB0QQw-unsplash-red.jpg"
|
||||
|
||||
|
@ -17,10 +17,11 @@ export async function getStaticProps(context: NextPageContext) {
|
|||
|
||||
|
||||
export default function Page500() {
|
||||
const {t} = useTranslation()
|
||||
const { t } = useTranslation()
|
||||
|
||||
usePostcardImage(`url(${errorPostcard.src})`)
|
||||
|
||||
return <>
|
||||
<Postcard src={errorPostcard.src}/>
|
||||
<ViewNotice
|
||||
notice={
|
||||
<ErrorBlock
|
||||
|
|
|
@ -2,10 +2,8 @@ import '../styles/globals.css'
|
|||
import type { AppProps } from 'next/app'
|
||||
import { LoginContext } from '../components/contexts/login'
|
||||
import { useState } from 'react'
|
||||
import defaultPostcard from "../public/postcards/adi-goldstein-Hli3R6LKibo-unsplash.jpg"
|
||||
import { PostcardRenderer } from '../components/postcard/PostcardRenderer'
|
||||
import { PostcardContext } from '../components/postcard/PostcardContext'
|
||||
import { StaticImageData } from 'next/image'
|
||||
import { appWithTranslation, useTranslation } from 'next-i18next'
|
||||
import { FestaLoginData } from '../types/user'
|
||||
import { useStoredLogin } from "../hooks/useStoredLogin"
|
||||
|
@ -13,12 +11,13 @@ import { SWRConfig } from 'swr'
|
|||
import { AxiosRequestConfig } from 'axios'
|
||||
import { useAxios } from '../hooks/useAxios'
|
||||
import { ErrorBoundary } from '../components/errors/ErrorBoundary'
|
||||
import defaultPostcard from "../public/postcards/adi-goldstein-Hli3R6LKibo-unsplash.jpg"
|
||||
import { useStatePostcard } from '../components/postcard/useStatePostcard'
|
||||
|
||||
|
||||
const App = ({ Component, pageProps }: AppProps): JSX.Element => {
|
||||
const {t} = useTranslation()
|
||||
const [postcard, setPostcard] = useState<string>(defaultPostcard.src)
|
||||
const [postcardVisible, setPostcardVisible] = useState<boolean>(false)
|
||||
const { t } = useTranslation()
|
||||
const postcardState = useStatePostcard()
|
||||
const [login, setLogin] = useState<FestaLoginData | null>(null)
|
||||
useStoredLogin(setLogin)
|
||||
|
||||
|
@ -35,14 +34,14 @@ const App = ({ Component, pageProps }: AppProps): JSX.Element => {
|
|||
|
||||
return <>
|
||||
<ErrorBoundary text={t("genericError")}>
|
||||
<PostcardContext.Provider value={{postcard, setPostcard, visible: postcardVisible, setVisible: setPostcardVisible}}>
|
||||
<LoginContext.Provider value={[login, setLogin]}>
|
||||
<SWRConfig value={swrConfig}>
|
||||
<PostcardRenderer/>
|
||||
<Component {...pageProps} />
|
||||
</SWRConfig>
|
||||
</LoginContext.Provider>
|
||||
</PostcardContext.Provider>
|
||||
<PostcardContext.Provider value={postcardState}>
|
||||
<LoginContext.Provider value={[login, setLogin]}>
|
||||
<SWRConfig value={swrConfig}>
|
||||
<PostcardRenderer />
|
||||
<Component {...pageProps} />
|
||||
</SWRConfig>
|
||||
</LoginContext.Provider>
|
||||
</PostcardContext.Provider>
|
||||
</ErrorBoundary>
|
||||
</>
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { NextPageContext } from "next";
|
|||
import { useTranslation } from "next-i18next";
|
||||
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
||||
import { default as Head } from "next/head";
|
||||
import { ChangeEvent, useCallback, useState } from "react";
|
||||
import { ChangeEvent, useMemo, useState } from "react";
|
||||
import { ToolBar } from "../../components/tools/ToolBar";
|
||||
import { EditableMarkdown } from "../../components/editable/EditableMarkdown";
|
||||
import { EditableText } from "../../components/editable/EditableText";
|
||||
|
@ -13,11 +13,9 @@ import { database } from "../../utils/prismaClient";
|
|||
import { EditableFilePicker } from "../../components/editable/EditableFilePicker";
|
||||
import { ViewEvent } from "../../components/view/ViewEvent";
|
||||
import { ToolToggleVisible } from "../../components/tools/ToolToggleVisible";
|
||||
import { EditableDateRange } from "../../components/editable/EditableDateRange";
|
||||
import { WorkInProgress } from "../../components/WorkInProgress";
|
||||
import { FormDateRange } from "../../components/form/FormDateRange";
|
||||
import { Postcard } from "../../components/postcard/Postcard";
|
||||
import { useFilePickerState } from "../../hooks/useFilePickerState";
|
||||
import { usePostcardImage } from "../../components/postcard/usePostcardImage";
|
||||
import defaultPostcard from "../../public/postcards/adi-goldstein-Hli3R6LKibo-unsplash.jpg"
|
||||
|
||||
|
||||
export async function getServerSideProps(context: NextPageContext) {
|
||||
|
@ -26,17 +24,17 @@ export async function getServerSideProps(context: NextPageContext) {
|
|||
return { notFound: true }
|
||||
}
|
||||
|
||||
const event = await database.event.findUnique({
|
||||
const initialEvent = await database.event.findUnique({
|
||||
where: { slug },
|
||||
include: { creator: true }
|
||||
})
|
||||
if (!event) {
|
||||
if (!initialEvent) {
|
||||
return { notFound: true }
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
event,
|
||||
initialEvent,
|
||||
...(await serverSideTranslations(context.locale ?? "it-IT", ["common"]))
|
||||
}
|
||||
}
|
||||
|
@ -44,25 +42,23 @@ export async function getServerSideProps(context: NextPageContext) {
|
|||
|
||||
|
||||
type PageEventDetailProps = {
|
||||
event: Event & { creator: User }
|
||||
initialEvent: Event & { creator: User }
|
||||
}
|
||||
|
||||
|
||||
export default function PageEventDetail({ event }: PageEventDetailProps) {
|
||||
export default function PageEventDetail({ initialEvent }: PageEventDetailProps) {
|
||||
const { t } = useTranslation()
|
||||
const editState = useState<boolean>(false)
|
||||
const [title, setTitle] = useState<string>(event.name)
|
||||
const [description, setDescription] = useState<string>(event.description)
|
||||
const [postcard, setPostcard] = useState<File | "">("")
|
||||
const [startingAt, setStartingAt] = useState<string>(event.startingAt?.toISOString() ?? "")
|
||||
const [endingAt, setEndingAt] = useState<string>(event.endingAt?.toISOString() ?? "")
|
||||
const [event, setEvent] = useState<Event>(initialEvent)
|
||||
|
||||
const displayedPostcard = event.postcard || defaultPostcard.src
|
||||
usePostcardImage(`url(${displayedPostcard})`)
|
||||
|
||||
return <>
|
||||
<Head>
|
||||
<title key="title">{event.name} - {t("siteTitle")}</title>
|
||||
<title key="title">{initialEvent.name} - {t("siteTitle")}</title>
|
||||
</Head>
|
||||
<WorkInProgress />
|
||||
<Postcard src={postcard ? URL.createObjectURL(postcard) : event.postcard ?? undefined} />
|
||||
<EditingContext.Provider value={editState}>
|
||||
<ToolBar vertical="vadapt" horizontal="right">
|
||||
<ToolToggleEditing />
|
||||
|
@ -71,25 +67,24 @@ export default function PageEventDetail({ event }: PageEventDetailProps) {
|
|||
<ViewEvent
|
||||
title={
|
||||
<EditableText
|
||||
value={title}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) => setTitle(e.target.value)}
|
||||
placeholder={t("eventDetailsTitlePlaceholder")}
|
||||
value={event.name}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) => setEvent({ ...event, name: e.target.value })}
|
||||
placeholder={t("eventDetailsNamePlaceholder")}
|
||||
/>
|
||||
}
|
||||
postcard={
|
||||
<EditableFilePicker
|
||||
value={postcard}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) => e.target.files ? setPostcard(e.target.files[0] ?? null) : setPostcard(null)}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) => setEvent({ ...event, postcard: URL.createObjectURL(e.target.files![0]) })}
|
||||
placeholder={t("eventDetailsPostcardPlaceholder")}
|
||||
/>
|
||||
}
|
||||
description={<>
|
||||
description={
|
||||
<EditableMarkdown
|
||||
value={description}
|
||||
onChange={(e: ChangeEvent<HTMLTextAreaElement>) => setDescription(e.target.value)}
|
||||
value={event.description}
|
||||
onChange={(e: ChangeEvent<HTMLTextAreaElement>) => setEvent({ ...event, description: e.target.value })}
|
||||
placeholder={t("eventDetailsDescriptionPlaceholder")}
|
||||
/>
|
||||
</>}
|
||||
}
|
||||
daterange={<></>}
|
||||
/>
|
||||
</EditingContext.Provider>
|
||||
|
|
|
@ -7,8 +7,8 @@ import { ActionLoginTelegram } from '../components/ActionLoginTelegram'
|
|||
import { ActionEventList } from '../components/ActionEventList'
|
||||
import { default as Head } from 'next/head'
|
||||
import defaultPostcard from "../public/postcards/adi-goldstein-Hli3R6LKibo-unsplash.jpg"
|
||||
import { Postcard } from '../components/postcard/Postcard'
|
||||
import { ViewLanding } from '../components/view/ViewLanding'
|
||||
import { usePostcardImage } from '../components/postcard/usePostcardImage'
|
||||
|
||||
|
||||
export async function getStaticProps(context: NextPageContext) {
|
||||
|
@ -22,15 +22,14 @@ export async function getStaticProps(context: NextPageContext) {
|
|||
|
||||
export default function PageIndex() {
|
||||
const { t } = useTranslation()
|
||||
const [login, ] = useDefinedContext(LoginContext)
|
||||
const [login,] = useDefinedContext(LoginContext)
|
||||
|
||||
usePostcardImage(`url(${defaultPostcard.src})`)
|
||||
|
||||
return <>
|
||||
<Head>
|
||||
<title key="title">{t("siteTitle")}</title>
|
||||
</Head>
|
||||
<Postcard
|
||||
src={defaultPostcard}
|
||||
/>
|
||||
<ViewLanding
|
||||
title={t("siteTitle")}
|
||||
subtitle={t("siteSubtitle")}
|
||||
|
@ -39,7 +38,7 @@ export default function PageIndex() {
|
|||
<ActionEventList
|
||||
className="hero-action"
|
||||
/>
|
||||
:
|
||||
:
|
||||
<ActionLoginTelegram
|
||||
className="hero-action"
|
||||
/>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
"eventListCreateError": "Si è verificato il seguente errore nella creazione del tuo evento:",
|
||||
"eventDetailsToggleEditingEdit": "Modifica pagina",
|
||||
"eventDetailsToggleEditingView": "Visualizza anteprima",
|
||||
"eventDetailsTitlePlaceholder": "Titolo",
|
||||
"eventDetailsNamePlaceholder": "Nome evento",
|
||||
"eventDetailsDescriptionPlaceholder": "Descrizione evento",
|
||||
"eventDetailsPostcardPlaceholder": "Cartolina",
|
||||
"workInProgress": "Questa pagina è ancora in sviluppo e potrebbe contenere errori o testo inaspettato.",
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
background-attachment: fixed;
|
||||
background-size: cover;
|
||||
background-position: 50% 50%;
|
||||
z-index: -1;
|
||||
filter: blur(7px) contrast(50%) brightness(50%);
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
|
@ -16,13 +14,18 @@
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
.postcard-vis-background {
|
||||
z-index: -1;
|
||||
filter: blur(7px) contrast(50%) brightness(50%);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.postcard {
|
||||
.postcard-vis-background {
|
||||
filter: blur(7px) contrast(25%) brightness(175%);
|
||||
}
|
||||
}
|
||||
|
||||
.postcard-visible {
|
||||
.postcard-vis-foreground {
|
||||
z-index: 1;
|
||||
filter: none;
|
||||
}
|
Loading…
Reference in a new issue