diff options
author | 2025-04-26 15:31:33 +0530 | |
---|---|---|
committer | 2025-04-26 15:31:33 +0530 | |
commit | 8c9677ffc5aef95964b42c03690eb5ea1b912b13 (patch) | |
tree | 8d1941b0e591e601288387c464db098e66e9b365 /app/src/components/ShareLocationForm.tsx | |
download | realtimeloc-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.tsx | 176 |
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 |