Skip to content

Commit 1af8f81

Browse files
committed
client: context refactor
1 parent 0932904 commit 1af8f81

File tree

2 files changed

+83
-56
lines changed

2 files changed

+83
-56
lines changed

client/src/components/ui/RepositoryLink.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { useState, useEffect } from "react";
2-
import Button from "./Button";
1+
import axios from "axios";
2+
import { useEffect, useState } from "react";
33
import { BiGitRepoForked } from "react-icons/bi";
44
import { FaStar } from "react-icons/fa";
55
import { GithubResponse } from "../../types";
6-
import axios from "axios";
6+
import Button from "./Button";
77

88
type Props = {
99
user: string;
@@ -18,11 +18,11 @@ const RepositoryLink = ({ user, repository, isPublic }: Props) => {
1818
description: "This is a description",
1919
});
2020

21-
// useEffect(() => {
22-
// axios
23-
// .get<GithubResponse>(`https://api.github.com/repos/${user}/${repository}`)
24-
// .then((res) => setGithubStats(res.data));
25-
// }, []);
21+
useEffect(() => {
22+
axios
23+
.get<GithubResponse>(`https://api.github.com/repos/${user}/${repository}`)
24+
.then((res) => setGithubStats(res.data));
25+
}, []);
2626

2727
return (
2828
<div>

client/src/context/MultistepContext.tsx

Lines changed: 75 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { FC, ReactNode, createContext, useState, useCallback } from "react";
2-
import { useMultistepForm } from "../hooks/useMultistepForm";
3-
import PageOne from "../components/form/PageOne";
4-
import PageTwo from "../components/form/PageTwo";
5-
import PageThree from "../components/form/PageThree";
6-
import { Badge, BadgeDataTransfer, Card } from "../types";
7-
import PageFour from "../components/form/PageFour";
1+
import { FC, ReactNode, createContext, useCallback, useState } from "react";
82
import PageFive from "../components/form/PageFive";
3+
import PageFour from "../components/form/PageFour";
4+
import PageOne from "../components/form/PageOne";
95
import PageSix from "../components/form/PageSix";
6+
import PageThree from "../components/form/PageThree";
7+
import PageTwo from "../components/form/PageTwo";
108
import { INITIAL_CARD } from "../const";
9+
import { useMultistepForm } from "../hooks/useMultistepForm";
10+
import { Badge, BadgeDataTransfer, Card, Line } from "../types";
1111

1212
export interface MultistepContextType {
1313
isFirstPage: boolean;
@@ -22,9 +22,7 @@ export interface MultistepContextType {
2222
addBadge: (lineNumber: number, badge: Omit<Badge, "position">) => void;
2323
removeBadge: (lineNumber: number, position: number) => void;
2424
grabbedBadge: BadgeDataTransfer | undefined;
25-
setGrabbedBadge: React.Dispatch<
26-
React.SetStateAction<BadgeDataTransfer | undefined>
27-
>;
25+
setGrabbedBadge: (grabbedBadge: BadgeDataTransfer | undefined) => void;
2826
insertBadge: (
2927
lineNumber: number,
3028
position: number,
@@ -63,82 +61,111 @@ export const MultistepProvider: FC<MultistepProviderProps> = ({ children }) => {
6361
<PageSix />,
6462
]);
6563

64+
/**
65+
* Updates the card in a way that none of the card's parameters is required.
66+
*
67+
* @param {Partial<Card>} updated
68+
*/
6669
const updateCard = useCallback(
6770
(updated: Partial<Card>) => setCard((prev) => ({ ...prev, ...updated })),
6871
[]
6972
);
7073

71-
const addBadge = useCallback(
72-
(lineNumber: number, badge: Omit<Badge, "position">) => {
74+
/**
75+
* Updates a line with the specified lineNumber.
76+
* If the line with the lineNumber is not presented, it does nothing.
77+
*
78+
* @param {number} lineNumber
79+
* @param {(line: Line) => void} callback
80+
*/
81+
const updateLine = useCallback(
82+
(lineNumber: number, callback: (line: Line) => void) => {
7383
setCard((prev) => {
7484
// check whether the line exists
75-
const line = prev.lines.findIndex((x) => x.lineNumber === lineNumber);
76-
if (line === -1) return prev;
85+
const idx = prev.lines.findIndex((x) => x.lineNumber === lineNumber);
86+
if (idx === -1) return prev;
7787

7888
const newCard = structuredClone(prev);
79-
80-
// update the badges
81-
newCard.lines[line].badges = [
82-
...newCard.lines[line].badges,
83-
{ ...badge, position: newCard.lines[line].badges.length },
84-
];
89+
callback(newCard.lines[idx]);
8590

8691
return newCard;
8792
});
8893
},
8994
[]
9095
);
9196

92-
const removeBadge = useCallback((lineNumber: number, position: number) => {
93-
setCard((prev) => {
94-
// check whether the line exists
95-
const line = prev.lines.findIndex((x) => x.lineNumber === lineNumber);
96-
if (line === -1) return prev;
97+
/**
98+
* Pushes a badge to the end of a line.
99+
* You should pass the badge without the position property.
100+
*
101+
* @param {number} lineNumber
102+
* @param {Omit<Badge, "position">} badge
103+
*/
104+
const addBadge = useCallback(
105+
(lineNumber: number, badge: Omit<Badge, "position">) => {
106+
updateLine(lineNumber, (line) => {
107+
const { badges } = line;
108+
badges.push({ position: badges.length, ...badge });
109+
});
110+
},
111+
[updateLine]
112+
);
97113

98-
const newCard = structuredClone(prev);
114+
/**
115+
* Removes a badge in the specified line at the specified position.
116+
*
117+
* @param {number} lineNumber
118+
* @param {number} position
119+
*/
120+
const removeBadge = useCallback(
121+
(lineNumber: number, position: number) => {
122+
updateLine(lineNumber, (line) => {
123+
const { badges } = line;
99124

100-
// remove the badge and rearrange the positions
101-
newCard.lines[line].badges = newCard.lines[line].badges
102-
.sort((a, z) => a.position - z.position)
103-
.filter((x) => x.position !== position)
104-
.map((prev, i) => ({ ...prev, position: i }));
125+
// remove the old badge
126+
const idx = badges.map((x) => x.position).indexOf(position);
127+
if (idx !== -1) badges.splice(idx, 1);
105128

106-
return newCard;
107-
});
108-
}, []);
129+
// rearrange the positions
130+
badges.forEach((badge, i) => (badge.position = i));
131+
});
132+
},
133+
[updateLine]
134+
);
109135

136+
/**
137+
* Inserts a new badge in the specified line at a specified position.
138+
* This function also removes the old badge from the array.
139+
*
140+
* @param {number} lineNumber
141+
* @param {number} position
142+
* @param {BadgeDataTransfer} bdt
143+
*/
110144
const insertBadge = useCallback(
111145
(lineNumber: number, position: number, bdt: BadgeDataTransfer) => {
112146
// If the grabbed badge is in the left side of the new position,
113147
// we need to decrement the position by one,
114148
// because we grabbed (technically removed) one from the new position's left side.
115149
if (position > bdt.badge.position) position--;
116150

117-
setCard((prev) => {
118-
// check whether the line exists
119-
const line = prev.lines.findIndex((x) => x.lineNumber === lineNumber);
120-
if (line === -1) return prev;
121-
122-
const newCard = structuredClone(prev);
123-
const badges = newCard.lines[line].badges;
124-
const badgePositions = badges.map((badge) => badge.position);
151+
updateLine(lineNumber, (line) => {
152+
const { badges } = line;
125153

126154
// remove the old badge
127-
const idx = badgePositions.indexOf(bdt.badge.position);
155+
const idx = badges.map((x) => x.position).indexOf(bdt.badge.position);
128156
if (idx !== -1) badges.splice(idx, 1);
129157

130158
// insert the new badge
131159
badges.splice(position, 0, bdt.badge);
132-
133-
// rearrange the positions
134160
badges.forEach((badge, i) => (badge.position = i));
135-
136-
return newCard;
137161
});
138162
},
139-
[]
163+
[updateLine]
140164
);
141165

166+
/**
167+
* Resets the card by setting it to it's initial state.
168+
*/
142169
const resetCard = useCallback(() => {
143170
goToPageFirst();
144171
setCard(structuredClone(INITIAL_CARD));

0 commit comments

Comments
 (0)