From 8809855e28296964dc1679e80e6bf5ac48f3dc92 Mon Sep 17 00:00:00 2001 From: wesleyfrankel Date: Wed, 13 Mar 2024 12:57:20 -0700 Subject: [PATCH 1/2] Initial commit --- .eslintrc.json | 2 +- .gitignore | 1 + app/components/CityList.js | 46 +++++++++++++++++ app/components/CitySearch.js | 33 +++++++++++++ app/layout.js | 29 ++++++----- app/page.js | 95 +++--------------------------------- app/store/configureStore.js | 8 +++ app/store/rootReducer.js | 8 +++ app/store/slices/city.js | 59 ++++++++++++++++++++++ package-lock.json | 66 ++++++++++++++++++++++++- package.json | 4 +- 11 files changed, 244 insertions(+), 107 deletions(-) create mode 100644 app/components/CityList.js create mode 100644 app/components/CitySearch.js create mode 100644 app/store/configureStore.js create mode 100644 app/store/rootReducer.js create mode 100644 app/store/slices/city.js diff --git a/.eslintrc.json b/.eslintrc.json index bffb357..a2ceebe 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,3 @@ { - "extends": "next/core-web-vitals" + "extends": ["next/babel", "next/core-web-vitals"] } diff --git a/.gitignore b/.gitignore index 8f322f0..45c1abc 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ yarn-error.log* # local env files .env*.local +.env # vercel .vercel diff --git a/app/components/CityList.js b/app/components/CityList.js new file mode 100644 index 0000000..0787860 --- /dev/null +++ b/app/components/CityList.js @@ -0,0 +1,46 @@ +'use client'; +import { useSelector } from 'react-redux'; +import { Sparklines, SparklinesLine } from 'react-sparklines'; + + +const CityList = () => { + const cities = useSelector((state) => state.city.city) + return ( + + + + + + + + + + + + {cities.map((city) => { + return( + + + + + + + )})} + +
CityTemperaturePressureHumidity
{city.name} + + + + + + + + + + + +
+ ); +}; + +export default CityList; \ No newline at end of file diff --git a/app/components/CitySearch.js b/app/components/CitySearch.js new file mode 100644 index 0000000..ad084a9 --- /dev/null +++ b/app/components/CitySearch.js @@ -0,0 +1,33 @@ +'use client'; +import { useDispatch } from 'react-redux'; +import { addNewCity, fetchData } from '../store/slices/city'; + + + +const CitySearch = () => { + const dispatch = useDispatch(); + + const handleSubmit = async(event) => { + event.preventDefault(); + await dispatch(fetchData(event.target.city.value)); + } + + return ( +
+
+ + +
+
+ ); +}; + +export default CitySearch; \ No newline at end of file diff --git a/app/layout.js b/app/layout.js index c93f806..2001c0a 100644 --- a/app/layout.js +++ b/app/layout.js @@ -1,17 +1,16 @@ -import './globals.css' -import { Inter } from 'next/font/google' - -const inter = Inter({ subsets: ['latin'] }) - -export const metadata = { - title: 'Create Next App', - description: 'Generated by create next app', -} +'use client'; +import './globals.css'; +import { Inter } from 'next/font/google'; +import { Provider } from 'react-redux'; +import store from './store/configureStore'; +const inter = Inter({ subsets: ['latin'] }); export default function RootLayout({ children }) { - return ( - - {children} - - ) -} + return ( + + + {children} + + + ); +} \ No newline at end of file diff --git a/app/page.js b/app/page.js index f049c39..140aeb8 100644 --- a/app/page.js +++ b/app/page.js @@ -1,95 +1,12 @@ -import Image from 'next/image' import styles from './page.module.css' +import CityList from './components/CityList' +import CitySearch from './components/CitySearch' export default function Home() { return ( -
-
-

- Get started by editing  - app/page.js -

-
- - By{' '} - Vercel Logo - -
-
- -
- Next.js Logo -
- -
- -

- Docs -> -

-

Find in-depth information about Next.js features and API.

-
- - -

- Learn -> -

-

Learn about Next.js in an interactive course with quizzes!

-
- - -

- Templates -> -

-

Explore the Next.js 13 playground.

-
- - -

- Deploy -> -

-

- Instantly deploy your Next.js site to a shareable URL with Vercel. -

-
-
-
+ <> + + + ) } diff --git a/app/store/configureStore.js b/app/store/configureStore.js new file mode 100644 index 0000000..bfdd016 --- /dev/null +++ b/app/store/configureStore.js @@ -0,0 +1,8 @@ +import { configureStore } from '@reduxjs/toolkit'; +import rootReducer from './rootReducer'; + +const store = configureStore({ + reducer: rootReducer +}); + +export default store; \ No newline at end of file diff --git a/app/store/rootReducer.js b/app/store/rootReducer.js new file mode 100644 index 0000000..af6646f --- /dev/null +++ b/app/store/rootReducer.js @@ -0,0 +1,8 @@ +import { combineReducers } from 'redux'; +import cityReducer from './slices/city'; + +const rootReducer = combineReducers({ + city: cityReducer, +}); + +export default rootReducer; \ No newline at end of file diff --git a/app/store/slices/city.js b/app/store/slices/city.js new file mode 100644 index 0000000..c5b2113 --- /dev/null +++ b/app/store/slices/city.js @@ -0,0 +1,59 @@ +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; + + + +export const fetchData = createAsyncThunk( + 'city/get', + async(cityName) => { + let url = 'https://api.openweathermap.org/data/2.5/forecast?q=' + cityName + '&appid=75f4785546ba2c0a068da88d46e4db01' + const response = await fetch(url, { + method: 'GET', + dataType: 'json' + }); + const data = await response.json(); + return data + } +) + +export const citySlice = createSlice({ + name: 'city', + initialState: { + city: [], + }, + reducers: { + + }, + extraReducers: (builder) => { + builder.addCase(fetchData.fulfilled, (state, action) => { + const data = action.payload; + const pressure = []; + const humidity = []; + const temperature = []; + let cityName = data.city.name; + for(let i = 0; i < data.list.length; i++){ + let curr = data.list[i] + + const temp = Math.floor((curr.main.temp - 273.15) * 9/5 + 32); + temperature.push(temp); + pressure.push(curr.main.pressure); + humidity.push(curr.main.humidity); + + }; + const cityData = { + cityName, + temperature, + pressure, + humidity + }; + + state.city.unshift(cityData); + + + + }) + } +}); + +export const { addNewCity } = citySlice.actions; + +export default citySlice.reducer; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 90f6bb1..da6287f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,13 @@ "name": "parsity_rtk_weather", "version": "0.1.0", "dependencies": { + "@reduxjs/toolkit": "^2.2.1", "eslint": "8.50.0", "eslint-config-next": "13.5.3", "next": "13.5.3", "react": "18.2.0", - "react-dom": "18.2.0" + "react-dom": "18.2.0", + "react-sparklines": "^1.7.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -296,6 +298,29 @@ "node": ">= 8" } }, + "node_modules/@reduxjs/toolkit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.1.tgz", + "integrity": "sha512-8CREoqJovQW/5I4yvvijm/emUiCCmcs4Ev4XPWd4mizSO+dD3g5G6w34QK5AGeNrSH7qM8Fl66j4vuV7dpOdkw==", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.0.1" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.5.0.tgz", @@ -1759,6 +1784,15 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.4.tgz", + "integrity": "sha512-cuBuGK40P/sk5IzWa9QPUaAdvPHjkk1c+xYsd9oZw+YQQEV+10G0P5uMpGctZZKnyQ+ibRO08bD25nWLmYi2pw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -2683,6 +2717,31 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-sparklines": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/react-sparklines/-/react-sparklines-1.7.0.tgz", + "integrity": "sha512-bJFt9K4c5Z0k44G8KtxIhbG+iyxrKjBZhdW6afP+R7EnIq+iKjbWbEFISrf3WKNFsda+C46XAfnX0StS5fbDcg==", + "dependencies": { + "prop-types": "^15.5.10" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "peerDependencies": { + "redux": "^5.0.0" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", @@ -2723,6 +2782,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/reselect": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.0.tgz", + "integrity": "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg==" + }, "node_modules/resolve": { "version": "1.22.6", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", diff --git a/package.json b/package.json index 6ca0f8f..d8421b5 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,12 @@ "lint": "next lint" }, "dependencies": { + "@reduxjs/toolkit": "^2.2.1", "eslint": "8.50.0", "eslint-config-next": "13.5.3", "next": "13.5.3", "react": "18.2.0", - "react-dom": "18.2.0" + "react-dom": "18.2.0", + "react-sparklines": "^1.7.0" } } From 87e3545def50e67627578927bdd9bd1e19a1499e Mon Sep 17 00:00:00 2001 From: wesleyfrankel Date: Thu, 14 Mar 2024 11:15:15 -0700 Subject: [PATCH 2/2] Added styling and weather data beneath the graphs --- app/components/CityList.js | 13 +- app/components/CitySearch.js | 8 +- app/globals.css | 106 +---------------- app/layout.js | 1 + app/page.module.css | 2 +- app/store/slices/city.js | 4 +- app/style.css | 9 ++ package-lock.json | 225 +++++++++++++++++++++++++++++++++++ package.json | 2 + 9 files changed, 259 insertions(+), 111 deletions(-) create mode 100644 app/style.css diff --git a/app/components/CityList.js b/app/components/CityList.js index 0787860..b61d530 100644 --- a/app/components/CityList.js +++ b/app/components/CityList.js @@ -1,45 +1,52 @@ 'use client'; import { useSelector } from 'react-redux'; import { Sparklines, SparklinesLine } from 'react-sparklines'; +import '../style.css'; const CityList = () => { const cities = useSelector((state) => state.city.city) return ( + - +
- + {cities.map((city) => { return( - + )})}
City Temperature PressureHumidityHumidityv
{city.name}{city.cityName} +

{city.temperature[0]} °F

+ +

{city.pressure[0]} hPa

+

{city.humidity[0]}%

+ ); }; diff --git a/app/components/CitySearch.js b/app/components/CitySearch.js index ad084a9..a61a361 100644 --- a/app/components/CitySearch.js +++ b/app/components/CitySearch.js @@ -1,6 +1,6 @@ 'use client'; import { useDispatch } from 'react-redux'; -import { addNewCity, fetchData } from '../store/slices/city'; +import { fetchData } from '../store/slices/city'; @@ -13,6 +13,8 @@ const CitySearch = () => { } return ( + <> +

Weather Data

{ id="search-city" type="text" placeholder="Enter City" + style={{marginTop: "60px"}} /> -
+ ); }; diff --git a/app/globals.css b/app/globals.css index d4f491e..86d06f6 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,107 +1,7 @@ :root { --max-width: 1100px; --border-radius: 12px; - --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', - 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', - 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace; - - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; - - --primary-glow: conic-gradient( - from 180deg at 50% 50%, - #16abff33 0deg, - #0885ff33 55deg, - #54d6ff33 120deg, - #0071ff33 160deg, - transparent 360deg - ); - --secondary-glow: radial-gradient( - rgba(255, 255, 255, 1), - rgba(255, 255, 255, 0) - ); - - --tile-start-rgb: 239, 245, 249; - --tile-end-rgb: 228, 232, 233; - --tile-border: conic-gradient( - #00000080, - #00000040, - #00000030, - #00000020, - #00000010, - #00000010, - #00000080 - ); - - --callout-rgb: 238, 240, 241; - --callout-border-rgb: 172, 175, 176; - --card-rgb: 180, 185, 188; - --card-border-rgb: 131, 134, 135; -} - -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - - --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); - --secondary-glow: linear-gradient( - to bottom right, - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0.3) - ); - - --tile-start-rgb: 2, 13, 46; - --tile-end-rgb: 2, 5, 19; - --tile-border: conic-gradient( - #ffffff80, - #ffffff40, - #ffffff30, - #ffffff20, - #ffffff10, - #ffffff10, - #ffffff80 - ); - - --callout-rgb: 20, 20, 20; - --callout-border-rgb: 108, 108, 108; - --card-rgb: 100, 100, 100; - --card-border-rgb: 200, 200, 200; - } -} - -* { - box-sizing: border-box; - padding: 0; - margin: 0; -} - -html, -body { - max-width: 100vw; - overflow-x: hidden; -} - -body { - color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); -} - -a { - color: inherit; - text-decoration: none; -} - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } + --font-mono: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono", + "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro", + "Fira Mono", "Droid Sans Mono", "Courier New", monospace; } diff --git a/app/layout.js b/app/layout.js index 2001c0a..534187d 100644 --- a/app/layout.js +++ b/app/layout.js @@ -2,6 +2,7 @@ import './globals.css'; import { Inter } from 'next/font/google'; import { Provider } from 'react-redux'; +import 'bootstrap/dist/css/bootstrap.min.css'; import store from './store/configureStore'; const inter = Inter({ subsets: ['latin'] }); diff --git a/app/page.module.css b/app/page.module.css index 6676d2c..eee920e 100644 --- a/app/page.module.css +++ b/app/page.module.css @@ -97,7 +97,7 @@ .center::before, .center::after { - content: ''; + content: ""; left: 50%; position: absolute; filter: blur(45px); diff --git a/app/store/slices/city.js b/app/store/slices/city.js index c5b2113..c9d4b87 100644 --- a/app/store/slices/city.js +++ b/app/store/slices/city.js @@ -37,7 +37,7 @@ export const citySlice = createSlice({ temperature.push(temp); pressure.push(curr.main.pressure); humidity.push(curr.main.humidity); - + }; const cityData = { cityName, @@ -45,7 +45,7 @@ export const citySlice = createSlice({ pressure, humidity }; - + console.log(cityData.temperature[0]) state.city.unshift(cityData); diff --git a/app/style.css b/app/style.css new file mode 100644 index 0000000..a001845 --- /dev/null +++ b/app/style.css @@ -0,0 +1,9 @@ +.graph-data { + color: red; + text-align: center; + margin-top: "50px"; +} + +.city-table { + margin-top: "28px"; +} diff --git a/package-lock.json b/package-lock.json index da6287f..c138c2b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,12 @@ "version": "0.1.0", "dependencies": { "@reduxjs/toolkit": "^2.2.1", + "bootstrap": "^5.3.3", "eslint": "8.50.0", "eslint-config-next": "13.5.3", "next": "13.5.3", "react": "18.2.0", + "react-bootstrap": "^2.10.1", "react-dom": "18.2.0", "react-sparklines": "^1.7.0" } @@ -298,6 +300,29 @@ "node": ">= 8" } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.2.tgz", + "integrity": "sha512-0gKkgDYdnq1w+ey8KzG9l+H5Z821qh9vVjztk55rUg71vTk/Eaebeir+WtzcLLwTjw3m/asIjx8Y59y1lJZhBw==", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, "node_modules/@reduxjs/toolkit": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.1.tgz", @@ -321,6 +346,45 @@ } } }, + "node_modules/@restart/hooks": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", + "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@restart/ui": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", + "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@popperjs/core": "^2.11.6", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.4.9", + "@types/warning": "^3.0.0", + "dequal": "^2.0.3", + "dom-helpers": "^5.2.0", + "uncontrollable": "^8.0.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + } + }, + "node_modules/@restart/ui/node_modules/uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "peerDependencies": { + "react": ">=16.14.0" + } + }, "node_modules/@rushstack/eslint-patch": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.5.0.tgz", @@ -339,6 +403,39 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "node_modules/@types/react": { + "version": "18.2.66", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.66.tgz", + "integrity": "sha512-OYTmMI4UigXeFMF/j4uv0lBBEbongSgptPrHBxqME44h9+yNov+oL6Z3ocJKo0WyXR84sQUNeyIp9MRfckvZpg==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "node_modules/@types/warning": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" + }, "node_modules/@typescript-eslint/parser": { "version": "6.7.3", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", @@ -672,6 +769,24 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/bootstrap": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz", + "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -757,6 +872,11 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -796,6 +916,11 @@ "node": ">= 8" } }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -881,6 +1006,15 @@ "node": ">=6.0.0" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -1843,6 +1977,14 @@ "node": ">= 0.4" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -2662,6 +2804,18 @@ "react-is": "^16.13.1" } }, + "node_modules/prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "dependencies": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -2700,6 +2854,35 @@ "node": ">=0.10.0" } }, + "node_modules/react-bootstrap": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.1.tgz", + "integrity": "sha512-J3OpRZIvCTQK+Tg/jOkRUvpYLHMdGeU9KqFUBQrV0d/Qr/3nsINpiOJyZMWnM5SJ3ctZdhPA6eCIKpEJR3Ellg==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.6.6", + "@types/react-transition-group": "^4.4.6", + "classnames": "^2.3.2", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.8.1", + "prop-types-extra": "^1.1.0", + "react-transition-group": "^4.4.5", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "@types/react": ">=16.14.8", + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -2717,6 +2900,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, "node_modules/react-sparklines": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/react-sparklines/-/react-sparklines-1.7.0.tgz", @@ -2729,6 +2917,21 @@ "react-dom": "*" } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/redux": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", @@ -3281,6 +3484,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3289,6 +3506,14 @@ "punycode": "^2.1.0" } }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", diff --git a/package.json b/package.json index d8421b5..16658b8 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,12 @@ }, "dependencies": { "@reduxjs/toolkit": "^2.2.1", + "bootstrap": "^5.3.3", "eslint": "8.50.0", "eslint-config-next": "13.5.3", "next": "13.5.3", "react": "18.2.0", + "react-bootstrap": "^2.10.1", "react-dom": "18.2.0", "react-sparklines": "^1.7.0" }