mirror of
https://github.com/Steffo99/festa.git
synced 2025-01-03 12:34:20 +00:00
Do some more progress
This commit is contained in:
parent
7ffd43268d
commit
783121b140
8 changed files with 119 additions and 28 deletions
|
@ -4,6 +4,8 @@ import { HTMLProps } from "react";
|
||||||
import { useMyEvents } from "../hooks/useMyEvents";
|
import { useMyEvents } from "../hooks/useMyEvents";
|
||||||
import { Loading } from "./Loading";
|
import { Loading } from "./Loading";
|
||||||
import { Event } from "@prisma/client";
|
import { Event } from "@prisma/client";
|
||||||
|
import { EventList } from "./EventList";
|
||||||
|
import { EventCreate } from "./EventCreate";
|
||||||
|
|
||||||
|
|
||||||
export function ActionEventList(props: HTMLProps<HTMLFormElement>) {
|
export function ActionEventList(props: HTMLProps<HTMLFormElement>) {
|
||||||
|
@ -27,7 +29,7 @@ export function ActionEventList(props: HTMLProps<HTMLFormElement>) {
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
else if(!data) {
|
else if(!data) {
|
||||||
contents = <Loading/>
|
contents = <Loading text={t("eventListLoading")}/>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(data.length === 0) {
|
if(data.length === 0) {
|
||||||
|
@ -35,6 +37,7 @@ export function ActionEventList(props: HTMLProps<HTMLFormElement>) {
|
||||||
<p>
|
<p>
|
||||||
{t("eventListCreateFirst")}
|
{t("eventListCreateFirst")}
|
||||||
</p>
|
</p>
|
||||||
|
<EventCreate/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -42,23 +45,11 @@ export function ActionEventList(props: HTMLProps<HTMLFormElement>) {
|
||||||
<p>
|
<p>
|
||||||
{t("eventListDescription")}
|
{t("eventListDescription")}
|
||||||
</p>
|
</p>
|
||||||
<div>
|
<EventList data={data}/>
|
||||||
{data.map((event: Event) => <div><a href={`/events/${event.slug}`}>{event.name}</a></div>)}
|
|
||||||
</div>
|
|
||||||
<p>
|
<p>
|
||||||
{t("eventListCreateAnother")}
|
{t("eventListCreateAnother")}
|
||||||
</p>
|
</p>
|
||||||
<form className="form-monorow">
|
<EventCreate/>
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
placeholder={t("eventListCreatePlaceholder")}
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="submit"
|
|
||||||
className="positive square-40"
|
|
||||||
value="→"
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
41
components/EventCreate.tsx
Normal file
41
components/EventCreate.tsx
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import { useTranslation } from "next-i18next"
|
||||||
|
import { FormEvent, MouseEventHandler, useCallback, useRef, useState } from "react"
|
||||||
|
import { Loading } from "./Loading"
|
||||||
|
|
||||||
|
export function EventCreate() {
|
||||||
|
const {t} = useTranslation()
|
||||||
|
const [name, setName] = useState<string>("")
|
||||||
|
const [running, setRunning] = useState<boolean>(false)
|
||||||
|
|
||||||
|
const createEvent = useCallback(() => {
|
||||||
|
setRunning(true)
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
|
if(running) return <Loading text={t("eventListCreateRunning")}/>
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
className="form-monorow"
|
||||||
|
onSubmit={e => {e.preventDefault(); createEvent()}}
|
||||||
|
noValidate
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder={t("eventListCreateEventNameLabel")}
|
||||||
|
value={name}
|
||||||
|
onChange={e => setName(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="submit"
|
||||||
|
aria-label={t("eventListCreateSubmitLabel")}
|
||||||
|
className="positive square-40"
|
||||||
|
value="→"
|
||||||
|
onClick={e => createEvent()}
|
||||||
|
disabled={!name}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
}
|
18
components/EventList.tsx
Normal file
18
components/EventList.tsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { Event } from "@prisma/client"
|
||||||
|
import Link from "next/link"
|
||||||
|
|
||||||
|
type EventListProps = {
|
||||||
|
data: Event[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EventList(props: EventListProps) {
|
||||||
|
const contents = props.data.map(e => (
|
||||||
|
<li key={e.slug}>
|
||||||
|
<Link href={`/events/${e.slug}`}>
|
||||||
|
{e.name}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))
|
||||||
|
|
||||||
|
return <ul className="list-events">{contents}</ul>
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ import { useTranslation } from "next-i18next";
|
||||||
import { FestaIcon } from "./FestaIcon";
|
import { FestaIcon } from "./FestaIcon";
|
||||||
|
|
||||||
type LoadingProps = {
|
type LoadingProps = {
|
||||||
text?: string
|
text: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Loading(props: LoadingProps) {
|
export function Loading(props: LoadingProps) {
|
||||||
|
@ -13,7 +13,7 @@ export function Loading(props: LoadingProps) {
|
||||||
<span>
|
<span>
|
||||||
<FestaIcon icon={faAsterisk} spin/>
|
<FestaIcon icon={faAsterisk} spin/>
|
||||||
|
|
||||||
{props.text ?? t("genericLoading")}
|
{props.text}
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -28,6 +28,8 @@ const App = ({ Component, pageProps }: AppProps): JSX.Element => {
|
||||||
const swrConfig = {
|
const swrConfig = {
|
||||||
fetcher: async (resource: string, localAxiosConfig: AxiosRequestConfig<any>) => {
|
fetcher: async (resource: string, localAxiosConfig: AxiosRequestConfig<any>) => {
|
||||||
const response = await axios.get(resource, {...axiosConfig, ...localAxiosConfig})
|
const response = await axios.get(resource, {...axiosConfig, ...localAxiosConfig})
|
||||||
|
// To test loading uncomment the following line:
|
||||||
|
// await new Promise(res => setTimeout(res, 100000))
|
||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
"genericLoading": "Caricamento...",
|
"genericLoading": "Caricamento...",
|
||||||
"eventListError": "Si è verificato il seguente errore durante il recupero dei tuoi eventi:",
|
"eventListError": "Si è verificato il seguente errore durante il recupero dei tuoi eventi:",
|
||||||
"eventListDescription": "Questi sono gli eventi che hai creato:",
|
"eventListDescription": "Questi sono gli eventi che hai creato:",
|
||||||
"eventListCreateAnother": "Se vuoi crearne un altro, inserisci il suo nome qui sotto:",
|
"eventListCreateAnother": "Se vuoi crearne un altro, inseriscine il nome qui sotto:",
|
||||||
"eventListCreateFirst": "Inserisci il nome del tuo primo evento qui sotto!",
|
"eventListCreateFirst": "Inserisci il nome del tuo primo evento qui sotto!",
|
||||||
"eventListCreatePlaceholder": "Nome evento"
|
"eventListCreateEventNameLabel": "Nome evento",
|
||||||
|
"eventListCreateSubmitLabel": "Crea",
|
||||||
|
"eventListCreateRunning": "Creazione in corso..."
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,10 +77,15 @@ input[type="submit"], button {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="submit"]:active, button:active {
|
input[type="submit"]:active:not([disabled]), button:active:not([disabled]) {
|
||||||
border-style: inset;
|
border-style: inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*[disabled] {
|
||||||
|
opacity: 0.2;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
.square-40 {
|
.square-40 {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
@ -124,10 +129,35 @@ input.negative, button.negative {
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-monorow {
|
.form-monorow {
|
||||||
|
max-width: 600px;
|
||||||
|
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-monorow input {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-monorow input[type="submit"] {
|
||||||
|
flex-grow: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-events {
|
||||||
|
max-height: 20vh;
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
column-count: auto;
|
||||||
|
column-width: 140px;
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#page-index {
|
#page-index {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 100%;
|
grid-template-columns: 100%;
|
||||||
grid-template-rows: 2fr 3fr;
|
grid-template-rows: auto 1fr;
|
||||||
|
|
||||||
justify-content: center;
|
justify-content: stretch;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
|
gap: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#page-index .hero-titles {
|
#page-index .hero-titles {
|
||||||
|
@ -12,25 +14,30 @@
|
||||||
grid-row: 1;
|
grid-row: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-titles h1 {
|
#page-index .hero-titles h1 {
|
||||||
font-size: 10rem;
|
font-size: 10rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-titles h2 {
|
#page-index .hero-titles h2 {
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) or (max-height: 640px) {
|
@media (max-width: 640px) or (max-height: 640px) {
|
||||||
.hero-titles h1 {
|
#page-index .hero-titles h1 {
|
||||||
font-size: 5rem;
|
font-size: 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-titles h2 {
|
#page-index .hero-titles h2 {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#page-index .hero-action {
|
#page-index .hero-action {
|
||||||
align-self: start;
|
align-self: start;
|
||||||
|
justify-self: center;
|
||||||
|
|
||||||
grid-row: 2;
|
grid-row: 2;
|
||||||
|
|
||||||
|
max-width: 800px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue