Merge pull request #454 from femyeda/issues-w-caldav

This commit is contained in:
Peer_Rich 2021-08-15 16:26:09 +02:00 committed by GitHub
commit ce63c55051
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 43 deletions

View file

@ -4,6 +4,8 @@ type Props = {
onSubmit: () => void; onSubmit: () => void;
}; };
export const ADD_CALDAV_INTEGRATION_FORM_TITLE = "addCalDav";
const AddCalDavIntegration = React.forwardRef<HTMLFormElement, Props>((props, ref) => { const AddCalDavIntegration = React.forwardRef<HTMLFormElement, Props>((props, ref) => {
const onSubmit = (event) => { const onSubmit = (event) => {
event.preventDefault(); event.preventDefault();
@ -13,7 +15,7 @@ const AddCalDavIntegration = React.forwardRef<HTMLFormElement, Props>((props, re
}; };
return ( return (
<form id="addCalDav" ref={ref} onSubmit={onSubmit}> <form id={ADD_CALDAV_INTEGRATION_FORM_TITLE} ref={ref} onSubmit={onSubmit}>
<div className="mb-2"> <div className="mb-2">
<label htmlFor="username" className="block text-sm font-medium text-gray-700"> <label htmlFor="username" className="block text-sm font-medium text-gray-700">
Calendar URL Calendar URL

View file

@ -69,10 +69,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
} }
} catch (reason) { } catch (reason) {
logger.error("Could not add this caldav account", reason); logger.error("Could not add this caldav account", reason);
return res.status(200).json({ message: "Could not add this caldav account" }); return res.status(500).json({ message: "Could not add this caldav account" });
} }
// TODO VALIDATE URL
// TODO VALIDATE CONNECTION IS POSSIBLE
return res.status(200).json({}); return res.status(200).json({});
} }

View file

@ -2,14 +2,16 @@ import Head from "next/head";
import Link from "next/link"; import Link from "next/link";
import prisma from "../../lib/prisma"; import prisma from "../../lib/prisma";
import Shell from "../../components/Shell"; import Shell from "../../components/Shell";
import { useEffect, useState, useRef } from "react"; import { useEffect, useState, useRef, useCallback } from "react";
import { getSession, useSession } from "next-auth/client"; import { getSession, useSession } from "next-auth/client";
import { CheckCircleIcon, ChevronRightIcon, PlusIcon, XCircleIcon } from "@heroicons/react/solid"; import { CheckCircleIcon, ChevronRightIcon, PlusIcon, XCircleIcon } from "@heroicons/react/solid";
import { InformationCircleIcon } from "@heroicons/react/outline"; import { InformationCircleIcon } from "@heroicons/react/outline";
import { Dialog, DialogClose, DialogContent, DialogHeader, DialogTrigger } from "@components/Dialog"; import { Dialog, DialogClose, DialogContent, DialogHeader, DialogTrigger } from "@components/Dialog";
import Switch from "@components/ui/Switch"; import Switch from "@components/ui/Switch";
import Loader from "@components/Loader"; import Loader from "@components/Loader";
import AddCalDavIntegration from "@lib/integrations/CalDav/components/AddCalDavIntegration"; import AddCalDavIntegration, {
ADD_CALDAV_INTEGRATION_FORM_TITLE,
} from "@lib/integrations/CalDav/components/AddCalDavIntegration";
type Integration = { type Integration = {
installed: boolean; installed: boolean;
@ -30,6 +32,7 @@ export default function Home({ integrations }: Props) {
const [selectableCalendars, setSelectableCalendars] = useState([]); const [selectableCalendars, setSelectableCalendars] = useState([]);
const addCalDavIntegrationRef = useRef<HTMLFormElement>(null); const addCalDavIntegrationRef = useRef<HTMLFormElement>(null);
const [isAddCalDavIntegrationDialogOpen, setIsAddCalDavIntegrationDialogOpen] = useState(false); const [isAddCalDavIntegrationDialogOpen, setIsAddCalDavIntegrationDialogOpen] = useState(false);
const [addCalDavError, setAddCalDavError] = useState<{ message: string } | null>(null);
useEffect(loadCalendars, [integrations]); useEffect(loadCalendars, [integrations]);
@ -43,6 +46,7 @@ export default function Home({ integrations }: Props) {
function integrationHandler(type) { function integrationHandler(type) {
if (type === "caldav_calendar") { if (type === "caldav_calendar") {
setAddCalDavError(null);
setIsAddCalDavIntegrationDialogOpen(true); setIsAddCalDavIntegrationDialogOpen(true);
return; return;
} }
@ -59,7 +63,7 @@ export default function Home({ integrations }: Props) {
password, password,
}); });
await fetch("/api/integrations/caldav/add", { return await fetch("/api/integrations/caldav/add", {
method: "POST", method: "POST",
body: requestBody, body: requestBody,
headers: { headers: {
@ -133,20 +137,11 @@ export default function Home({ integrations }: Props) {
<p className="text-gray-400 text-sm">{integration.description}</p> <p className="text-gray-400 text-sm">{integration.description}</p>
</div> </div>
<div className="w-2/12 text-right pt-2"> <div className="w-2/12 text-right pt-2">
{integration.type === "caldav_calendar" ? ( <button
<button onClick={() => integrationHandler(integration.type)}
onClick={() => integrationHandler(integration.type)} className="font-medium text-neutral-900 hover:text-neutral-500">
className="font-medium text-neutral-900 hover:text-neutral-500"> Add
Add </button>
</button>
) : (
// <ConnectCalDavServerDialog isOpen={isOpen}/>
<button
onClick={() => integrationHandler(integration.type)}
className="font-medium text-neutral-900 hover:text-neutral-500">
Add
</button>
)}
</div> </div>
</li> </li>
); );
@ -206,41 +201,43 @@ export default function Home({ integrations }: Props) {
</Dialog> </Dialog>
); );
function handleAddCalDavIntegrationSaveButtonPress() { const handleAddCalDavIntegrationSaveButtonPress = async () => {
const form = addCalDavIntegrationRef.current.elements; const form = addCalDavIntegrationRef.current.elements;
const url = form.url.value; const url = form.url.value;
const password = form.password.value; const password = form.password.value;
const username = form.username.value; const username = form.username.value;
try { try {
handleAddCalDavIntegration({ username, password, url }); setAddCalDavError(null);
const addCalDavIntegrationResponse = await handleAddCalDavIntegration({ username, password, url });
if (addCalDavIntegrationResponse.ok) {
setIsAddCalDavIntegrationDialogOpen(false);
} else {
const j = await addCalDavIntegrationResponse.json();
setAddCalDavError({ message: j.message });
}
} catch (reason) { } catch (reason) {
console.error(reason); console.error(reason);
} }
}
const onSubmit = () => {
const form = addCalDavIntegrationRef.current;
if (form) {
if (typeof form.requestSubmit === "function") {
form.requestSubmit();
} else {
form.dispatchEvent(new Event("submit", { cancelable: true }));
}
setIsAddCalDavIntegrationDialogOpen(false);
}
}; };
const ConnectCalDavServerDialog = ({ isOpen }) => { const ConnectCalDavServerDialog = useCallback(() => {
return ( return (
<Dialog open={isOpen}> <Dialog
open={isAddCalDavIntegrationDialogOpen}
onOpenChange={(isOpen) => setIsAddCalDavIntegrationDialogOpen(isOpen)}>
<DialogContent> <DialogContent>
<DialogHeader <DialogHeader
title="Connect to CalDav Server" title="Connect to CalDav Server"
subtitle="Your credentials will be stored and encrypted." subtitle="Your credentials will be stored and encrypted."
/> />
<div className="my-4"> <div className="my-4">
{addCalDavError && (
<p className="text-red-700 text-sm">
<span className="font-bold">Error: </span>
{addCalDavError.message}
</p>
)}
<AddCalDavIntegration <AddCalDavIntegration
ref={addCalDavIntegrationRef} ref={addCalDavIntegrationRef}
onSubmit={handleAddCalDavIntegrationSaveButtonPress} onSubmit={handleAddCalDavIntegrationSaveButtonPress}
@ -248,18 +245,24 @@ export default function Home({ integrations }: Props) {
</div> </div>
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse"> <div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
<button <button
onClick={onSubmit} type="submit"
form={ADD_CALDAV_INTEGRATION_FORM_TITLE}
className="flex justify-center py-2 px-4 border border-transparent rounded-sm shadow-sm text-sm font-medium text-white bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900"> className="flex justify-center py-2 px-4 border border-transparent rounded-sm shadow-sm text-sm font-medium text-white bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
Save Save
</button> </button>
<DialogClose as="button" className="btn btn-white mx-2"> <DialogClose
onClick={() => {
setIsAddCalDavIntegrationDialogOpen(false);
}}
as="button"
className="btn btn-white mx-2">
Cancel Cancel
</DialogClose> </DialogClose>
</div> </div>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
); );
}; }, [isAddCalDavIntegrationDialogOpen, addCalDavError]);
if (loading) { if (loading) {
return <Loader />; return <Loader />;
@ -367,7 +370,7 @@ export default function Home({ integrations }: Props) {
</div> </div>
</div> </div>
</div> </div>
<ConnectCalDavServerDialog isOpen={isAddCalDavIntegrationDialogOpen} /> <ConnectCalDavServerDialog />
</Shell> </Shell>
</div> </div>
); );