Skip to content

Commit e949d5d

Browse files
committed
Add CSS and Contact component
1 parent 8f6b975 commit e949d5d

File tree

4 files changed

+548
-48
lines changed

4 files changed

+548
-48
lines changed

package-lock.json

Lines changed: 110 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@
1010
"preview": "vite preview"
1111
},
1212
"dependencies": {
13+
"localforage": "^1.10.0",
14+
"match-sorter": "^6.3.1",
1315
"react": "^18.2.0",
14-
"react-dom": "^18.2.0"
16+
"react-dom": "^18.2.0",
17+
"react-router-dom": "^6.21.0",
18+
"sort-by": "^1.2.0"
1519
},
1620
"devDependencies": {
1721
"@types/react": "^18.2.43",

src/Contact.jsx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import localforage from "localforage";
2+
import { matchSorter } from "match-sorter";
3+
import sortBy from "sort-by";
4+
5+
export async function getContacts(query) {
6+
await fakeNetwork(`getContacts:${query}`);
7+
let contacts = await localforage.getItem("contacts");
8+
if (!contacts) contacts = [];
9+
if (query) {
10+
contacts = matchSorter(contacts, query, { keys: ["first", "last"] });
11+
}
12+
return contacts.sort(sortBy("last", "createdAt"));
13+
}
14+
15+
export async function createContact() {
16+
await fakeNetwork();
17+
let id = Math.random().toString(36).substring(2, 9);
18+
let contact = { id, createdAt: Date.now() };
19+
let contacts = await getContacts();
20+
contacts.unshift(contact);
21+
await set(contacts);
22+
return contact;
23+
}
24+
25+
export async function getContact(id) {
26+
await fakeNetwork(`contact:${id}`);
27+
let contacts = await localforage.getItem("contacts");
28+
let contact = contacts.find(contact => contact.id === id);
29+
return contact ?? null;
30+
}
31+
32+
export async function updateContact(id, updates) {
33+
await fakeNetwork();
34+
let contacts = await localforage.getItem("contacts");
35+
let contact = contacts.find(contact => contact.id === id);
36+
if (!contact) throw new Error("No contact found for", id);
37+
Object.assign(contact, updates);
38+
await set(contacts);
39+
return contact;
40+
}
41+
42+
export async function deleteContact(id) {
43+
let contacts = await localforage.getItem("contacts");
44+
let index = contacts.findIndex(contact => contact.id === id);
45+
if (index > -1) {
46+
contacts.splice(index, 1);
47+
await set(contacts);
48+
return true;
49+
}
50+
return false;
51+
}
52+
53+
function set(contacts) {
54+
return localforage.setItem("contacts", contacts);
55+
}
56+
57+
// fake a cache so we don't slow down stuff we've already seen
58+
let fakeCache = {};
59+
60+
async function fakeNetwork(key) {
61+
if (!key) {
62+
fakeCache = {};
63+
}
64+
65+
if (fakeCache[key]) {
66+
return;
67+
}
68+
69+
fakeCache[key] = true;
70+
return new Promise(res => {
71+
setTimeout(res, Math.random() * 800);
72+
});
73+
}

0 commit comments

Comments
 (0)