Skip to content

Commit 9f052a5

Browse files
adminadmin
authored andcommitted
fix useLocalStorage
1 parent 850e96f commit 9f052a5

34 files changed

+598
-1044
lines changed

rmtdev/final-code/package-lock.json

Lines changed: 142 additions & 147 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rmtdev/final-code/package.json

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,22 @@
1010
"preview": "vite preview"
1111
},
1212
"dependencies": {
13-
"@radix-ui/react-icons": "^1.3.0",
14-
"@tanstack/react-query": "^4.36.1",
15-
"react": "^18.2.0",
16-
"react-dom": "^18.2.0",
17-
"react-hot-toast": "^2.4.1"
13+
"@radix-ui/react-icons": "1.3.0",
14+
"@tanstack/react-query": "4.36.1",
15+
"react": "18.2.0",
16+
"react-dom": "18.2.0",
17+
"react-hot-toast": "2.4.1"
1818
},
1919
"devDependencies": {
20-
"@types/react": "^18.2.15",
21-
"@types/react-dom": "^18.2.7",
22-
"@typescript-eslint/eslint-plugin": "^6.0.0",
23-
"@typescript-eslint/parser": "^6.0.0",
24-
"@vitejs/plugin-react": "^4.0.3",
25-
"eslint": "^8.45.0",
26-
"eslint-plugin-react-hooks": "^4.6.0",
27-
"eslint-plugin-react-refresh": "^0.4.3",
28-
"typescript": "^5.0.2",
29-
"vite": "^4.4.5"
20+
"@types/react": "18.2.15",
21+
"@types/react-dom": "18.2.7",
22+
"@typescript-eslint/eslint-plugin": "6.0.0",
23+
"@typescript-eslint/parser": "6.0.0",
24+
"@vitejs/plugin-react": "4.0.3",
25+
"eslint": "8.45.0",
26+
"eslint-plugin-react-hooks": "4.6.0",
27+
"eslint-plugin-react-refresh": "0.4.3",
28+
"typescript": "5.0.2",
29+
"vite": "4.4.5"
3030
}
3131
}

rmtdev/final-code/src/components/App-Before-Context.tsx

Lines changed: 0 additions & 102 deletions
This file was deleted.

rmtdev/final-code/src/components/App.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ import Background from "./Background";
22
import Container from "./Container";
33
import Footer from "./Footer";
44
import Header, { HeaderTop } from "./Header";
5-
import Sidebar, { SidebarTop } from "./Sidebar";
6-
import { Toaster } from "react-hot-toast";
7-
import ResultsCount from "./ResultsCount";
8-
import Sorting from "./SortingControls";
9-
import Pagination from "./PaginationControls";
10-
import JobItemContent from "./JobItemContent";
5+
import BookmarksButton from "./BookmarksButton";
116
import Logo from "./Logo";
12-
import Bookmarks from "./BookmarksButton";
13-
import JobListSearch from "./JobList/JobListSearch";
147
import SearchForm from "./SearchForm";
8+
import JobItemContent from "./JobItemContent";
9+
import Sidebar, { SidebarTop } from "./Sidebar";
10+
import PaginationControls from "./PaginationControls";
11+
import ResultsCount from "./ResultsCount";
12+
import SortingControls from "./SortingControls";
13+
import { Toaster } from "react-hot-toast";
14+
import JobListSearch from "./JobListSearch";
1515

1616
function App() {
1717
return (
@@ -21,7 +21,7 @@ function App() {
2121
<Header>
2222
<HeaderTop>
2323
<Logo />
24-
<Bookmarks />
24+
<BookmarksButton />
2525
</HeaderTop>
2626

2727
<SearchForm />
@@ -31,12 +31,12 @@ function App() {
3131
<Sidebar>
3232
<SidebarTop>
3333
<ResultsCount />
34-
<Sorting />
34+
<SortingControls />
3535
</SidebarTop>
3636

3737
<JobListSearch />
3838

39-
<Pagination />
39+
<PaginationControls />
4040
</Sidebar>
4141

4242
<JobItemContent />

rmtdev/final-code/src/components/BookmarkIcon.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
import { BookmarkFilledIcon } from "@radix-ui/react-icons";
2-
import { JobItemId } from "../lib/types";
3-
import { useBookmarksContext } from "../contexts/BookmarksContextProvider";
2+
import { useBookmarksContext } from "../lib/hooks";
43

54
type BookmarkIconProps = {
6-
jobItemId: JobItemId;
5+
id: number;
76
};
87

9-
export default function BookmarkIcon({ jobItemId }: BookmarkIconProps) {
10-
const { bookmarkedJobItemIds, handleToggleBookmark } = useBookmarksContext();
8+
export default function BookmarkIcon({ id }: BookmarkIconProps) {
9+
const { bookmarkedIds, handleToggleBookmark } = useBookmarksContext();
1110

1211
return (
1312
<button
1413
onClick={(e) => {
15-
handleToggleBookmark(jobItemId);
14+
handleToggleBookmark(id);
1615
e.stopPropagation();
1716
e.preventDefault();
1817
}}
1918
className="bookmark-btn"
2019
>
2120
<BookmarkFilledIcon
22-
className={`${
23-
bookmarkedJobItemIds.some((id) => id === jobItemId) ? "filled" : ""
24-
}`}
21+
className={`
22+
${bookmarkedIds.includes(id) ? "filled" : ""}
23+
`}
2524
/>
2625
</button>
2726
);

rmtdev/final-code/src/components/BookmarksButton.tsx

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,19 @@
1-
import { useState, useEffect, useRef } from "react";
21
import { TriangleDownIcon } from "@radix-ui/react-icons";
32
import BookmarksPopover from "./BookmarksPopover";
3+
import { useRef, useState } from "react";
44
import { useOnClickOutside } from "../lib/hooks";
55

6-
export default function Bookmarks() {
7-
// also called local state
6+
export default function BookmarksButton() {
87
const [isOpen, setIsOpen] = useState(false);
98
const buttonRef = useRef<HTMLButtonElement>(null);
109
const popoverRef = useRef<HTMLDivElement>(null);
11-
12-
// hooks for common use cases are available (show google results)
13-
14-
// detect click outside of the bookmarks list with own solution, without ref
15-
// useEffect(() => {
16-
// function handleClick(event: MouseEvent) {
17-
// const target = event.target as HTMLElement;
18-
// if (
19-
// !target.closest(".bookmarks-popover") &&
20-
// !target.closest(".bookmarks-btn")
21-
// ) {
22-
// setIsOpen(false);
23-
// }
24-
// }
25-
26-
// document.addEventListener("click", handleClick);
27-
28-
// return () => document.removeEventListener("click", handleClick);
29-
// }, []);
30-
31-
// detect click outside of the bookmarks list with own solution, with ref
32-
// useEffect(() => {
33-
// function handleClick(event: MouseEvent) {
34-
// const target = event.target as HTMLElement;
35-
// if (
36-
// // use ref to check if the click is inside the popover
37-
// !popoverRef.current?.contains(target) &&
38-
// // use ref to check if the click is inside the button
39-
// !buttonRef.current?.contains(target)
40-
// ) {
41-
// setIsOpen(false);
42-
// }
43-
// }
44-
45-
// document.addEventListener("click", handleClick);
46-
47-
// return () => document.removeEventListener("click", handleClick);
48-
// }, []);
49-
50-
// use hook
5110
useOnClickOutside([buttonRef, popoverRef], () => setIsOpen(false));
5211

5312
return (
5413
<section>
5514
<button
5615
ref={buttonRef}
57-
onClick={() => setIsOpen(!isOpen)}
16+
onClick={() => setIsOpen((prev) => !prev)}
5817
className="bookmarks-btn"
5918
>
6019
Bookmarks <TriangleDownIcon />

rmtdev/final-code/src/components/BookmarksPopover.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
// use portal so that the bookmarks list is not affected by the z-index of the header
2-
import { createPortal } from "react-dom";
3-
import JobListBookmarks from "./JobList/JobListBookmarks";
41
import { forwardRef } from "react";
2+
import { useBookmarksContext } from "../lib/hooks";
3+
import JobList from "./JobList";
4+
import { createPortal } from "react-dom";
5+
6+
const BookmarksPopover = forwardRef<HTMLDivElement>(function (_, ref) {
7+
const { bookmarkedJobItems, isLoading } = useBookmarksContext();
58

6-
const BookmarksPopover = forwardRef<
7-
HTMLDivElement,
8-
React.HTMLAttributes<HTMLDivElement>
9-
>(function (_, ref) {
109
return createPortal(
1110
<div ref={ref} className="bookmarks-popover">
12-
<JobListBookmarks />
11+
<JobList jobItems={bookmarkedJobItems} isLoading={isLoading} />
1312
</div>,
1413
document.body
1514
);
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
type ContainerProps = {
2-
children: React.ReactNode;
3-
};
4-
5-
export default function Container({ children }: ContainerProps) {
1+
export default function Container({ children }: { children: React.ReactNode }) {
62
return <div className="container">{children}</div>;
73
}
Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
import Bookmarks from "./BookmarksButton";
2-
import Logo from "./Logo";
3-
4-
export default function Header({ children }) {
1+
export default function Header({ children }: { children: React.ReactNode }) {
52
return <header className="header">{children}</header>;
63
}
74

8-
export function HeaderTop({ children }) {
5+
export function HeaderTop({ children }: { children: React.ReactNode }) {
96
return <div className="header__top">{children}</div>;
107
}

0 commit comments

Comments
 (0)