mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 20:13:49 +00:00
Update readme, add docs to useMediaQuery, fix security issue with vm2
This commit is contained in:
@@ -4,13 +4,13 @@
|
|||||||
|
|
||||||
The Biergarten App is a web application designed for beer lovers to share their favorite brews and breweries with like-minded people online.
|
The Biergarten App is a web application designed for beer lovers to share their favorite brews and breweries with like-minded people online.
|
||||||
|
|
||||||
I'm using Next.js, Prisma, and CockroachDB to build this app, and I'm motivated to learn more about these technologies while exploring my passion for beer.
|
This application's stack consists of Next.js, Prisma and CockroachDB, and I'm motivated to learn more about these technologies while exploring my passion for beer.
|
||||||
|
|
||||||
I've also incorporated different APIs into the application, such as the Cloudinary API for image uploading and SparkPost for email services.
|
I've also incorporated different APIs into the application, such as the Cloudinary API for image uploading and the SparkPost API for email services.
|
||||||
|
|
||||||
To handle serverless functions (API routes), I use the next-connect package.
|
To handle serverless functions (API routes), I use the next-connect package.
|
||||||
|
|
||||||
On the client-side, I'm using React, Tailwind CSS, and DaisyUI for styling to create a visually appealing and user-friendly interface.
|
On the client-side, I use Tailwind CSS, Headless UI and Daisy UI for styling to create a visually appealing and user-friendly interface.
|
||||||
|
|
||||||
I'm sharing my code publicly so that others can learn from it and use it as a reference for their own projects.
|
I'm sharing my code publicly so that others can learn from it and use it as a reference for their own projects.
|
||||||
|
|
||||||
@@ -93,13 +93,12 @@ SPARKPOST_SENDER_ADDRESS=" > .env
|
|||||||
- `SPARKPOST_API_KEY` is the API key for your SparkPost account.
|
- `SPARKPOST_API_KEY` is the API key for your SparkPost account.
|
||||||
- You can create a free account [here](https://www.sparkpost.com/).
|
- You can create a free account [here](https://www.sparkpost.com/).
|
||||||
- `SPARKPOST_SENDER_ADDRESS` is the email address that will be used to send emails.
|
- `SPARKPOST_SENDER_ADDRESS` is the email address that will be used to send emails.
|
||||||
- This email address must be verified in your SparkPost account.
|
|
||||||
|
|
||||||
4. Initialize the database and run the migrations.
|
4. Initialize the database and run the migrations.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx prisma generate
|
npx prisma generate
|
||||||
npx prisma migrate dev --name init
|
npx prisma migrate dev
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Seed the database with some initial data.
|
5. Seed the database with some initial data.
|
||||||
|
|||||||
12
package-lock.json
generated
12
package-lock.json
generated
@@ -10213,9 +10213,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vm2": {
|
"node_modules/vm2": {
|
||||||
"version": "3.9.15",
|
"version": "3.9.16",
|
||||||
"resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.15.tgz",
|
"resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.16.tgz",
|
||||||
"integrity": "sha512-XqNqknHGw2avJo13gbIwLNZUumvrSHc9mLqoadFZTpo3KaNEJoe1I0lqTFhRXmXD7WkLyG01aaraXdXT0pa4ag==",
|
"integrity": "sha512-3T9LscojNTxdOyG+e8gFeyBXkMlOBYDoF6dqZbj+MPVHi9x10UfiTAJIobuchRCp3QvC+inybTbMJIUrLsig0w==",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "^8.7.0",
|
"acorn": "^8.7.0",
|
||||||
@@ -17582,9 +17582,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vm2": {
|
"vm2": {
|
||||||
"version": "3.9.15",
|
"version": "3.9.16",
|
||||||
"resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.15.tgz",
|
"resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.16.tgz",
|
||||||
"integrity": "sha512-XqNqknHGw2avJo13gbIwLNZUumvrSHc9mLqoadFZTpo3KaNEJoe1I0lqTFhRXmXD7WkLyG01aaraXdXT0pa4ag==",
|
"integrity": "sha512-3T9LscojNTxdOyG+e8gFeyBXkMlOBYDoF6dqZbj+MPVHi9x10UfiTAJIobuchRCp3QvC+inybTbMJIUrLsig0w==",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"acorn": "^8.7.0",
|
"acorn": "^8.7.0",
|
||||||
|
|||||||
@@ -1,15 +1,49 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
const useMediaQuery = (query: string) => {
|
/**
|
||||||
|
* A custom react hook that provides a convenient way to query the viewport size and check
|
||||||
|
* if it matches a given media query. The hook returns a boolean value indicating whether
|
||||||
|
* the query matches the current viewport size.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const isSmallScreen = useMediaQuery('(max-width: 600px)');
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const userPrefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
|
||||||
|
*
|
||||||
|
* @param query - A media query string to match against.
|
||||||
|
* @returns - A boolean indicating whether the given media query matches the current
|
||||||
|
* viewport size.
|
||||||
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries|Media Queries} for more information on media queries in CSS.
|
||||||
|
*/
|
||||||
|
const useMediaQuery = (query: `(${string})`) => {
|
||||||
|
/**
|
||||||
|
* Initialize the matches state variable to false. This is updated whenever the viewport
|
||||||
|
* size changes (i.e. when the component is mounted and when the window is resized)
|
||||||
|
*/
|
||||||
const [matches, setMatches] = useState(false);
|
const [matches, setMatches] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
/**
|
||||||
|
* Create a media query object based on the provided query string. This is used to
|
||||||
|
* check if the media query matches the current viewport size.
|
||||||
|
*/
|
||||||
const media = window.matchMedia(query);
|
const media = window.matchMedia(query);
|
||||||
if (media.matches !== matches) {
|
if (media.matches !== matches) {
|
||||||
setMatches(media.matches);
|
setMatches(media.matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a resize event listener to the window object, and update the `matches` state
|
||||||
|
* variable whenever the viewport size changes.
|
||||||
|
*/
|
||||||
const listener = () => setMatches(media.matches);
|
const listener = () => setMatches(media.matches);
|
||||||
window.addEventListener('resize', listener);
|
window.addEventListener('resize', listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup function that removes the resize event listener when the component is
|
||||||
|
* unmounted or when the dependencies change.
|
||||||
|
*/
|
||||||
return () => window.removeEventListener('resize', listener);
|
return () => window.removeEventListener('resize', listener);
|
||||||
}, [matches, query]);
|
}, [matches, query]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user