calendar initial

This commit is contained in:
Kalle (Sendou) 2021-03-22 12:09:00 +02:00
parent 8b76ee59f3
commit 3fc22c7269
6 changed files with 223 additions and 2 deletions

View File

@ -0,0 +1,20 @@
import { Button } from "@chakra-ui/button";
import { Trans } from "@lingui/macro";
import { useState } from "react";
import { EventModal } from "./EventModal";
export default function CalendarPage() {
const [modalIsOpen, setModalIsOpen] = useState(false);
return null;
return (
<div>
<Button size="sm" onClick={() => setModalIsOpen(true)}>
<Trans>Add event</Trans>
</Button>
{modalIsOpen && (
<EventModal onClose={() => setModalIsOpen(false)} event={false} />
)}
</div>
);
}

View File

@ -0,0 +1,137 @@
import { Button } from "@chakra-ui/button";
import {
FormControl,
FormErrorMessage,
FormHelperText,
FormLabel,
} from "@chakra-ui/form-control";
import { Input } from "@chakra-ui/input";
import { Flex } from "@chakra-ui/layout";
import {
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
} from "@chakra-ui/modal";
import { zodResolver } from "@hookform/resolvers/zod";
import { t, Trans } from "@lingui/macro";
import { useForm } from "react-hook-form";
import { FiTrash } from "react-icons/fi";
import { eventSchema } from "utils/validators/event";
import * as z from "zod";
type FormData = z.infer<typeof eventSchema>;
export function EventModal({
onClose,
event,
}: {
onClose: () => void;
event: boolean;
}) {
const { handleSubmit, errors, register, watch, control } = useForm<FormData>({
resolver: zodResolver(eventSchema),
// defaultValues: {
// headAbilities: ([
// "UNKNOWN",
// "UNKNOWN",
// "UNKNOWN",
// "UNKNOWN",
// ] as unknown) as Ability[],
// clothingAbilities: ([
// "UNKNOWN",
// "UNKNOWN",
// "UNKNOWN",
// "UNKNOWN",
// ] as unknown) as Ability[],
// shoesAbilities: ([
// "UNKNOWN",
// "UNKNOWN",
// "UNKNOWN",
// "UNKNOWN",
// ] as unknown) as Ability[],
// weapon: weapons.includes(weaponFromQuery as any)
// ? weaponFromQuery
// : undefined,
// ...build,
// },
});
const onSubmit = (values: any) => {
console.log(values);
};
const onDelete = async () => {
console.log("delete");
};
return (
<Modal isOpen onClose={onClose} size="xl" closeOnOverlayClick={false}>
<ModalOverlay>
<ModalContent>
<ModalHeader>
{event ? (
<Trans>Editing event</Trans>
) : (
<Trans>Adding a new event</Trans>
)}
</ModalHeader>
<ModalCloseButton borderRadius="50%" />
<form onSubmit={handleSubmit(onSubmit)}>
<ModalBody pb={6}>
{event && (
<Button
leftIcon={<FiTrash />}
variant="outline"
color="red.500"
mb={6}
//isLoading={deleting}
onClick={async () => {
if (window.confirm(t`Delete the event?`)) await onDelete();
}}
>
<Trans>Delete build</Trans>
</Button>
)}
<FormLabel htmlFor="name">
<Trans>Name</Trans>
</FormLabel>
<FormControl isInvalid={!!errors.name}>
<Input name="name" ref={register} />
<FormErrorMessage>{errors.name}</FormErrorMessage>
</FormControl>
<FormLabel htmlFor="date" mt={4}>
<Trans>Date</Trans>
</FormLabel>
<FormControl isInvalid={!!errors.date}>
<Flex>
<Input ref={register} type="date" mr={2} />
<Input ref={register} type="time" ml={2} />
</Flex>
<FormHelperText>
<Trans>Input the time in your local time zone:</Trans>{" "}
{Intl.DateTimeFormat().resolvedOptions().timeZone}
</FormHelperText>
<FormErrorMessage>{errors.date}</FormErrorMessage>
</FormControl>
</ModalBody>
<ModalFooter>
<Button mr={3} type="submit" /*isLoading={sending}*/>
<Trans>Save</Trans>
</Button>
<Button onClick={onClose} variant="outline">
<Trans>Cancel</Trans>
</Button>
</ModalFooter>
</form>
</ModalContent>
</ModalOverlay>
</Modal>
);
}

View File

@ -21,7 +21,6 @@ import {
} from "@chakra-ui/react";
import { zodResolver } from "@hookform/resolvers/zod";
import { t, Trans } from "@lingui/macro";
import { useLingui } from "@lingui/react";
import MarkdownTextarea from "components/common/MarkdownTextarea";
import { GetAllFreeAgentPostsData } from "prisma/queries/getAllFreeAgentPosts";
import { useState } from "react";
@ -47,7 +46,6 @@ type FormData = z.infer<typeof freeAgentPostSchema>;
const FAModal: React.FC<Props> = ({ onClose, post }) => {
const [sending, setSending] = useState(false);
const [deleting, setDeleting] = useState(false);
const { i18n } = useLingui();
const { handleSubmit, errors, register, watch, control } = useForm<FormData>({
resolver: zodResolver(freeAgentPostSchema),

29
pages/calendar.tsx Normal file
View File

@ -0,0 +1,29 @@
import CalendarPage from "app/calendar/components/CalendarPage";
import HeaderBanner from "components/layout/HeaderBanner";
// import { ssr } from "pages/api/trpc/[trpc]";
// import { trpc } from "utils/trpc";
// export const getStaticProps = async () => {
// await Promise.all([
// ssr.prefetchQuery("plus.suggestions"),
// ssr.prefetchQuery("plus.statuses"),
// ]);
// return {
// props: {
// dehydratedState: trpc.dehydrate(),
// },
// revalidate: 60,
// };
// };
// @ts-expect-error
CalendarPage.header = (
<HeaderBanner
icon="calendar"
title="Calendar"
subtitle="Upcoming tournaments and other events."
/>
);
export default CalendarPage;

View File

@ -57,6 +57,9 @@ const Home = () => {
What exactly is the effect of your builds? Guess no more.
</Trans>
</PageInfoSection>
<PageInfoSection location="u" title={t`Calendar`}>
<Trans>View all the upcoming events in the community.</Trans>
</PageInfoSection>
<PageInfoSection location="u" title={t`User Search`}>
<Trans>
You can make your own page. Use this tool to find other users'

34
utils/validators/event.ts Normal file
View File

@ -0,0 +1,34 @@
import * as z from "zod";
export const EVENT_DESCRIPTION_LIMIT = 2000;
export const eventSchema = z.object({
name: z.string().min(5).max(100),
description: z.string().min(10).max(EVENT_DESCRIPTION_LIMIT),
date: z.date().refine((val) => {
const now = new Date();
if (now.getTime() < val.getTime()) return false;
now.setMonth(now.getMonth() + 3);
if (now.getTime() < val.getTime()) return false;
return true;
}),
eventUrl: z.string().url(),
discordInviteUrl: z.string().optional().nullable(),
tags: z.array(z.enum(["SZ_ONLY"])),
isTournament: z.boolean(),
format: z.array(
z.enum([
"SE",
"DE",
"GROUPS2SE",
"GROUPS2DE",
"SWISS2SE",
"SWISS2DE",
"SWISS",
"OTHER",
])
),
});