diff --git a/COMMIT_MSG.tmp b/COMMIT_MSG.tmp deleted file mode 100644 index 1017ff1c..00000000 --- a/COMMIT_MSG.tmp +++ /dev/null @@ -1,18 +0,0 @@ -feat(dx): initial project scaffolding and configuration - -this initial commit establishes a robust foundation for the project, focusing on developer experience (dx) and modern configuration standards. it addresses several inconsistencies and sets up the monorepo for scalable contributions. - -- vscode & editor config: - - introduced `.vscode/settings.json` and `extensions.json` to enforce consistent formatting (prettier on save) and recommend essential extensions. this minimizes style drift and lowers the barrier for new contributors. - - added `.gitattributes` to normalize line endings (lf), preventing cross-platform git noise. - -- typescript & build integrity: - - resolved a series of cascading typescript errors stemming from the monorepo setup. corrected the `tsconfig.json` `extends` to use a relative path, as module path aliases aren't resolved for this property. - - updated the shared `nextjs.json` config with `jsx: "react-jsx"` and `jsxImportSource: "react"`. this is critical for react 19's jsx transform and ensures the compiler can correctly resolve jsx typings across the workspace. - -- baseline cleanup: - - refactored the boilerplate `page.tsx` to provide a cleaner, more structured starting point for the web application. - -this groundwork ensures the project is stable, easy to work with, and ready for feature development. - --kofi :) diff --git a/apps/web/components/app/section/_components/create-call-modal.tsx b/apps/web/components/app/section/_components/create-call-modal.tsx index 9a184193..f0f11287 100644 --- a/apps/web/components/app/section/_components/create-call-modal.tsx +++ b/apps/web/components/app/section/_components/create-call-modal.tsx @@ -15,9 +15,11 @@ interface Contact { export function CreateCallModal({ onClose, onCallCreated, + selectedContact }: { onClose?: () => void; onCallCreated?: (callId: string) => void; + selectedContact?: string }) { const [meetingName, setMeetingName] = useState(""); const [contacts, setContacts] = useState([]); @@ -29,10 +31,40 @@ export function CreateCallModal({ const [mounted, setMounted] = useState(false); const router = useRouter(); + useEffect(() => { + const fetchContacts = async () => { + try { + const res = await fetch(`${process.env.NEXT_PUBLIC_BACKEND_URL}/api/contacts`, { + credentials: "include", + }); + if (!res.ok) { + console.error("Failed to fetch contacts"); + return; + }; + const data = await res.json(); + setContacts(data.contacts || []); + } catch (err) { + console.error("Failed to fetch contacts", err); + } + }; + fetchContacts(); + }, []); + useEffect(() => { setMounted(true); }, []); + useEffect(() => { + if (selectedContact) { + setSelectedMembers((prev) => { + if (prev.includes(selectedContact)) { + return prev; + } + return [...prev, selectedContact]; + }); + } + }, [selectedContact]); + const handleMemberToggle = (email: string) => { setSelectedMembers((prev) => prev.includes(email) ? prev.filter((e) => e !== email) : [...prev, email] diff --git a/apps/web/components/app/section/contacts-list.tsx b/apps/web/components/app/section/contacts-list.tsx index 155fe08f..f87fe83e 100644 --- a/apps/web/components/app/section/contacts-list.tsx +++ b/apps/web/components/app/section/contacts-list.tsx @@ -23,6 +23,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@call/ui/components/dropdown-menu"; +import { useModal } from "@/hooks/use-modal"; interface Contact { id: string; @@ -42,6 +43,7 @@ export default function ContactsList({ onAddContact }: ContactsListProps) { const [deletingContact, setDeletingContact] = useState(null); const [searchQuery, setSearchQuery] = useState(""); + const fetchContacts = async () => { setLoading(true); setError(null); @@ -223,6 +225,7 @@ interface ContactCardProps { } const ContactCard = ({ contact, onDeleteContact, isDeleting }: ContactCardProps) => { + const { onOpen } = useModal(); return (
@@ -236,7 +239,7 @@ const ContactCard = ({ contact, onDeleteContact, isDeleting }: ContactCardProps) - + onOpen("start-call", { selectedContact: contact.email })}> Call Contact diff --git a/apps/web/components/modal/start-call.tsx b/apps/web/components/modal/start-call.tsx index 6eadcbb8..f510ef31 100644 --- a/apps/web/components/modal/start-call.tsx +++ b/apps/web/components/modal/start-call.tsx @@ -13,7 +13,7 @@ import { LoadingButton } from "@call/ui/components/loading-button"; import { zodResolver } from "@hookform/resolvers/zod"; import { useMutation } from "@tanstack/react-query"; import { useRouter } from "next/navigation"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { z } from "zod"; @@ -24,17 +24,31 @@ const formSchema = z.object({ }); export const StartCall = () => { - const { isOpen, onClose, type } = useModal(); + const { isOpen, onClose, type, data } = useModal(); + const { selectedContact } = data; const router = useRouter(); const [selectedContacts, setSelectedContacts] = useState([]); const { user } = useSession(); + useEffect(() => { + if (selectedContact) { + setSelectedContacts((prev) => { + if (prev.includes(selectedContact)) { + return prev; + } + return [...prev, selectedContact]; + }); + } + }, [selectedContact]); + const { mutate: createCall, isPending } = useMutation({ mutationFn: CALLS_QUERY.createCall, onSuccess: (data) => { if (selectedContacts.length > 0) { toast.success( - `Invitations sent to ${selectedContacts.length} contact${selectedContacts.length !== 1 ? "s" : ""}` + `Invitations sent to ${selectedContacts.length} contact${ + selectedContacts.length !== 1 ? "s" : "" + }` ); } onClose(); @@ -103,11 +117,13 @@ export const StartCall = () => { disabled={isPending} > {selectedContacts.length > 0 - ? `Start with ${selectedContacts.length} contact${selectedContacts.length !== 1 ? "s" : ""}` + ? `Start with ${selectedContacts.length} contact${ + selectedContacts.length !== 1 ? "s" : "" + }` : "Start call"} ); -}; +}; \ No newline at end of file diff --git a/apps/web/hooks/use-modal.tsx b/apps/web/hooks/use-modal.tsx index 620ade70..32dcf442 100644 --- a/apps/web/hooks/use-modal.tsx +++ b/apps/web/hooks/use-modal.tsx @@ -19,6 +19,7 @@ interface ModalData { team?: Team; participants?: Participant[]; callInfo?: CallInfo; + selectedContact?: string; } interface ModalStore { @@ -33,6 +34,6 @@ export const useModal = create((set) => ({ type: null, isOpen: false, data: {}, - onOpen: (type, data?: ModalData) => set({ type, isOpen: true, data }), - onClose: () => set({ type: null, isOpen: false }), -})); + onOpen: (type, data = {}) => set({ isOpen: true, type, data }), + onClose: () => set({ type: null, isOpen: false, data: {} }), +})); \ No newline at end of file