aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/components/ShareLocationForm.tsx
diff options
context:
space:
mode:
authorLibravatarLibravatar Biswa Kalyan Bhuyan <[email protected]> 2025-04-26 15:31:33 +0530
committerLibravatarLibravatar Biswa Kalyan Bhuyan <[email protected]> 2025-04-26 15:31:33 +0530
commit8c9677ffc5aef95964b42c03690eb5ea1b912b13 (patch)
tree8d1941b0e591e601288387c464db098e66e9b365 /app/src/components/ShareLocationForm.tsx
downloadrealtimeloc-8c9677ffc5aef95964b42c03690eb5ea1b912b13.tar.gz
realtimeloc-8c9677ffc5aef95964b42c03690eb5ea1b912b13.tar.bz2
realtimeloc-8c9677ffc5aef95964b42c03690eb5ea1b912b13.zip
testing location tracker
Diffstat (limited to 'app/src/components/ShareLocationForm.tsx')
-rw-r--r--app/src/components/ShareLocationForm.tsx176
1 files changed, 176 insertions, 0 deletions
diff --git a/app/src/components/ShareLocationForm.tsx b/app/src/components/ShareLocationForm.tsx
new file mode 100644
index 0000000..ddebfab
--- /dev/null
+++ b/app/src/components/ShareLocationForm.tsx
@@ -0,0 +1,176 @@
+"use client";
+
+import { useState } from "react";
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import * as z from "zod";
+import { toast } from "sonner";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Label } from "@/components/ui/label";
+import {
+ Form,
+ FormControl,
+ FormDescription,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from "@/components/ui/form";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+
+// Form validation schema
+const shareFormSchema = z.object({
+ email: z.string().email("Please enter a valid email address"),
+ senderName: z.string().min(1, "Please enter your name"),
+ expiryHours: z.coerce.number().min(0).optional(),
+});
+
+type ShareFormValues = z.infer<typeof shareFormSchema>;
+
+interface ShareLocationFormProps {
+ location: {
+ latitude: number;
+ longitude: number;
+ accuracy?: number;
+ } | null;
+}
+
+export default function ShareLocationForm({ location }: ShareLocationFormProps) {
+ const [isSubmitting, setIsSubmitting] = useState(false);
+
+ const form = useForm<ShareFormValues>({
+ resolver: zodResolver(shareFormSchema),
+ defaultValues: {
+ email: "",
+ senderName: "",
+ expiryHours: 24,
+ },
+ });
+
+ const onSubmit = async (values: ShareFormValues) => {
+ if (!location) {
+ toast.error("No location data available to share");
+ return;
+ }
+
+ setIsSubmitting(true);
+
+ try {
+ const response = await fetch("/api/share-location", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ ...values,
+ latitude: location.latitude,
+ longitude: location.longitude,
+ accuracy: location.accuracy,
+ }),
+ });
+
+ const data = await response.json();
+
+ if (!response.ok) {
+ if (data.emailError) {
+ toast.error(`Email error: ${data.message || 'Failed to send notification email'}`);
+ toast.info("Location was generated but notification couldn't be sent");
+ return;
+ }
+ throw new Error(data.message || data.error || "Failed to share location");
+ }
+
+ if (data.data?.devMode) {
+ toast.success("Dev mode: Email would be sent (check server logs)");
+ form.reset();
+ return;
+ }
+
+ toast.success(`Location shared with ${values.email}`);
+ form.reset();
+ } catch (error) {
+ console.error("Error sharing location:", error);
+ toast.error("Failed to share location. Please try again.");
+ } finally {
+ setIsSubmitting(false);
+ }
+ };
+
+ return (
+ <Card>
+ <CardHeader>
+ <CardTitle className="text-xl">Share Your Location</CardTitle>
+ </CardHeader>
+ <CardContent>
+ <Form {...form}>
+ <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
+ <FormField
+ control={form.control}
+ name="email"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>Email Address</FormLabel>
+ <FormControl>
+ <Input placeholder="[email protected]" {...field} />
+ </FormControl>
+ <FormDescription>
+ The email address to share your location with.
+ </FormDescription>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ <FormField
+ control={form.control}
+ name="senderName"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>Your Name</FormLabel>
+ <FormControl>
+ <Input placeholder="Your Name" {...field} />
+ </FormControl>
+ <FormDescription>
+ Your name will be included in the email.
+ </FormDescription>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ <FormField
+ control={form.control}
+ name="expiryHours"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>Expiry Time (hours)</FormLabel>
+ <FormControl>
+ <Input
+ type="number"
+ min="0"
+ placeholder="24"
+ {...field}
+ />
+ </FormControl>
+ <FormDescription>
+ How long the location share will be valid (0 for no expiry)
+ </FormDescription>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ <Button
+ type="submit"
+ className="w-full"
+ disabled={isSubmitting || !location}
+ >
+ {isSubmitting ? "Sharing..." : "Share Location"}
+ </Button>
+ </form>
+ </Form>
+ </CardContent>
+ </Card>
+ );
+} \ No newline at end of file