diff --git a/react-typescript/src/components/App.tsx b/react-typescript/src/components/App.tsx
index 50c89f89..bef2a923 100644
--- a/react-typescript/src/components/App.tsx
+++ b/react-typescript/src/components/App.tsx
@@ -1,10 +1,13 @@
+import useDayLoader from '../hooks/useDayLoader';
import './App.css';
-import Items from './Item';
+import Items from './Items';
function App() {
+ const { loadNextDay } = useDayLoader();
return (
+
);
}
diff --git a/react-typescript/src/components/Item.tsx b/react-typescript/src/components/Items.tsx
similarity index 66%
rename from react-typescript/src/components/Item.tsx
rename to react-typescript/src/components/Items.tsx
index 448c1862..b0bfd4cc 100644
--- a/react-typescript/src/components/Item.tsx
+++ b/react-typescript/src/components/Items.tsx
@@ -1,15 +1,15 @@
-import useItem from "../hooks/useItem";
+import useAllItems from "../hooks/useAllItems";
import { TItem } from "../types"
function Items() {
- const { items, updateItem } = useItem();
+ const { items } = useAllItems();
return (
{items.map((item: TItem) => {
return (
-
- Name: {item.name} Quality: {item.quality} SellIn: {item.sellIn}
+ Name: {item.name} Quality: {item.quality} SellIn: {item.sellIn}
);
})}
diff --git a/react-typescript/src/components/StoreProvider.tsx b/react-typescript/src/components/StoreProvider.tsx
new file mode 100644
index 00000000..5e4fba42
--- /dev/null
+++ b/react-typescript/src/components/StoreProvider.tsx
@@ -0,0 +1,20 @@
+import { useReducer } from "react";
+import initialState from "../model/initialState";
+import reducer from "../model/reducer";
+import StoreContext from "../model/storeContext";
+
+type TProps = {
+ children: JSX.Element;
+}
+
+function StoreProvider({ children }: TProps): JSX.Element {
+ const [state, dispatch] = useReducer(reducer, initialState);
+
+ return (
+
+ { children }
+
+ );
+}
+
+export default StoreProvider;
\ No newline at end of file
diff --git a/react-typescript/src/hooks/useAllItems.ts b/react-typescript/src/hooks/useAllItems.ts
new file mode 100644
index 00000000..733f59ec
--- /dev/null
+++ b/react-typescript/src/hooks/useAllItems.ts
@@ -0,0 +1,8 @@
+import { useStore } from "../model";
+
+function useAllItems() {
+ const { state } = useStore();
+ return { items: state.items };
+}
+
+export default useAllItems;
\ No newline at end of file
diff --git a/react-typescript/src/hooks/useDayLoader.ts b/react-typescript/src/hooks/useDayLoader.ts
new file mode 100644
index 00000000..12ec9620
--- /dev/null
+++ b/react-typescript/src/hooks/useDayLoader.ts
@@ -0,0 +1,12 @@
+import { useStore } from "../model";
+import {EActionTypes} from "../types";
+
+function useDayLoader() {
+ const { dispatch } = useStore();
+ const loadNextDay = () => {
+ dispatch({ type: EActionTypes.NEXT_DAY });
+ };
+ return { loadNextDay };
+}
+
+export default useDayLoader;
\ No newline at end of file
diff --git a/react-typescript/src/hooks/useItem.ts b/react-typescript/src/hooks/useItem.ts
index fe76dbe1..0a7007ad 100644
--- a/react-typescript/src/hooks/useItem.ts
+++ b/react-typescript/src/hooks/useItem.ts
@@ -1,22 +1,10 @@
import { useStore } from "../model";
-import EEvents from "../model/EEvents";
-import { TItem } from "../types"
-
-function useItem() {
- const { state, dispatch } = useStore();
-
- return {
- items: state,
-
- updateItem: (item: TItem):void => {
- dispatch({
- type: EEvents.NEXT_DAY,
- payload: {
- name: item.name
- }
- });
- }
- };
+import {TItem} from "../types";
+
+function useItem(item: TItem): TItem {
+ const { state } = useStore();
+ const itemFound = state.items.find(target => target.name.toLowerCase().includes(item.name.toLowerCase()));
+ return itemFound === undefined ? item : itemFound;
}
export default useItem;
\ No newline at end of file
diff --git a/react-typescript/src/index.tsx b/react-typescript/src/index.tsx
index 024fa737..c8fe2e6a 100644
--- a/react-typescript/src/index.tsx
+++ b/react-typescript/src/index.tsx
@@ -2,12 +2,15 @@ import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './components/App';
+import StoreProvider from './components/StoreProvider';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
-
+
+
+
);
diff --git a/react-typescript/src/model/EEvents.ts b/react-typescript/src/model/EEvents.ts
deleted file mode 100644
index 65bf67ef..00000000
--- a/react-typescript/src/model/EEvents.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-const enum EEvents {
- NEXT_DAY = 'NEXT_DAY',
-}
-
-export default EEvents;
\ No newline at end of file
diff --git a/react-typescript/src/model/reducer/calculateQuality.ts b/react-typescript/src/model/reducer/calculateQuality.ts
deleted file mode 100644
index 25938e3c..00000000
--- a/react-typescript/src/model/reducer/calculateQuality.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { TItem } from "../../types"
-
-function calculateQuality(state: TItem): number {
- const sellInAmount = state.sellIn;
-
- let calculatedQuality = state.quality;
- let degradeRate = 1;
- let qualityIdentifier = 1;
-
- if(state.name.includes("Sulfuras")) {
- return 80;
- }
-
- if(state.name.includes("Aged Brie")) {
- qualityIdentifier = -1;
- }
-
- if(state.name.includes("Backstage passes")) {
- qualityIdentifier = -1;
- if(sellInAmount <= 10 && sellInAmount > 6) {
- degradeRate = 2;
- }
- if(sellInAmount <= 6 && sellInAmount > 0) {
- degradeRate = 3;
- }
- if(sellInAmount <= 0) {
- return 0;
- }
- }
-
- if(state.isConjured || state.sellIn < 0) {
- degradeRate = 2;
- }
-
- calculatedQuality = calculatedQuality - (qualityIdentifier * degradeRate);
-
- if(calculatedQuality > 50) {
- return 50;
- }
-
- if(calculatedQuality < 0) {
- return 0;
- }
-
- return calculatedQuality;
-}
-
-export default calculateQuality;
\ No newline at end of file
diff --git a/react-typescript/src/model/reducer/calculateSellIn.ts b/react-typescript/src/model/reducer/calculateSellIn.ts
deleted file mode 100644
index 97c739b6..00000000
--- a/react-typescript/src/model/reducer/calculateSellIn.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-function updateSellIn (state: any): number {
- let calculatedSellIn = state.sellIn;
-
- if(state.name.includes("Sulfuras")) {
- return calculatedSellIn;
- }
-
- return calculatedSellIn - 1;
-}
-
-export default updateSellIn;
\ No newline at end of file
diff --git a/react-typescript/src/model/reducer/getItemOnNextDay.ts b/react-typescript/src/model/reducer/getItemOnNextDay.ts
new file mode 100644
index 00000000..e7235331
--- /dev/null
+++ b/react-typescript/src/model/reducer/getItemOnNextDay.ts
@@ -0,0 +1,11 @@
+import { TItem } from '../../types';
+import updateQuality from './updateQuality';
+import updateSellIn from './updateSellIn';
+
+function getItemOnNextDay(item: TItem): TItem {
+ const itemWithUpdatedSellIn = updateSellIn(item);
+ const itemWithUpdatedQuality = updateQuality(itemWithUpdatedSellIn);
+ return itemWithUpdatedQuality;
+}
+
+export default getItemOnNextDay;
\ No newline at end of file
diff --git a/react-typescript/src/model/reducer/index.ts b/react-typescript/src/model/reducer/index.ts
index 84b75cea..10536654 100644
--- a/react-typescript/src/model/reducer/index.ts
+++ b/react-typescript/src/model/reducer/index.ts
@@ -1,26 +1,9 @@
-import { TItem } from '../../types';
-import EEvents from '../EEvents';
-import calculateQuality from '././calculateQuality';
-import calculateSellIn from '././calculateSellIn';
+import { TState, TAction, EActionTypes } from '../../types';
+import getItemOnNextDay from './getItemOnNextDay';
-function updateQuality(item: TItem): TItem {
- const calculatedQuality = calculateQuality(item);
- return { ...item, quality: calculatedQuality };
-}
-
-function updateSellIn(item: TItem): TItem {
- const calculatedSellIn = calculateSellIn(item);
- return { ...item, sellIn: calculatedSellIn };
-}
-
-function reducer(state: TItem[], action: any): TItem[] {
- if(action.type === EEvents.NEXT_DAY) {
- return state.map(item => {
- if(item.name.includes(action.payload.name)) {
- return updateQuality(updateSellIn(item));
- }
- return item;
- });
+function reducer(state: TState, action: TAction): TState {
+ if(action.type === EActionTypes.NEXT_DAY) {
+ return { ...state, items: state.items.map(getItemOnNextDay) };
}
return state;
}
diff --git a/react-typescript/src/model/reducer/updateQuality.ts b/react-typescript/src/model/reducer/updateQuality.ts
new file mode 100644
index 00000000..a5ba5ebf
--- /dev/null
+++ b/react-typescript/src/model/reducer/updateQuality.ts
@@ -0,0 +1,42 @@
+import { TItem } from "../../types"
+import clamp from "../../utils/clamp";
+
+function updateQuality(item: TItem): TItem {
+ const sellInAmount = item.sellIn;
+
+ let calculatedQuality = item.quality;
+ let degradeRate = 1;
+ let qualityIdentifier = 1;
+
+ if(item.name.toLowerCase().includes('sulfuras')) {
+ return { ...item, quality: 80 };
+ }
+
+ if(item.name.toLowerCase().includes('aged brie')) {
+ qualityIdentifier = -1;
+ }
+
+ if(item.name.toLowerCase().includes('backstage passes')) {
+ qualityIdentifier = -1;
+ if(sellInAmount <= 10 && sellInAmount > 6) {
+ degradeRate = 2;
+ }
+ if(sellInAmount <= 6 && sellInAmount > 0) {
+ degradeRate = 3;
+ }
+ if(sellInAmount <= 0) {
+ return { ...item, quality: 0 };
+ }
+ }
+
+ if(item.isConjured || item.sellIn < 0) {
+ degradeRate = 2;
+ }
+
+ calculatedQuality = calculatedQuality - (qualityIdentifier * degradeRate);
+ calculatedQuality = clamp(calculatedQuality, 0, 50);
+
+ return { ...item, quality: calculatedQuality };
+}
+
+export default updateQuality;
\ No newline at end of file
diff --git a/react-typescript/src/model/reducer/updateSellIn.ts b/react-typescript/src/model/reducer/updateSellIn.ts
new file mode 100644
index 00000000..d958ecd3
--- /dev/null
+++ b/react-typescript/src/model/reducer/updateSellIn.ts
@@ -0,0 +1,13 @@
+import { TItem } from '../../types';
+
+function updateSellIn (state: TItem): TItem {
+ let calculatedSellIn = state.sellIn;
+
+ if(state.name.toLowerCase().includes('sulfuras')) {
+ return {...state, sellIn: calculatedSellIn};
+ }
+
+ return { ...state, sellIn: calculatedSellIn - 1 };
+}
+
+export default updateSellIn;
\ No newline at end of file
diff --git a/react-typescript/src/model/storeContext.ts b/react-typescript/src/model/storeContext.ts
new file mode 100644
index 00000000..cc48f286
--- /dev/null
+++ b/react-typescript/src/model/storeContext.ts
@@ -0,0 +1,10 @@
+import { createContext } from "react";
+import { TContext } from "../types";
+import initialState from "./initialState";
+
+const StoreContext = createContext({
+ state: initialState,
+ dispatch: () => {},
+})
+
+export default StoreContext;
\ No newline at end of file
diff --git a/react-typescript/src/model/useStore.ts b/react-typescript/src/model/useStore.ts
index 03f36535..b009d6c4 100644
--- a/react-typescript/src/model/useStore.ts
+++ b/react-typescript/src/model/useStore.ts
@@ -1,12 +1,6 @@
-import { useReducer } from "react";
-import initialState from "./initialState";
-import reducer from "./reducer";
+import { useContext } from "react";
+import StoreContext from "./storeContext";
export default function useStore() {
- const [state, dispatch] = useReducer(reducer, initialState.items);
-
- return {
- state,
- dispatch
- }
+ return useContext(StoreContext);
}
\ No newline at end of file
diff --git a/react-typescript/src/qualityCalculator.ts b/react-typescript/src/qualityCalculator.ts
deleted file mode 100644
index 96e1242f..00000000
--- a/react-typescript/src/qualityCalculator.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-const qualityCalculator = (item: any) => {
- return 1;
-}
-
-export default qualityCalculator;
\ No newline at end of file
diff --git a/react-typescript/src/types/index.ts b/react-typescript/src/types/index.ts
index 11261b68..6ec8bcbc 100644
--- a/react-typescript/src/types/index.ts
+++ b/react-typescript/src/types/index.ts
@@ -5,11 +5,27 @@ type TItem = {
isConjured: boolean
}
-type TGildedRose = {
+type TState = {
items: TItem[]
+};
+
+type TAction = {
+ type: EActionTypes,
+ payload?: any
+}
+
+type TContext = {
+ state: TState,
+ dispatch: (action: TAction) => void
+}
+
+export enum EActionTypes {
+ NEXT_DAY = 'NEXT_DAY',
}
export type {
TItem,
- TGildedRose
-}
\ No newline at end of file
+ TState,
+ TAction,
+ TContext
+};
diff --git a/react-typescript/src/utils/clamp.ts b/react-typescript/src/utils/clamp.ts
new file mode 100644
index 00000000..6f19b929
--- /dev/null
+++ b/react-typescript/src/utils/clamp.ts
@@ -0,0 +1,5 @@
+function clamp(number: number, min: number, max: number): number {
+ return Math.min(Math.max(number, min), max);
+}
+
+export default clamp;
\ No newline at end of file