From e040fa0a1ac1a88e49dd3a5adcb48aea62990462 Mon Sep 17 00:00:00 2001 From: Pieter Stols Date: Fri, 26 Apr 2024 19:14:11 +0300 Subject: [PATCH] first commit --- .eslintrc.json | 21 + .github/workflows/deploy.yaml | 44 + .gitignore | 37 + .prettierignore | 2 + .prettierrc | 18 + README.md | 61 + components/CancelBtn.jsx | 20 + components/Client.jsx | 44 + components/ClientList.jsx | 25 + components/Footer.jsx | 7 + components/Header.jsx | 37 + components/Layout.jsx | 17 + css/tailwind.css | 3 + db/models/client.js | 16 + db/mongoose.js | 17 + next.config.js | 8 + package.json | 36 + pages/_app.js | 21 + pages/add-client.jsx | 178 + pages/api/add-client.js | 34 + pages/api/clients.js | 20 + pages/api/delete-client.js | 21 + pages/api/get-client.js | 16 + pages/api/update-client.js | 22 + pages/edit/[id].jsx | 226 ++ pages/index.jsx | 66 + postcss.config.js | 3 + public/favicon.ico | Bin 0 -> 15086 bytes public/zeit.svg | 10 + sst-env.d.ts | 1 + sst.config.ts | 26 + tailwind.config.js | 3 + utils/notify-message.js | 23 + yarn.lock | 7087 +++++++++++++++++++++++++++++++++ 34 files changed, 8170 insertions(+) create mode 100644 .eslintrc.json create mode 100644 .github/workflows/deploy.yaml create mode 100644 .gitignore create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 README.md create mode 100644 components/CancelBtn.jsx create mode 100644 components/Client.jsx create mode 100644 components/ClientList.jsx create mode 100644 components/Footer.jsx create mode 100644 components/Header.jsx create mode 100644 components/Layout.jsx create mode 100644 css/tailwind.css create mode 100644 db/models/client.js create mode 100644 db/mongoose.js create mode 100644 next.config.js create mode 100644 package.json create mode 100644 pages/_app.js create mode 100644 pages/add-client.jsx create mode 100644 pages/api/add-client.js create mode 100644 pages/api/clients.js create mode 100644 pages/api/delete-client.js create mode 100644 pages/api/get-client.js create mode 100644 pages/api/update-client.js create mode 100644 pages/edit/[id].jsx create mode 100644 pages/index.jsx create mode 100644 postcss.config.js create mode 100644 public/favicon.ico create mode 100644 public/zeit.svg create mode 100644 sst-env.d.ts create mode 100644 sst.config.ts create mode 100644 tailwind.config.js create mode 100644 utils/notify-message.js create mode 100644 yarn.lock diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..afdb519 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,21 @@ +{ + "env": { + "browser": true, + "es6": true, + "node": true + }, + "extends": ["eslint:recommended", "plugin:react/recommended"], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 2018, + "sourceType": "module" + }, + "plugins": ["react"], + "rules": { "react/react-in-jsx-scope": "off" } +} diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000..9884cc2 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,44 @@ +name: Deploy Via SST + +on: + push: + branches: [master] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + env: + MONGODB_URI: ${{secrets.MONGODB_URI}} + USERNAME: Paul + WEBURL: https://d2pwr7td6bbxrr.cloudfront.net + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 18 + + - name: Cache Next.js Build + uses: actions/cache@v3 + with: + path: | + .next/cache/ + .open-next/ + .sst/ + key: cache-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]xs') }} + restore-keys: | + cache-${{ hashFiles('**/yarn.lock.') }}- + + - run: npm install -g yarn + - run: yarn install --frozen-lockfile + - run: yarn build + + - name: Install AWS Creds + run: | + mkdir -p ~/.aws + echo "[default]" > ~/.aws/credentials + echo "aws_access_key_id=${{ secrets.AWS_ACCESS_KEY_ID }}" >> ~/.aws/credentials + echo "aws_secret_access_key=${{ secrets.AWS_SECRET_ACCESS_KEY }}" >> ~/.aws/credentials + + - name: Deploy to AWS with SST + run: npx sst deploy --stage production diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff81620 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local +.env + +# sst +.sst + +# open-next +.open-next \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..6cc2cb2 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +.next +coverage diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..a887023 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,18 @@ +{ + "arrowParens": "avoid", + "bracketSpacing": true, + "htmlWhitespaceSensitivity": "css", + "insertPragma": false, + "bracketSameLine": false, + "jsxSingleQuote": false, + "printWidth": 80, + "proseWrap": "preserve", + "quoteProps": "as-needed", + "requirePragma": false, + "semi": false, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "none", + "useTabs": false, + "vueIndentScriptAndStyle": false +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2be66c --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +# Test a Next.js App with Cypress + +## Video Lesson Outline: + +[# 1 - Application Overview](https://youtu.be/xIl-0ZTtOHY) + +[# 2 - Install Cypress and eslint-plugin-cypress](https://youtu.be/dkekN7rKF1Y) + +[# 3 - Configure Cypress.json File](https://youtu.be/smd5UQUq5Uc) + +[# 4 - Write Our First Test](https://youtu.be/TLjFmOpGjUU) + +[# 5 - Write Better Tests with Cypress Testing Library](https://youtu.be/a1SvfURYxTQ) + +[# 6 - Run Cypress in Multiple Browsers](https://youtu.be/z7s-acDceCs) + +[# 7 - Test The Client Flow ](https://youtu.be/RupBr0w-bAk) + +## Installing/Running the app + +### Create a .env file + +``` +USERNAME="name you want displayed in project here" +MONGODB_URI="database creds here" +``` + +```bash +yarn +yarn dev +``` + +## Running Tests + +```bash +yarn cy:open +``` + +### Formatting with Prettier + +```bash +yarn format +``` + +## Technologies Used + +[NextJS](https://nextjs.org/) + +[Cypress-testing-library](https://testing-library.com/docs/cypress-testing-library/intro) + +[Tailwindcss](https://tailwindcss.com/) + +[React-notifications-component](https://teodosii.github.io/react-notifications-component/) + +[React-icons](https://github.com/react-icons/react-icons#readme) + +[Mongoose](https://mongoosejs.com/) + +[MongoDB Atlas](https://www.mongodb.com/cloud/atlas/) + +[Prettier](https://prettier.io/docs/en/install.html) diff --git a/components/CancelBtn.jsx b/components/CancelBtn.jsx new file mode 100644 index 0000000..13aeec5 --- /dev/null +++ b/components/CancelBtn.jsx @@ -0,0 +1,20 @@ +import Link from 'next/link' +import { MdCancel } from 'react-icons/md' + +const CancelBtn = () => ( + +) + +export default CancelBtn diff --git a/components/Client.jsx b/components/Client.jsx new file mode 100644 index 0000000..95eb5f9 --- /dev/null +++ b/components/Client.jsx @@ -0,0 +1,44 @@ +import PropTypes from 'prop-types' +import Link from 'next/link' +import { FaRegEdit } from 'react-icons/fa' + +const Client = ({ id, name, email, phone, address, company, notes }) => { + return ( + <> + + {name} + {email} + {phone} + {address} + {company} + + {notes ? `${notes.slice(0, 15)}...` : ''} + + + + + + + ) +} + +Client.propTypes = { + id: PropTypes.string, + name: PropTypes.string, + email: PropTypes.string, + phone: PropTypes.number, + address: PropTypes.string, + company: PropTypes.string, + notes: PropTypes.string +}.isRequired + +export default Client diff --git a/components/ClientList.jsx b/components/ClientList.jsx new file mode 100644 index 0000000..4269865 --- /dev/null +++ b/components/ClientList.jsx @@ -0,0 +1,25 @@ +import PropTypes from 'prop-types' +import Client from './Client' + +const ClientList = ({ clients }) => { + if (clients) { + const list = clients.map(client => ) + return <>{list} + } +} + +ClientList.propTypes = { + clients: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string, + name: PropTypes.string, + email: PropTypes.string, + phone: PropTypes.number, + address: PropTypes.string, + company: PropTypes.string, + notes: PropTypes.string + }) + ) +} + +export default ClientList diff --git a/components/Footer.jsx b/components/Footer.jsx new file mode 100644 index 0000000..895738b --- /dev/null +++ b/components/Footer.jsx @@ -0,0 +1,7 @@ +const Footer = () => ( +
+ Client Address Book Ⓒ{new Date().getFullYear()} +
+) + +export default Footer diff --git a/components/Header.jsx b/components/Header.jsx new file mode 100644 index 0000000..b15d206 --- /dev/null +++ b/components/Header.jsx @@ -0,0 +1,37 @@ +import Link from 'next/link' +import { useRouter } from 'next/router' +import { FaAddressCard } from 'react-icons/fa' + +const Header = () => ( +
+
    +
  • + + + + {process.env.username}'s Clients{' '} +
  • + +
+
+) + +export default Header diff --git a/components/Layout.jsx b/components/Layout.jsx new file mode 100644 index 0000000..a3bdfce --- /dev/null +++ b/components/Layout.jsx @@ -0,0 +1,17 @@ +import PropTypes from 'prop-types' +import Header from './Header' +import Footer from './Footer' + +const Layout = props => ( + <> +
+
{props.children}
+