Skip to content

Commit

Permalink
chore(contacts): edit contact
Browse files Browse the repository at this point in the history
  • Loading branch information
antonstjernquist committed Sep 20, 2024
1 parent deaaf72 commit 2446b26
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 36 deletions.
36 changes: 36 additions & 0 deletions src/ui/src/Apps/Calls/Contacts/Contact/Edit/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useContacts } from '@/api/hooks/useContacts';
import { EditContactForm } from '@/components/Contacts/EditContactForm';
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer';
import { useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';

export const EditContactView = () => {
const navigate = useNavigate();

const handleBack = () => {
navigate(-1);
};

const { contactId } = useParams<{ contactId: string }>();
const [contacts, , isLoading] = useContacts();
console.log({ contacts, isLoading });
const contact = contacts.find((contact) => contact.id === parseInt(contactId ?? '', 10));

useEffect(() => {
if (!contact && !isLoading) {
handleBack();
}
}, [contact, handleBack, isLoading]);

return (
<Drawer modal open onClose={handleBack}>
<DrawerContent>
<DrawerHeader>
<DrawerTitle className="text-primary">Update contact</DrawerTitle>
</DrawerHeader>

<EditContactForm onContactUpdated={handleBack} contact={contact} />
</DrawerContent>
</Drawer>
);
};
34 changes: 16 additions & 18 deletions src/ui/src/Apps/Calls/Contacts/Contact/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import { useParams } from 'react-router';
// import { contacts } from '..';
import { Outlet, useParams } from 'react-router';
import { Link } from 'react-router-dom';
import { TopNavigation } from '../../../../components/Navigation/TopNavigation';
import { useContacts } from '@/api/hooks/useContacts';
import { Button } from '@/components/ui/button';

export const ContactView = () => {
const { contactId } = useParams<{ contactId: string }>();

if (!contactId) {
return null;
}
const contact = {
name: 'John Doe',
phoneNumbers: ['123-456-7890'],
};
const [contacts] = useContacts();
const contact = contacts.find((contact) => contact.id === parseInt(contactId ?? '', 10));

if (!contact) {
return null;
Expand All @@ -24,22 +19,25 @@ export const ContactView = () => {
title={contact.name}
left={
<Link to=".." relative="path">
Back
<Button variant="ghost">Back</Button>
</Link>
}
right={
<Link to={`edit`} relative="path">
<Button variant="ghost">Edit</Button>
</Link>
}
/>

<section className="p-4 flex flex-col gap-2">
<div className="bg-secondary p-4">
<ul className="list-disc list-inside">
{contact.phoneNumbers.map((phoneNumber) => (
<Link key={phoneNumber} to={`/apps/calls/call/${phoneNumber}`}>
<li>{phoneNumber}</li>
</Link>
))}
</ul>
<Link to={`/apps/calls/call/${contact.phone_number}`}>
<ul className="list-disc list-inside">{contact.phone_number}</ul>
</Link>
</div>
</section>

<Outlet />
</main>
);
};
2 changes: 1 addition & 1 deletion src/ui/src/Apps/Calls/Contacts/New/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const NewContactView = () => {
<Drawer modal open onClose={handleBack}>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Create a new contact</DrawerTitle>
<DrawerTitle className="text-primary">Create a new contact</DrawerTitle>
</DrawerHeader>

<NewContactForm onContactCreated={handleBack} />
Expand Down
10 changes: 7 additions & 3 deletions src/ui/src/Apps/Calls/Contacts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Link, Outlet, useSearchParams } from 'react-router-dom';
import { TopNavigation } from '../../../components/Navigation/TopNavigation';
import { useCurrentDevice } from '../../../api/hooks/useCurrentDevice';
import { useContacts } from '../../../api/hooks/useContacts';
import { Button } from '@/components/ui/button';

export const ContactsView = () => {
const device = useCurrentDevice();
Expand All @@ -16,7 +17,7 @@ export const ContactsView = () => {
title="Contacts"
right={
<Link to="/apps/calls/contacts/new">
<button>New</button>
<Button variant="ghost">New</Button>
</Link>
}
/>
Expand All @@ -36,10 +37,13 @@ export const ContactsView = () => {
to={
referal
? `${referal}?data=${encodeURIComponent(JSON.stringify(contact))}`
: `/apps/calls/call/${contact.phone_number}`
: `/apps/calls/contacts/${contact.id}`
}
>
<li className="text-xl font-bold rounded-lg bg-secondary">{contact.name}</li>
<li className="rounded-lg bg-secondary flex flex-col">
<span className="text-xl font-bold ">{contact.name}</span>
<span className="text-sm text-secondary">{contact.phone_number}</span>
</li>
</Link>
))}
</ul>
Expand Down
6 changes: 6 additions & 0 deletions src/ui/src/api/contacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ export const createContact = async (name: string, phoneNumber: string) => {
.post<{ payload: Contact }>('/contacts/add', { name, phoneNumber })
.then((res) => res.data);
};

export const updateContact = async (contact: Contact) => {
return await instance
.post<{ payload: Contact }>(`/contacts/${contact.id}/edit`, contact)
.then((res) => res.data);
};
79 changes: 79 additions & 0 deletions src/ui/src/components/Contacts/EditContactForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { updateContact } from '@/api/contacts';
import { queryClient } from '@/Providers';
import { Contact } from '../../../../shared/Types';
import { useState } from 'react';
import { handleClientError } from '@/utils/errors';
import { Button } from '../ui/button';
import { Input } from '../Input';

interface NewContactFormProps {
contact?: Contact;
onContactUpdated: () => void;
}

export const EditContactForm = ({ onContactUpdated, contact }: NewContactFormProps) => {
const [error, setError] = useState<string | null>(null);

const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();

const form = event.currentTarget;
const formData = new FormData(form);
const name = formData.get('name') as string;
const phoneNumber = formData.get('phone_number') as string;

if (!name || !phoneNumber || !contact) {
return;
}

try {
const { payload } = await updateContact({
...contact,
name,
phone_number: phoneNumber,
});

onContactUpdated();

/**
* Update the cache with the new contact.
*/
queryClient.setQueryData(['contacts'], (contacts: { payload: Contact[] }) => {
return {
...contacts,
payload: contacts.payload.map((contact) => {
if (contact.phone_number === phoneNumber) {
return payload;
}

return contact;
}),
};
});
} catch (error) {
console.log(error);
setError(handleClientError(error));
}
};

if (!contact) {
return null;
}

return (
<form
className="flex flex-col gap-2 p-4"
onSubmit={handleSubmit}
onFocus={() => setError(null)}
>
<Input name="name" placeholder="Name" defaultValue={contact.name} />
<Input name="phone_number" placeholder="Phone number" defaultValue={contact.phone_number} />

{error && <div className="text-red-500">{error}</div>}

<Button type="submit" variant="outline" className="text-primary">
Update contact
</Button>
</form>
);
};
19 changes: 5 additions & 14 deletions src/ui/src/components/Contacts/NewContactForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Contact } from '../../../../shared/Types';
import { useState } from 'react';
import { handleClientError } from '@/utils/errors';
import { Button } from '../ui/button';
import { Input } from '../Input';

interface NewContactFormProps {
onContactCreated: () => void;
Expand Down Expand Up @@ -44,26 +45,16 @@ export const NewContactForm = ({ onContactCreated }: NewContactFormProps) => {

return (
<form
className="flex flex-col gap-2 p-4 "
className="flex flex-col gap-2 p-4"
onSubmit={handleSubmit}
onFocus={() => setError(null)}
>
<input
name="name"
type="text"
placeholder="Name"
className="bg-secondary px-4 py-2 rounded-sm"
/>
<input
name="phone_number"
type="text"
placeholder="Phone number"
className="bg-secondary px-4 py-2 rounded-sm"
/>
<Input name="name" placeholder="Name" />
<Input name="phone_number" placeholder="Phone number" />

{error && <div className="text-red-500">{error}</div>}

<Button type="submit" variant="outline">
<Button type="submit" variant="outline" className="text-primary">
Create
</Button>
</form>
Expand Down
8 changes: 8 additions & 0 deletions src/ui/src/components/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { InputHTMLAttributes } from 'react';

interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
isDisabled?: boolean;
}
export const Input = (props: InputProps) => {
return <input className="bg-secondary px-4 py-2 rounded-sm text-primary" {...props} />;
};
7 changes: 7 additions & 0 deletions src/ui/src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { MessagesApp } from './Apps/Calls/Messages';
import { Conversation } from './Apps/Calls/Messages/Conversation';
import { NewContactView } from './Apps/Calls/Contacts/New';
import { NotFound } from './views/NotFound';
import { EditContactView } from './Apps/Calls/Contacts/Contact/Edit';

export const routes = [
{
Expand Down Expand Up @@ -54,6 +55,12 @@ export const routes = [
{
path: 'contacts/:contactId',
element: <ContactView />,
children: [
{
path: 'edit',
element: <EditContactView />,
},
],
},
{
path: 'latest',
Expand Down

0 comments on commit 2446b26

Please sign in to comment.