From 1a48dad58e231a1d78c7084d0e4ac6cc45e221d6 Mon Sep 17 00:00:00 2001 From: Jacob Cox Date: Mon, 26 Aug 2024 19:52:15 -0700 Subject: [PATCH 01/23] forked weather app --- app/layout.js | 3 +- app/page.js | 95 ---------------------------------- app/page.tsx | 9 ++++ package-lock.json | 129 ++++++++++++++++++++++++++++++++++++++++++++-- package.json | 7 +++ tsconfig.json | 34 ++++++++++++ 6 files changed, 176 insertions(+), 101 deletions(-) delete mode 100644 app/page.js create mode 100644 app/page.tsx create mode 100644 tsconfig.json diff --git a/app/layout.js b/app/layout.js index c93f806..d2a84c1 100644 --- a/app/layout.js +++ b/app/layout.js @@ -1,10 +1,9 @@ -import './globals.css' import { Inter } from 'next/font/google' const inter = Inter({ subsets: ['latin'] }) export const metadata = { - title: 'Create Next App', + title: 'Weather App', description: 'Generated by create next app', } diff --git a/app/page.js b/app/page.js deleted file mode 100644 index f049c39..0000000 --- a/app/page.js +++ /dev/null @@ -1,95 +0,0 @@ -import Image from 'next/image' -import styles from './page.module.css' - -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/page.tsx b/app/page.tsx new file mode 100644 index 0000000..c62b0db --- /dev/null +++ b/app/page.tsx @@ -0,0 +1,9 @@ +import styles from "./page.module.css"; + +export default function App(): JSX.Element { + return ( +
+

Weather App

+
+ ); +} diff --git a/package-lock.json b/package-lock.json index 90f6bb1..5604ab1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,18 @@ "name": "parsity_rtk_weather", "version": "0.1.0", "dependencies": { + "@reduxjs/toolkit": "^2.2.7", + "bootstrap": "^5.3.3", "eslint": "8.50.0", "eslint-config-next": "13.5.3", "next": "13.5.3", "react": "18.2.0", "react-dom": "18.2.0" + }, + "devDependencies": { + "@types/node": "^22.5.0", + "@types/react": "^18.3.4", + "typescript": "^5.5.4" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -296,6 +303,39 @@ "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==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.7.tgz", + "integrity": "sha512-faI3cZbSdFb8yv9dhDTmGwclW0vk0z5o1cia+kf7gCbaCwHI5e+7tP57mJUv22pNcNbeA62GSrPpfrUfdXcQ6g==", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "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", @@ -314,6 +354,31 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/node": { + "version": "22.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", + "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", + "dev": true, + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.4.tgz", + "integrity": "sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, "node_modules/@typescript-eslint/parser": { "version": "6.7.3", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", @@ -647,6 +712,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", @@ -771,6 +854,12 @@ "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==", + "dev": true + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -1759,6 +1848,15 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "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 +2781,19 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "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 +2834,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==" + }, "node_modules/resolve": { "version": "1.22.6", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", @@ -3191,10 +3307,9 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "peer": true, + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3217,6 +3332,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/package.json b/package.json index 6ca0f8f..553b2e9 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,17 @@ "lint": "next lint" }, "dependencies": { + "@reduxjs/toolkit": "^2.2.7", + "bootstrap": "^5.3.3", "eslint": "8.50.0", "eslint-config-next": "13.5.3", "next": "13.5.3", "react": "18.2.0", "react-dom": "18.2.0" + }, + "devDependencies": { + "@types/node": "^22.5.0", + "@types/react": "^18.3.4", + "typescript": "^5.5.4" } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..14bd9ea --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "noEmit": true, + "incremental": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "plugins": [ + { + "name": "next" + } + ] + }, + "include": [ + "next-env.d.ts", + ".next/types/**/*.ts", + "**/*.ts", + "**/*.tsx" + ], + "exclude": [ + "node_modules" + ] +} From caa06aa7df6f0a51a4ace4ca366b4bbdd8556a1e Mon Sep 17 00:00:00 2001 From: Jacob Cox Date: Mon, 26 Aug 2024 21:43:45 -0700 Subject: [PATCH 02/23] added bare components and store --- app/components/addCity.tsx | 0 app/components/searchBar.tsx | 7 ++++++ app/layout.js | 13 +++++----- app/page.tsx | 2 ++ app/store/configureStore.tsx | 8 +++++++ app/store/rootReducer.tsx | 7 ++++++ app/store/slices/location.tsx | 0 package-lock.json | 45 +++++++++++++++++++++++++++++++---- package.json | 4 +++- 9 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 app/components/addCity.tsx create mode 100644 app/components/searchBar.tsx create mode 100644 app/store/configureStore.tsx create mode 100644 app/store/rootReducer.tsx create mode 100644 app/store/slices/location.tsx diff --git a/app/components/addCity.tsx b/app/components/addCity.tsx new file mode 100644 index 0000000..e69de29 diff --git a/app/components/searchBar.tsx b/app/components/searchBar.tsx new file mode 100644 index 0000000..9d8cc31 --- /dev/null +++ b/app/components/searchBar.tsx @@ -0,0 +1,7 @@ +interface SearchBarProps { + placeholder: string; +} + +const SearchBar = ({ placeholder }: SearchBarProps): JSX.Element => { + return ; +}; diff --git a/app/layout.js b/app/layout.js index d2a84c1..43605c9 100644 --- a/app/layout.js +++ b/app/layout.js @@ -1,16 +1,17 @@ -import { Inter } from 'next/font/google' +'use client' +import { Inter } from 'next/font/google'; +import { Provider } from 'react-redux'; +import store from './store/configureStore'; const inter = Inter({ subsets: ['latin'] }) -export const metadata = { - title: 'Weather App', - description: 'Generated by create next app', -} export default function RootLayout({ children }) { return ( - {children} + + {children} + ) } diff --git a/app/page.tsx b/app/page.tsx index c62b0db..a4db014 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,9 +1,11 @@ import styles from "./page.module.css"; +import { SearchBar } from "./components/searchBar"; export default function App(): JSX.Element { return (

Weather App

+
); } diff --git a/app/store/configureStore.tsx b/app/store/configureStore.tsx new file mode 100644 index 0000000..9afb8ce --- /dev/null +++ b/app/store/configureStore.tsx @@ -0,0 +1,8 @@ +import { configureStore } from "@reduxjs/toolkit"; +import rootReducer from "./rootReducer"; + +const store = configureStore({ + reducer: rootReducer, +}); + +export default store; diff --git a/app/store/rootReducer.tsx b/app/store/rootReducer.tsx new file mode 100644 index 0000000..856344f --- /dev/null +++ b/app/store/rootReducer.tsx @@ -0,0 +1,7 @@ +import { combineReducers } from "redux"; + +const rootReducer = combineReducers({ + // location: locationReducer, //haven't created reducers yet +}); + +export default rootReducer; diff --git a/app/store/slices/location.tsx b/app/store/slices/location.tsx new file mode 100644 index 0000000..e69de29 diff --git a/package-lock.json b/package-lock.json index 5604ab1..48915d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,9 @@ "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-redux": "^9.1.2", + "redux": "^5.0.1" }, "devDependencies": { "@types/node": "^22.5.0", @@ -367,18 +369,23 @@ "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true + "devOptional": true }, "node_modules/@types/react": { "version": "18.3.4", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.4.tgz", "integrity": "sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==", - "dev": true, + "devOptional": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@typescript-eslint/parser": { "version": "6.7.3", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.3.tgz", @@ -858,7 +865,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "devOptional": true }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -2781,6 +2788,28 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-redux": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", + "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", + "dependencies": { + "@types/use-sync-external-store": "^0.0.3", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25", + "react": "^18.0", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, "node_modules/redux": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", @@ -3346,6 +3375,14 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.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 553b2e9..e655b23 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,9 @@ "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-redux": "^9.1.2", + "redux": "^5.0.1" }, "devDependencies": { "@types/node": "^22.5.0", From 0d586f2a914065c9376ae8054658bc54241ec781 Mon Sep 17 00:00:00 2001 From: Jacob Cox Date: Tue, 27 Aug 2024 09:25:53 -0700 Subject: [PATCH 03/23] added search bar component --- .../{addCity.tsx => locationCard.tsx} | 0 app/components/searchBar.tsx | 30 +++++++++++++++++-- app/layout.js | 7 +++-- app/page.tsx | 9 ++++-- app/store/configureStore.tsx | 8 ----- app/store/rootReducer.tsx | 7 ----- app/store/slices/location.tsx | 0 style.css | 4 +++ 8 files changed, 42 insertions(+), 23 deletions(-) rename app/components/{addCity.tsx => locationCard.tsx} (100%) delete mode 100644 app/store/configureStore.tsx delete mode 100644 app/store/rootReducer.tsx delete mode 100644 app/store/slices/location.tsx create mode 100644 style.css diff --git a/app/components/addCity.tsx b/app/components/locationCard.tsx similarity index 100% rename from app/components/addCity.tsx rename to app/components/locationCard.tsx diff --git a/app/components/searchBar.tsx b/app/components/searchBar.tsx index 9d8cc31..00e3d70 100644 --- a/app/components/searchBar.tsx +++ b/app/components/searchBar.tsx @@ -1,7 +1,33 @@ +"use client"; +import { useState } from "react"; interface SearchBarProps { placeholder: string; + onSearch: (query: string) => void; } -const SearchBar = ({ placeholder }: SearchBarProps): JSX.Element => { - return ; +const SearchBar = ({ placeholder, onSearch }: SearchBarProps): JSX.Element => { + const [query, setQuery] = useState(""); + + const handleChange = (e: React.ChangeEvent): void => { + setQuery(e.target.value); + }; + + const handleSubmit = (e: React.FormEvent): void => { + e.preventDefault(); + }; + + return ( +
+
+ + +
+
+ ); }; + +export default SearchBar; diff --git a/app/layout.js b/app/layout.js index 43605c9..a136af2 100644 --- a/app/layout.js +++ b/app/layout.js @@ -1,7 +1,7 @@ 'use client' import { Inter } from 'next/font/google'; -import { Provider } from 'react-redux'; -import store from './store/configureStore'; +// import { Provider } from 'react-redux'; +// import store from './store/configureStore'; const inter = Inter({ subsets: ['latin'] }) @@ -10,7 +10,8 @@ export default function RootLayout({ children }) { return ( - {children} + {children} + {/* {children} */} ) diff --git a/app/page.tsx b/app/page.tsx index a4db014..bea2ee9 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,11 +1,14 @@ import styles from "./page.module.css"; -import { SearchBar } from "./components/searchBar"; +import SearchBar from "./components/searchBar"; export default function App(): JSX.Element { return (
-

Weather App

- +
+

Weather App

+
+ +
); } diff --git a/app/store/configureStore.tsx b/app/store/configureStore.tsx deleted file mode 100644 index 9afb8ce..0000000 --- a/app/store/configureStore.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { configureStore } from "@reduxjs/toolkit"; -import rootReducer from "./rootReducer"; - -const store = configureStore({ - reducer: rootReducer, -}); - -export default store; diff --git a/app/store/rootReducer.tsx b/app/store/rootReducer.tsx deleted file mode 100644 index 856344f..0000000 --- a/app/store/rootReducer.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { combineReducers } from "redux"; - -const rootReducer = combineReducers({ - // location: locationReducer, //haven't created reducers yet -}); - -export default rootReducer; diff --git a/app/store/slices/location.tsx b/app/store/slices/location.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/style.css b/style.css new file mode 100644 index 0000000..89b6f36 --- /dev/null +++ b/style.css @@ -0,0 +1,4 @@ +btn { + width: 100px; + height: 50px; +} From 151749157df7d2d05dbd8544ad3b6ca626082c27 Mon Sep 17 00:00:00 2001 From: Jacob Cox Date: Wed, 28 Aug 2024 15:57:31 -0700 Subject: [PATCH 04/23] added comments in searchBar component --- app/components/searchBar.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/components/searchBar.tsx b/app/components/searchBar.tsx index 00e3d70..0a0c1a8 100644 --- a/app/components/searchBar.tsx +++ b/app/components/searchBar.tsx @@ -4,14 +4,16 @@ interface SearchBarProps { placeholder: string; onSearch: (query: string) => void; } - +//onSearch will be passed onto another component that fetches the API request const SearchBar = ({ placeholder, onSearch }: SearchBarProps): JSX.Element => { const [query, setQuery] = useState(""); + //sets the query to what is being searched const handleChange = (e: React.ChangeEvent): void => { setQuery(e.target.value); }; + //prevents running default requests when submitted const handleSubmit = (e: React.FormEvent): void => { e.preventDefault(); }; From f81a723aa8d916366de3c2a61cf1257590efd42a Mon Sep 17 00:00:00 2001 From: Jacob Cox Date: Wed, 28 Aug 2024 22:53:34 -0700 Subject: [PATCH 05/23] building reducers and api requests --- app/components/searchBar.tsx | 16 ++-- app/components/searchResults.tsx | 12 +++ app/globals.css | 6 +- app/page.module.css | 19 +++- app/page.tsx | 4 +- app/store/configureStore.tsx | 8 ++ app/store/rootReducer.tsx | 9 ++ app/store/slices/location.tsx | 21 +++++ .../slices/weather.tsx} | 0 package-lock.json | 91 +++++++++++++++++++ package.json | 1 + style.css | 4 - 12 files changed, 174 insertions(+), 17 deletions(-) create mode 100644 app/components/searchResults.tsx create mode 100644 app/store/configureStore.tsx create mode 100644 app/store/rootReducer.tsx create mode 100644 app/store/slices/location.tsx rename app/{components/locationCard.tsx => store/slices/weather.tsx} (100%) delete mode 100644 style.css diff --git a/app/components/searchBar.tsx b/app/components/searchBar.tsx index 0a0c1a8..0245e2b 100644 --- a/app/components/searchBar.tsx +++ b/app/components/searchBar.tsx @@ -1,4 +1,5 @@ "use client"; +import styles from "../page.module.css"; import { useState } from "react"; interface SearchBarProps { placeholder: string; @@ -8,14 +9,10 @@ interface SearchBarProps { const SearchBar = ({ placeholder, onSearch }: SearchBarProps): JSX.Element => { const [query, setQuery] = useState(""); - //sets the query to what is being searched - const handleChange = (e: React.ChangeEvent): void => { - setQuery(e.target.value); - }; - //prevents running default requests when submitted const handleSubmit = (e: React.FormEvent): void => { e.preventDefault(); + onSearch(query); }; return ( @@ -24,9 +21,14 @@ const SearchBar = ({ placeholder, onSearch }: SearchBarProps): JSX.Element => { ): void => { + setQuery(e.target.value); + onSearch(e.target.value); + }} /> - + ); diff --git a/app/components/searchResults.tsx b/app/components/searchResults.tsx new file mode 100644 index 0000000..a68dfb0 --- /dev/null +++ b/app/components/searchResults.tsx @@ -0,0 +1,12 @@ +"use client"; +import styles from "../page.module.css"; +import { useState } from "react"; +import SearchBar from "../components/searchBar"; + +const SearchResults = () => { + const [results, setResults] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); +}; + +export default SearchResults; diff --git a/app/globals.css b/app/globals.css index d4f491e..f4bd77c 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,9 +1,9 @@ :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; + --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; diff --git a/app/page.module.css b/app/page.module.css index 6676d2c..ad2ff56 100644 --- a/app/page.module.css +++ b/app/page.module.css @@ -1,3 +1,16 @@ +.button { + height: auto; + width: auto; + background-color: blue; + color: white; + border-radius: 5px; + margin: 10px; +} + +.button:hover { + background-color: lightblue; +} + .main { display: flex; flex-direction: column; @@ -51,7 +64,9 @@ border-radius: var(--border-radius); background: rgba(var(--card-rgb), 0); border: 1px solid rgba(var(--card-border-rgb), 0); - transition: background 200ms, border 200ms; + transition: + background 200ms, + border 200ms; } .card span { @@ -97,7 +112,7 @@ .center::before, .center::after { - content: ''; + content: ""; left: 50%; position: absolute; filter: blur(45px); diff --git a/app/page.tsx b/app/page.tsx index bea2ee9..42d37cf 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,5 +1,7 @@ +"use client"; import styles from "./page.module.css"; import SearchBar from "./components/searchBar"; +import fetchLocation from "./store/slices/location"; export default function App(): JSX.Element { return ( @@ -7,7 +9,7 @@ export default function App(): JSX.Element {

Weather App


- +
); diff --git a/app/store/configureStore.tsx b/app/store/configureStore.tsx new file mode 100644 index 0000000..8c6b168 --- /dev/null +++ b/app/store/configureStore.tsx @@ -0,0 +1,8 @@ +import { configureStore } from "@reduxjs/toolkit"; +import rootReducer from "../store/rootReducer"; + +const store = configureStore({ + reducer: rootReducer, +}); + +export default store; diff --git a/app/store/rootReducer.tsx b/app/store/rootReducer.tsx new file mode 100644 index 0000000..1078d54 --- /dev/null +++ b/app/store/rootReducer.tsx @@ -0,0 +1,9 @@ +import { combineReducers } from "redux"; +import locationReducer from "./slices/location"; + +const rootReducer = combineReducers({ + location: locationReducer, + // weather: weatherReducer +}); + +export default rootReducer; diff --git a/app/store/slices/location.tsx b/app/store/slices/location.tsx new file mode 100644 index 0000000..2221756 --- /dev/null +++ b/app/store/slices/location.tsx @@ -0,0 +1,21 @@ +import axios from "axios"; +import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; +import SearchBar from "/Users/jacobcox/Code/rtk-weather/app/components/searchBar"; + +const fetchLocation = createAsyncThunk( + "location/fetchLocation", + async (query) => { + const API_KEY: string = process.env.NEXT_PUBLIC_WEATHER_API_KEY; + const API: string = `http://api.openweathermap.org/geo/1.0/direct?q=${query}appid=${API_KEY}`; + const response = await axios.get(API); + + console.log(response.data); + return response.data; + } +); + +//create reducer for data to be put in store +//create second slice for weather api fetch +//figure out why response.data above isn't console logging (possibly query isn't returning) + +export default fetchLocation; diff --git a/app/components/locationCard.tsx b/app/store/slices/weather.tsx similarity index 100% rename from app/components/locationCard.tsx rename to app/store/slices/weather.tsx diff --git a/package-lock.json b/package-lock.json index 48915d2..6e7123f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "@reduxjs/toolkit": "^2.2.7", + "axios": "^1.7.5", "bootstrap": "^5.3.3", "eslint": "8.50.0", "eslint-config-next": "13.5.3", @@ -687,6 +688,11 @@ "has-symbols": "^1.0.3" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -706,6 +712,16 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz", + "integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", @@ -843,6 +859,17 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -922,6 +949,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -1587,6 +1622,25 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -1595,6 +1649,19 @@ "is-callable": "^1.1.3" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2375,6 +2442,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2733,6 +2819,11 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", diff --git a/package.json b/package.json index e655b23..14c52f0 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@reduxjs/toolkit": "^2.2.7", + "axios": "^1.7.5", "bootstrap": "^5.3.3", "eslint": "8.50.0", "eslint-config-next": "13.5.3", diff --git a/style.css b/style.css deleted file mode 100644 index 89b6f36..0000000 --- a/style.css +++ /dev/null @@ -1,4 +0,0 @@ -btn { - width: 100px; - height: 50px; -} From 5c80aef2ac02a7938bae71fbb153534f2bd2fb3a Mon Sep 17 00:00:00 2001 From: Jacob Cox Date: Fri, 30 Aug 2024 21:50:57 -0700 Subject: [PATCH 06/23] working out api requests --- app/components/searchBar.tsx | 17 +++++----- app/layout.js | 7 ++-- app/page.js | 31 ++++++++++++++++++ app/page.tsx | 16 --------- app/store/configureStore.tsx | 1 + app/store/rootReducer.tsx | 7 ++-- app/store/slices/location.tsx | 21 ------------ app/store/slices/locations.tsx | 60 ++++++++++++++++++++++++++++++++++ app/store/slices/search.tsx | 24 ++++++++++++++ tsconfig.json | 16 ++++----- 10 files changed, 139 insertions(+), 61 deletions(-) create mode 100644 app/page.js delete mode 100644 app/page.tsx delete mode 100644 app/store/slices/location.tsx create mode 100644 app/store/slices/locations.tsx create mode 100644 app/store/slices/search.tsx diff --git a/app/components/searchBar.tsx b/app/components/searchBar.tsx index 0245e2b..5b59c2f 100644 --- a/app/components/searchBar.tsx +++ b/app/components/searchBar.tsx @@ -1,18 +1,20 @@ "use client"; import styles from "../page.module.css"; import { useState } from "react"; +import { useDispatch } from "react-redux"; +import { setSearchQuery } from "../store/slices/search"; + interface SearchBarProps { placeholder: string; - onSearch: (query: string) => void; } -//onSearch will be passed onto another component that fetches the API request -const SearchBar = ({ placeholder, onSearch }: SearchBarProps): JSX.Element => { - const [query, setQuery] = useState(""); - //prevents running default requests when submitted +const SearchBar = ({ placeholder }: SearchBarProps): JSX.Element => { + const dispatch = useDispatch(); //allows store to listen to events + const [query, setQuery] = useState(""); //allows query to be set as state + const handleSubmit = (e: React.FormEvent): void => { - e.preventDefault(); - onSearch(query); + e.preventDefault(); //prevents running default requests when submitted + dispatch(setSearchQuery(query)); //assigns the query to store via slice when searched }; return ( @@ -23,7 +25,6 @@ const SearchBar = ({ placeholder, onSearch }: SearchBarProps): JSX.Element => { value={query} onChange={(e: React.ChangeEvent): void => { setQuery(e.target.value); - onSearch(e.target.value); }} />