suggestion frontend

This commit is contained in:
Kalle 2021-02-22 13:42:47 +02:00
parent ec77a7c1b6
commit 94bda2e1b0
5 changed files with 213 additions and 0 deletions

View File

@ -71,6 +71,7 @@ const UserSelector: React.FC<SingleSelectorProps | MultiSelectorProps> = ({
),
}}
hideMenuBeforeTyping
isClearable={!isMulti}
/>
);

View File

@ -0,0 +1,21 @@
import { Button } from "@chakra-ui/button";
import { Box } from "@chakra-ui/layout";
import { Trans } from "@lingui/macro";
import SuggestionVouchModal from "./SuggestionVouchModal";
export interface PlusHomePageProps {}
const PlusHomePage: React.FC<PlusHomePageProps> = () => {
return (
<>
<SuggestionVouchModal
canSuggest={true}
canVouch={false}
userPlusTier={1}
/>
<Box>No suggestions yet for this month</Box>
</>
);
};
export default PlusHomePage;

View File

@ -0,0 +1,142 @@
import {
Button,
Modal,
ModalCloseButton,
ModalHeader,
ModalOverlay,
ModalContent,
ModalBody,
ModalFooter,
FormControl,
FormLabel,
Textarea,
FormHelperText,
FormErrorMessage,
Select,
} from "@chakra-ui/react";
import { Trans, t } from "@lingui/macro";
import { useState } from "react";
import { Controller, useForm } from "react-hook-form";
import {
suggestionSchema,
SUGGESTION_DESCRIPTION_LIMIT,
} from "lib/validators/suggestion";
import * as z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import UserSelector from "components/common/UserSelector";
interface Props {
canVouch: boolean;
canSuggest: boolean;
userPlusTier: number;
}
type FormData = z.infer<typeof suggestionSchema>;
const SuggestionVouchModal: React.FC<Props> = ({
canVouch,
canSuggest,
userPlusTier,
}) => {
const [isOpen, setIsOpen] = useState(false);
const sending = false; //usemutation hook
const { handleSubmit, errors, register, watch, control } = useForm<FormData>({
resolver: zodResolver(suggestionSchema),
});
const watchDescription = watch("description", "");
if (!canVouch && !canSuggest) return null;
const getButtonText = () => {
if (canSuggest && canVouch) return t`Add new suggestion or vouch`;
if (canVouch) return t`Vouch`;
return t`Add new suggestion`;
};
return (
<>
<Button size="sm" mb={4} onClick={() => setIsOpen(true)}>
{getButtonText()}
</Button>
{isOpen && (
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
size="xl"
closeOnOverlayClick={false}
>
<ModalOverlay>
<ModalContent>
<ModalHeader>
<Trans>Adding a new suggestion or vouch</Trans>
</ModalHeader>
<ModalCloseButton borderRadius="50%" />
<form>
<ModalBody pb={2}>
<FormLabel>
<Trans>Tier</Trans>
</FormLabel>
<Controller
name="tier"
control={control}
defaultValue={1}
render={({ value, onChange }) => (
<Select
value={value}
onChange={(e) => onChange(Number(e.target.value))}
>
{userPlusTier === 1 && <option value="1">+1</option>}
{userPlusTier <= 2 && <option value="2">+2</option>}
{false && <option value="3">+3</option>}
</Select>
)}
/>
<FormLabel mt={4}>
<Trans>User</Trans>
</FormLabel>
<Controller
name="suggestedUserId"
control={control}
render={({ value, onChange }) => (
<UserSelector
value={value}
setValue={onChange}
isMulti={false}
maxMultiCount={undefined}
/>
)}
/>
<FormControl isInvalid={!!errors.description}>
<FormLabel htmlFor="description" mt={4}>
<Trans>Description</Trans>
</FormLabel>
<Textarea name="description" ref={register} />
<FormHelperText>
{(watchDescription ?? "").length}/
{SUGGESTION_DESCRIPTION_LIMIT}
</FormHelperText>
<FormErrorMessage>
{errors.description?.message}
</FormErrorMessage>
</FormControl>
</ModalBody>
<ModalFooter>
<Button mr={3} type="submit" isLoading={sending}>
<Trans>Save</Trans>
</Button>
<Button onClick={() => setIsOpen(false)} variant="outline">
<Trans>Cancel</Trans>
</Button>
</ModalFooter>
</form>
</ModalContent>
</ModalOverlay>
</Modal>
)}
</>
);
};
export default SuggestionVouchModal;

View File

@ -0,0 +1,9 @@
import * as z from "zod";
export const SUGGESTION_DESCRIPTION_LIMIT = 500;
export const suggestionSchema = z.object({
description: z.string().max(SUGGESTION_DESCRIPTION_LIMIT),
suggestedUserId: z.number().int(),
tier: z.number().int().min(1).max(3),
});

40
pages/plus/index.tsx Normal file
View File

@ -0,0 +1,40 @@
import PlusHomePage from "components/plus/PlusHomePage";
// export const getStaticProps: GetStaticProps<PlusVotingHistoryPageProps> = async ({
// params,
// }) => {
// const getSlug = async () => {
// const slug = Array.isArray(params!.slug) ? params!.slug : [];
// if (slug.length === 3) {
// return slug;
// }
// if (slug.length > 0) {
// return [];
// }
// const mostRecent = await plusService.getMostRecentVotingWithResultsMonth();
// return ["1", mostRecent.year, mostRecent.month];
// };
// const [tier, year, month] = (await getSlug()).map((param) => Number(param));
// if (!tier) return { notFound: true };
// const [summaries, monthsWithData] = await Promise.all([
// plusService.getVotingSummariesByMonthAndTier({
// tier: tier as any,
// year,
// month,
// }),
// plusService.getDistinctSummaryMonths(),
// ]);
// if (!summaries.length) return { notFound: true };
// return {
// props: { summaries, monthsWithData },
// };
// };
export default PlusHomePage;