diff --git a/client/src/assets/styles/search.scss b/client/src/assets/styles/search.scss new file mode 100644 index 0000000..a24eee1 --- /dev/null +++ b/client/src/assets/styles/search.scss @@ -0,0 +1,75 @@ +.search-sort-container { + width: 100%; + display: grid; + grid-auto-flow: column; + justify-content: start; +} + +.search-container { + +} + +.search-input { + display: block; + width: 400px; + margin-top: 10px; + margin-left: 10px; + padding: 10px 50px 10px 20px; + font-size: 14px; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + color: gray; + border-radius: 50px; + border: 1px solid gray; +} + +.sort-button { + display: grid; + padding: 12px 15px; + margin: 10px; + border-radius: 50px; + border: 1px solid gray; + color: var(--primary-600); + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + font-size: 12px; + font-weight: bolder; +} + +.sort-list { + padding: 5px; + padding-right: 30px; + background-color: white; + border: 1px solid gray; + border-radius: 5px; + font-size: 12px; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + :hover { + color: #ffa630; + cursor: pointer; + } +} + +.active { + color: #ffa630; +} + +.search { + position: relative; + + button { + position: absolute; + top:0px; + right:5px; + width: 40px; + height: 100%; + cursor: pointer; + background-color: transparent; + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z'/%3E%3Cpath d='M0 0h24v24H0z' fill='none'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: center; + border-radius: 20px; + border: 0; + } +} \ No newline at end of file diff --git a/client/src/components/Search.jsx b/client/src/components/Search.jsx new file mode 100644 index 0000000..0e1bedd --- /dev/null +++ b/client/src/components/Search.jsx @@ -0,0 +1,38 @@ +import { useState } from 'react'; +import '../assets/styles/search.scss'; +import { useAppContext } from '../context/appContext'; + +const Search = (props) => { + const [search, setSearch] = useState({ + value: '' + }); + + const { getSubscriptions } = useAppContext(); + + const handleSubmit = () => { + event.preventDefault(); + getSubscriptions({type: props.type, sort: null, search: search.value}) + }; + const handleChange = event => { + setSearch({value: event.target.value}); + }; + + return ( +
+
+ + +
+
+ ); +}; + +export default Search; diff --git a/client/src/components/Sort.jsx b/client/src/components/Sort.jsx new file mode 100644 index 0000000..02b0e08 --- /dev/null +++ b/client/src/components/Sort.jsx @@ -0,0 +1,69 @@ +import { useState } from 'react'; +import { useAppContext } from '../context/appContext'; +import '../assets/styles/search.scss'; + +const Sort = (props) => { + //Initialize the sort button's open state to false + //Otherwise, the dropdown will be open upon initial render + const [sortStatus, setSortStatus] = useState({ + isOpen: false, + activeSortOpt: '', + }); + + const { activeSortOpt } = sortStatus; + const { getSubscriptions } = useAppContext(); + + //Sort dropdown options + const sortOptions = ['Alphabetical', 'Cost', 'Payment Due']; + + const handleSortOptClick = (e) => { + e.preventDefault(); + getSubscriptions({type: props.type, sort: e.target.innerText.toLowerCase()}); + setSortStatus({ isOpen: false, activeSortOpt: e.target.innerText }); + }; + + //handler that is invoked upon clicking on sort button, toggling its open status to the opposite boolean + const handleSortClick = () => { + //invoke funtion in appContext here + //dispatch action? + setSortStatus((sortStatus) => { + return { + ...sortStatus, + isOpen: !sortStatus.isOpen, + }; + }); + }; + + //Map dropdown options to li component + const sortListItems = sortOptions.map(el => { + //If the list item was selected, provide dynamic className for dynamic styling + //Will let user know which sort option is currently active + let activeClass = activeSortOpt === el ? 'active sort-list-item' : 'sort-list-item'; + + return ( +
  • + {el} +
  • + ); + }); + + return ( +
    + + {sortStatus.isOpen && ( +
    + +
    + )} +
    + ); +}; + +export default Sort; diff --git a/client/src/components/index.js b/client/src/components/index.js index 0aeeb02..03a60a8 100644 --- a/client/src/components/index.js +++ b/client/src/components/index.js @@ -4,5 +4,7 @@ import Alert from './Alert'; import Navbar from './Navbar'; import LargeSidebar from './LargeSidebar'; import SmallSidebar from './SmallSidebar'; +import Search from './Search'; +import Sort from './Sort'; -export { Logo, FormRow, Alert, Navbar, LargeSidebar, SmallSidebar }; +export { Logo, FormRow, Alert, Navbar, LargeSidebar, SmallSidebar, Search, Sort }; diff --git a/client/src/context/actions.js b/client/src/context/actions.js index aac11a2..cf1bdd2 100644 --- a/client/src/context/actions.js +++ b/client/src/context/actions.js @@ -20,6 +20,11 @@ const GET_CURRENT_USER_SUCCESS = 'GET_CURRENT_USER_SUCCESS'; const TOGGLE_SIDEBAR = 'TOGGLE_SIDEBAR'; +//Subscriptions +const GET_SUBSCRIPTIONS_SUCCESS = 'GET_SUBSCRIPTIONS_SUCCESS'; +const GET_SUBSCRIPTIONS_ERROR = 'GET_SUBSCRIPTIONS_ERROR'; +const GET_SUBSCRIPTIONS_BEGIN = 'GET_SUBSCRIPTIONS_BEGIN'; + export { DISPLAY_ALERT, REMOVE_ALERT, @@ -36,4 +41,7 @@ export { GET_CURRENT_USER_BEGIN, GET_CURRENT_USER_SUCCESS, TOGGLE_SIDEBAR, + GET_SUBSCRIPTIONS_SUCCESS, + GET_SUBSCRIPTIONS_ERROR, + GET_SUBSCRIPTIONS_BEGIN, }; diff --git a/client/src/context/appContext.js b/client/src/context/appContext.js index 7ffea06..d6cd1c6 100644 --- a/client/src/context/appContext.js +++ b/client/src/context/appContext.js @@ -17,6 +17,9 @@ import { GET_CURRENT_USER_BEGIN, GET_CURRENT_USER_SUCCESS, TOGGLE_SIDEBAR, + GET_SUBSCRIPTIONS_BEGIN, + GET_SUBSCRIPTIONS_SUCCESS, + GET_SUBSCRIPTIONS_ERROR, } from './actions'; const initialState = { @@ -36,7 +39,7 @@ const AppProvider = ({ children }) => { // Axios config // TODO move to separate file const authFetch = axios.create({ - baseURL: '/api/v1/', + baseURL: '/api/v1', }); // alternative way to add token to header @@ -196,6 +199,39 @@ const AppProvider = ({ children }) => { getCurrentUser(); }, []); + //do we want to consider optional parameters at all? + const getSubscriptions = async ({ type, sort, search }) => { + const url = `/subscriptions?status=${type}&sort=${sort}&search=${search}`; + + try{ + dispatch({ type: GET_SUBSCRIPTIONS_BEGIN }); + + const { data } = await authFetch.get(url); + if (!data) { + throw new Error('Subscriptions not found'); + } + const { subscriptions } = data; + if (!subscriptions) { + throw new Error('Subscriptions not found'); + } + + dispatch({ + type: GET_SUBSCRIPTIONS_SUCCESS, + payload: { subscriptions } + }); + } + catch(error){ + dispatch( { + type: GET_SUBSCRIPTIONS_ERROR, + payload: { + message: + error.response?.data?.message || error.message || 'Getting subscriptions failed' + } + }); + } + clearAlert(); + }; + return ( { toggleSidebar, logoutUser, updateUser, + getSubscriptions, }} > {children} diff --git a/client/src/context/reducer.js b/client/src/context/reducer.js index 5caa010..937d222 100644 --- a/client/src/context/reducer.js +++ b/client/src/context/reducer.js @@ -14,6 +14,9 @@ import { GET_CURRENT_USER_BEGIN, GET_CURRENT_USER_SUCCESS, TOGGLE_SIDEBAR, + GET_SUBSCRIPTIONS_BEGIN, + GET_SUBSCRIPTIONS_ERROR, + GET_SUBSCRIPTIONS_SUCCESS, } from './actions'; import { initialState } from './appContext'; @@ -151,6 +154,32 @@ const reducer = (state, action) => { }; } + if (action.type === GET_SUBSCRIPTIONS_BEGIN) { + return { ...state, isLoading: true }; + } + + if (action.type === GET_SUBSCRIPTIONS_SUCCESS) { + return { + ...state, + isLoading: false, + subscriptions: action.payload.subscriptions, + } + } + + if (action.type === GET_SUBSCRIPTIONS_ERROR) { + return { + ...state, + isLoading: false, + showAlert: true, + alert: { + type: 'danger', + message: + action.payload.message || + 'Unexpected Error. Subscriptions could not be retrieved.', + } + } + } + throw new Error(`Unhandled action type: ${action.type}`); }; diff --git a/client/src/pages/dashboard/Active.jsx b/client/src/pages/dashboard/Active.jsx index 04eebba..d8ac609 100644 --- a/client/src/pages/dashboard/Active.jsx +++ b/client/src/pages/dashboard/Active.jsx @@ -1,5 +1,20 @@ -const Active = () => { - return
    Active Subscription
    ; +import { Search, Sort } from '../../components'; +import { useAppContext } from '../../context/appContext'; +import '../../assets/styles/search.scss'; + +const Active = () => { + return ( +
    +
    Active Subscriptions
    + {/* add a div container to contain the search filter and sort components w/ className for styling*/} +
    + + +
    + + {/* render all cards that have been mapped to an array and/or retrieved from state/contexAPI */} +
    + ); }; -export default Active; +export default Active; \ No newline at end of file diff --git a/client/src/pages/dashboard/Past.jsx b/client/src/pages/dashboard/Past.jsx index 3db9250..0a2ee4b 100644 --- a/client/src/pages/dashboard/Past.jsx +++ b/client/src/pages/dashboard/Past.jsx @@ -1,5 +1,17 @@ +import { Search, Sort } from '../../components'; +import { useAppContext } from '../../context/appContext'; +import '../../assets/styles/search.scss'; + const Past = () => { - return
    Past
    ; + return ( +
    +
    Past Subscriptions
    +
    + + +
    +
    + ); }; export default Past; diff --git a/client/src/pages/dashboard/Trial.jsx b/client/src/pages/dashboard/Trial.jsx index 916437e..190d0e5 100644 --- a/client/src/pages/dashboard/Trial.jsx +++ b/client/src/pages/dashboard/Trial.jsx @@ -1,5 +1,17 @@ +import { Search, Sort } from '../../components'; +import { useAppContext } from '../../context/appContext'; +import '../../assets/styles/search.scss'; + const Trial = () => { - return
    Trial
    ; + return ( +
    +
    Trial Subscriptions
    +
    + + +
    +
    + ); }; export default Trial; diff --git a/package-lock.json b/package-lock.json index 18e24df..deffc0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "subslify", "version": "0.1.0", "license": "MIT", + "dependencies": { + "ts-node": "^10.9.1" + }, "devDependencies": { "@types/node": "^18.11.18", "@typescript-eslint/eslint-plugin": "^5.48.2", @@ -2055,6 +2058,26 @@ "node": ">=6.9.0" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", @@ -2128,7 +2151,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -2145,8 +2167,7 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.17", @@ -2230,6 +2251,26 @@ "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==", "dev": true }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==" + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -2245,8 +2286,7 @@ "node_modules/@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", - "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", - "dev": true + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -2492,7 +2532,6 @@ "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -2509,6 +2548,14 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2549,6 +2596,11 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2962,6 +3014,11 @@ "node": ">=10" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3049,6 +3106,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -4654,6 +4719,11 @@ "node": ">=10" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5461,6 +5531,48 @@ "node": ">=8.0" } }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, "node_modules/tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -5548,7 +5660,6 @@ "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", - "dev": true, "peer": true, "bin": { "tsc": "bin/tsc", @@ -5648,6 +5759,11 @@ "punycode": "^2.1.0" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5744,6 +5860,14 @@ "node": ">= 6" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index f65800c..8164040 100644 --- a/package.json +++ b/package.json @@ -39,5 +39,8 @@ "eslint-config-react-app": "^7.0.1", "eslint-plugin-react": "^7.32.1", "prettier": "^2.8.1" + }, + "dependencies": { + "ts-node": "^10.9.1" } } diff --git a/server/src/Config/google.ts b/server/src/Config/google.ts index b4ea1a8..d87f447 100644 --- a/server/src/Config/google.ts +++ b/server/src/Config/google.ts @@ -6,7 +6,7 @@ import { VerifyCallback, } from 'passport-google-oauth20'; import generator from 'generate-password'; -import BadRequestError from 'src/errors/bad-request.js'; +import { BadRequestError } from '../errors/index.js'; const randomPw: string = generator.generate({ length: 10, diff --git a/server/src/controllers/subscriptionsController.js b/server/src/controllers/subscriptionsController.js index fb790df..252323c 100644 --- a/server/src/controllers/subscriptionsController.js +++ b/server/src/controllers/subscriptionsController.js @@ -32,6 +32,7 @@ const deleteSubscription = async (req, res) => { }; const getSubscriptions = async (req, res) => { + const user = req.user.id; const filter = { user, diff --git a/server/src/server.ts b/server/src/server.ts index c2c192d..c7cccb5 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -5,6 +5,7 @@ import session from 'express-session'; import passport from 'passport'; import passportConfig from './Config/google.js'; import morgan from 'morgan'; +import authenticateUser from './middleware/auth.js'; // db and authenticateUser import connectDB from './db/connect.js'; @@ -55,7 +56,7 @@ app.get('/', (_req: Request, res: Response, _next: NextFunction) => { // Register the authRouter and subscriptionsRouter to their respective endpoints. app.use('/api/v1/auth', authRouter); -app.use('/api/v1/subscriptions', subscriptionsRouter); +app.use('/api/v1/subscriptions', authenticateUser, subscriptionsRouter); app.use(notFoundMiddleware); app.use(errorHandlerMiddleware);