Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion integrations/evaluations/app/actions/manage/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { findInstance } from "~/lib/instance";
import { makePubFromDoi, makePubFromTitle, makePubFromUrl } from "~/lib/metadata";
import { client } from "~/lib/pubpub";

export const manage = async (instanceId: string) => {
export const manage = async (instanceId: string, pubId: string, email: Create<typeof client>) => {
try {
console.log(`Instance: ${instanceId}, pubId: ${pubId}, email: ${email}`);
return {};
} catch (error) {
return { error: error.message };
Expand Down
130 changes: 130 additions & 0 deletions integrations/evaluations/app/actions/manage/emailForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import {
Button,
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
Icon,
Input,
Textarea,
useLocalStorage,
useToast,
} from "ui";
import { cn } from "utils";
import * as z from "zod";
import { manage } from "./actions";

type Props = {
instanceId: string;
pubId: string;
};

// TODO: generate fields using instance's configured PubType
const schema = z.object({
Email: z.string().email("Enter a valid email address"),
});

export function EmailForm(props: Props) {
const { pubId } = props;
const { toast } = useToast();
const form = useForm<z.infer<typeof schema>>({
mode: "onChange",
reValidateMode: "onChange",
// TODO: generate fields using instance's configured PubType
resolver: zodResolver(schema),
defaultValues: {
Email: "",
},
});
const [persistedValues, persist] = useLocalStorage<z.infer<typeof schema>>(props.instanceId);

const onSubmit = async (email: z.infer<typeof schema>) => {
const result = await manage(props.instanceId, props.pubId, email);
if ("error" in result && typeof result.error === "string") {
toast({
title: "Error",
description: result.error,
variant: "destructive",
});
} else {
toast({
title: "Success",
description: "The email was sent successfully",
});
form.reset();
}
};

// Load the persisted values.
const { reset } = form;
useEffect(() => {
// `keepDefaultValues` is set to true to prevent the form from
// validating fields that were not filled during the previous session.
reset(persistedValues, { keepDefaultValues: true });
}, [reset]);

// Persist form values to local storage. This operation is debounced by
// the timeout passed to <LocalStorageProvider>.
const values = form.watch();
useEffect(() => {
persist(values);
}, [values]);

return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<Card>
<CardContent className={cn("flex flex-col column gap-4")}>
<FormField
control={form.control}
name="Email"
render={({ field }) => (
<FormItem>
<FormLabel>Email Address</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>
The email of the evaluator you'd like to invite.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</CardContent>
<CardFooter className={cn("flex justify-between")}>
<Button
variant="outline"
onClick={(e) => {
e.preventDefault();
window.history.back();
}}
>
Go Back
</Button>
<Button type="submit" disabled={!form.formState.isValid}>
{form.formState.isSubmitting && (
<Icon.Loader2 className="h-4 w-4 mr-2 animate-spin" />
)}
Invite
</Button>
</CardFooter>
</Card>
</form>
</Form>
);
}
12 changes: 10 additions & 2 deletions integrations/evaluations/app/actions/manage/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { EmailForm } from "./emailForm";

type Props = {
searchParams: {
instanceId: string;
pubId: any;
};
};

export default async function Page(props: Props) {
const { instanceId } = props.searchParams;
return <h1>Evaluation Integration</h1>;
const { instanceId, pubId } = props.searchParams;
return (
<>
<h1>Evaluation Integration</h1>
<EmailForm instanceId={instanceId} pubId={pubId} />
</>
);
}