mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 10:42:08 +00:00
Merge pull request #66 from aaronpo97/dev
Style updates, security fixes
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -37,12 +37,11 @@ yarn-error.log*
|
|||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
# http requests
|
# HTTP playground
|
||||||
*.http
|
*.http
|
||||||
|
|
||||||
# uploaded images
|
|
||||||
public/uploads
|
|
||||||
|
|
||||||
# vscode
|
# vscode
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
/cloudinary-images
|
||||||
|
|
||||||
|
|||||||
@@ -136,8 +136,10 @@ POSTGRES_PRISMA_URL=
|
|||||||
POSTGRES_URL_NON_POOLING=
|
POSTGRES_URL_NON_POOLING=
|
||||||
SHADOW_DATABASE_URL=
|
SHADOW_DATABASE_URL=
|
||||||
|
|
||||||
|
ADMIN_PASSWORD=
|
||||||
|
|
||||||
MAPBOX_ACCESS_TOKEN=
|
MAPBOX_ACCESS_TOKEN=
|
||||||
NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN=
|
|
||||||
SPARKPOST_API_KEY=
|
SPARKPOST_API_KEY=
|
||||||
SPARKPOST_SENDER_ADDRESS=" > .env
|
SPARKPOST_SENDER_ADDRESS=" > .env
|
||||||
```
|
```
|
||||||
@@ -175,6 +177,8 @@ 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.
|
||||||
|
- `ADMIN_PASSWORD` is the password for the admin account created when seeding the
|
||||||
|
database.
|
||||||
|
|
||||||
1. Initialize the database and run the migrations.
|
1. Initialize the database and run the migrations.
|
||||||
|
|
||||||
|
|||||||
13
package-lock.json
generated
13
package-lock.json
generated
@@ -72,6 +72,7 @@
|
|||||||
"eslint-config-next": "^13.5.4",
|
"eslint-config-next": "^13.5.4",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
|
"generate-password": "^1.7.1",
|
||||||
"onchange": "^7.1.0",
|
"onchange": "^7.1.0",
|
||||||
"postcss": "^8.4.26",
|
"postcss": "^8.4.26",
|
||||||
"prettier": "^3.0.0",
|
"prettier": "^3.0.0",
|
||||||
@@ -5354,6 +5355,12 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/generate-password": {
|
||||||
|
"version": "1.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/generate-password/-/generate-password-1.7.1.tgz",
|
||||||
|
"integrity": "sha512-9bVYY+16m7W7GczRBDqXE+VVuCX+bWNrfYKC/2p2JkZukFb2sKxT6E3zZ3mJGz7GMe5iRK0A/WawSL3jQfJuNQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/geojson-vt": {
|
"node_modules/geojson-vt": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz",
|
||||||
@@ -14595,6 +14602,12 @@
|
|||||||
"wide-align": "^1.1.2"
|
"wide-align": "^1.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"generate-password": {
|
||||||
|
"version": "1.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/generate-password/-/generate-password-1.7.1.tgz",
|
||||||
|
"integrity": "sha512-9bVYY+16m7W7GczRBDqXE+VVuCX+bWNrfYKC/2p2JkZukFb2sKxT6E3zZ3mJGz7GMe5iRK0A/WawSL3jQfJuNQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"geojson-vt": {
|
"geojson-vt": {
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz",
|
||||||
|
|||||||
@@ -64,27 +64,28 @@
|
|||||||
"@types/multer": "^1.4.7",
|
"@types/multer": "^1.4.7",
|
||||||
"@types/node": "^20.4.2",
|
"@types/node": "^20.4.2",
|
||||||
"@types/passport-local": "^1.0.35",
|
"@types/passport-local": "^1.0.35",
|
||||||
"@types/react": "^18.2.15",
|
|
||||||
"@types/react-dom": "^18.2.7",
|
"@types/react-dom": "^18.2.7",
|
||||||
|
"@types/react": "^18.2.15",
|
||||||
"@types/sparkpost": "^2.1.5",
|
"@types/sparkpost": "^2.1.5",
|
||||||
"@vercel/fetch": "^7.0.0",
|
"@vercel/fetch": "^7.0.0",
|
||||||
"autoprefixer": "^10.4.14",
|
"autoprefixer": "^10.4.14",
|
||||||
"daisyui": "^3.9.2",
|
"daisyui": "^3.9.2",
|
||||||
"dotenv-cli": "^7.2.1",
|
"dotenv-cli": "^7.2.1",
|
||||||
"eslint": "^8.51.0",
|
|
||||||
"eslint-config-airbnb-base": "15.0.0",
|
"eslint-config-airbnb-base": "15.0.0",
|
||||||
"eslint-config-airbnb-typescript": "17.1.0",
|
"eslint-config-airbnb-typescript": "17.1.0",
|
||||||
"eslint-config-next": "^13.5.4",
|
"eslint-config-next": "^13.5.4",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
|
"eslint": "^8.51.0",
|
||||||
|
"generate-password": "^1.7.1",
|
||||||
"onchange": "^7.1.0",
|
"onchange": "^7.1.0",
|
||||||
"postcss": "^8.4.26",
|
"postcss": "^8.4.26",
|
||||||
"prettier": "^3.0.0",
|
|
||||||
"prettier-plugin-jsdoc": "^1.0.2",
|
"prettier-plugin-jsdoc": "^1.0.2",
|
||||||
"prettier-plugin-tailwindcss": "^0.4.1",
|
"prettier-plugin-tailwindcss": "^0.4.1",
|
||||||
|
"prettier": "^3.0.0",
|
||||||
"prisma": "^5.6.0",
|
"prisma": "^5.6.0",
|
||||||
"tailwindcss": "^3.3.3",
|
|
||||||
"tailwindcss-animate": "^1.0.6",
|
"tailwindcss-animate": "^1.0.6",
|
||||||
|
"tailwindcss": "^3.3.3",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^5.3.2"
|
"typescript": "^5.3.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { FC } from 'react';
|
|||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import GetUserSchema from '@/services/User/schema/GetUserSchema';
|
import GetUserSchema from '@/services/User/schema/GetUserSchema';
|
||||||
|
import { FaUser } from 'react-icons/fa';
|
||||||
|
|
||||||
interface UserAvatarProps {
|
interface UserAvatarProps {
|
||||||
user: {
|
user: {
|
||||||
@@ -13,13 +14,23 @@ interface UserAvatarProps {
|
|||||||
|
|
||||||
const UserAvatar: FC<UserAvatarProps> = ({ user }) => {
|
const UserAvatar: FC<UserAvatarProps> = ({ user }) => {
|
||||||
const { userAvatar } = user;
|
const { userAvatar } = user;
|
||||||
return !userAvatar ? null : (
|
return !userAvatar ? (
|
||||||
|
<div
|
||||||
|
className="h-32 w-full bg-primary mask mask-circle flex items-center justify-center"
|
||||||
|
aria-label="Default user avatar"
|
||||||
|
role="img"
|
||||||
|
>
|
||||||
|
<span className="text-2xl font-bold text-base-content h-full">
|
||||||
|
<FaUser className="h-full" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<Image
|
<Image
|
||||||
src={userAvatar.path}
|
src={userAvatar.path}
|
||||||
alt="user avatar"
|
alt="user avatar"
|
||||||
width={1000}
|
width={1000}
|
||||||
height={1000}
|
height={1000}
|
||||||
className="h-full w-full object-cover mask mask-circle ring ring-primary ring-offset-base-100 ring-offset-2"
|
className="h-full w-full object-cover mask mask-circle"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const CommentCardBody: FC<CommentCardProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div ref={ref} className="flex">
|
<div ref={ref} className="flex">
|
||||||
<div className="w-[12%] py-4 justify-center">
|
<div className="w-[12%] py-4 justify-center">
|
||||||
<div className="px-1">
|
<div className="px-3 h-20">
|
||||||
<UserAvatar user={comment.postedBy} />
|
<UserAvatar user={comment.postedBy} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
13
src/config/env/index.ts
vendored
13
src/config/env/index.ts
vendored
@@ -28,6 +28,8 @@ const envSchema = z.object({
|
|||||||
SPARKPOST_API_KEY: z.string(),
|
SPARKPOST_API_KEY: z.string(),
|
||||||
SPARKPOST_SENDER_ADDRESS: z.string().email(),
|
SPARKPOST_SENDER_ADDRESS: z.string().email(),
|
||||||
MAPBOX_ACCESS_TOKEN: z.string(),
|
MAPBOX_ACCESS_TOKEN: z.string(),
|
||||||
|
|
||||||
|
ADMIN_PASSWORD: z.string().regex(/^(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9]).{8,}$/),
|
||||||
});
|
});
|
||||||
|
|
||||||
const parsed = envSchema.safeParse(env);
|
const parsed = envSchema.safeParse(env);
|
||||||
@@ -194,3 +196,14 @@ export const SPARKPOST_SENDER_ADDRESS = parsed.data.SPARKPOST_SENDER_ADDRESS;
|
|||||||
* @see https://docs.mapbox.com/help/how-mapbox-works/access-tokens/
|
* @see https://docs.mapbox.com/help/how-mapbox-works/access-tokens/
|
||||||
*/
|
*/
|
||||||
export const MAPBOX_ACCESS_TOKEN = parsed.data.MAPBOX_ACCESS_TOKEN;
|
export const MAPBOX_ACCESS_TOKEN = parsed.data.MAPBOX_ACCESS_TOKEN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Admin password for seeding the database.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* 'abcdefghijklmnopqrstuvwxyz123456';
|
||||||
|
*
|
||||||
|
* @see README.md for instructions on generating a secret key.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const ADMIN_PASSWORD = parsed.data.ADMIN_PASSWORD;
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// create a 404 next js page using tailwind
|
|
||||||
|
|
||||||
import { NextPage } from 'next';
|
import { NextPage } from 'next';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ const AccountPage: NextPage = () => {
|
|||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<div className="m-12 flex w-11/12 flex-col items-center justify-center space-y-3 lg:w-8/12">
|
<div className="m-12 flex w-11/12 flex-col items-center justify-center space-y-3 lg:w-8/12">
|
||||||
<div className="flex flex-col items-center space-y-3">
|
<div className="flex flex-col items-center space-y-3">
|
||||||
<div className="h-32">
|
<div className="h-20 mb-10 w-20">
|
||||||
<UserAvatar user={user} />
|
<UserAvatar user={user} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { NextPage } from 'next';
|
|||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import { useContext, MutableRefObject, useRef } from 'react';
|
import { useContext, MutableRefObject, useRef } from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { FaPlus, FaArrowUp } from 'react-icons/fa';
|
import { FaPlus, FaArrowUp, FaMap } from 'react-icons/fa';
|
||||||
import { useInView } from 'react-intersection-observer';
|
import { useInView } from 'react-intersection-observer';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
@@ -51,25 +51,24 @@ const BreweryPage: NextPage<BreweryPageProps> = () => {
|
|||||||
<h1 className="text-4xl font-bold lg:text-6xl">The Biergarten App</h1>
|
<h1 className="text-4xl font-bold lg:text-6xl">The Biergarten App</h1>
|
||||||
<h2 className="text-2xl font-bold lg:text-4xl">Breweries</h2>
|
<h2 className="text-2xl font-bold lg:text-4xl">Breweries</h2>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
</div>
|
||||||
<Link
|
<div className="flex flex-col">
|
||||||
className="link-hover link text-xl font-bold lg:text-2xl"
|
{!!user && (
|
||||||
href="/breweries/map"
|
<div
|
||||||
|
className="tooltip tooltip-left"
|
||||||
|
data-tip="Create a new brewery post"
|
||||||
>
|
>
|
||||||
View map
|
<Link href="/breweries/create" className="btn-ghost btn-sm btn">
|
||||||
|
<FaPlus className="text-lg" />
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="tooltip tooltip-left" data-tip="View map">
|
||||||
|
<Link className="btn-ghost btn-sm btn" href="/breweries/map">
|
||||||
|
<FaMap className="text-lg" />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!!user && (
|
|
||||||
<div
|
|
||||||
className="tooltip tooltip-left h-full"
|
|
||||||
data-tip="Create a new brewery post"
|
|
||||||
>
|
|
||||||
<Link href="/breweries/create" className="btn-ghost btn-sm btn">
|
|
||||||
<FaPlus />
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</header>
|
</header>
|
||||||
<div className="grid gap-6 xl:grid-cols-2">
|
<div className="grid gap-6 xl:grid-cols-2">
|
||||||
{!!breweryPosts.length && !isLoading && (
|
{!!breweryPosts.length && !isLoading && (
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const BreweryMapPage: NextPage<BreweryMapPageProps> = ({ token }) => {
|
|||||||
|
|
||||||
const mapStyles: MapStyles = {
|
const mapStyles: MapStyles = {
|
||||||
light: 'mapbox://styles/mapbox/light-v10',
|
light: 'mapbox://styles/mapbox/light-v10',
|
||||||
dark: 'mapbox://styles/mapbox/dark-v11',
|
dark: 'mapbox://styles/mapbox/dark-v10',
|
||||||
};
|
};
|
||||||
|
|
||||||
const pins = useMemo(
|
const pins = useMemo(
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { hashPassword } from '../../../config/auth/passwordFns';
|
import { hashPassword } from '../../../config/auth/passwordFns';
|
||||||
|
import { ADMIN_PASSWORD } from '../../../config/env';
|
||||||
|
|
||||||
import DBClient from '../../DBClient';
|
import DBClient from '../../DBClient';
|
||||||
import GetUserSchema from '../../../services/User/schema/GetUserSchema';
|
import GetUserSchema from '../../../services/User/schema/GetUserSchema';
|
||||||
import imageUrls from '../util/imageUrls';
|
import imageUrls from '../util/imageUrls';
|
||||||
|
|
||||||
const createAdminUser = async () => {
|
const createAdminUser = async () => {
|
||||||
const hash = await hashPassword('Pas!3word');
|
const hash = await hashPassword(ADMIN_PASSWORD);
|
||||||
const adminUser: z.infer<typeof GetUserSchema> = await DBClient.instance.user.create({
|
const adminUser: z.infer<typeof GetUserSchema> = await DBClient.instance.user.create({
|
||||||
data: {
|
data: {
|
||||||
username: 'admin',
|
username: 'admin',
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import { faker } from '@faker-js/faker';
|
import { faker } from '@faker-js/faker';
|
||||||
|
import generator from 'generate-password';
|
||||||
|
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import DBClient from '../../DBClient';
|
import DBClient from '../../DBClient';
|
||||||
import { hashPassword } from '../../../config/auth/passwordFns';
|
import { hashPassword } from '../../../config/auth/passwordFns';
|
||||||
|
import logger from '../../../config/pino/logger';
|
||||||
|
|
||||||
interface CreateNewUsersArgs {
|
interface CreateNewUsersArgs {
|
||||||
numberOfUsers: number;
|
numberOfUsers: number;
|
||||||
@@ -23,9 +26,25 @@ interface UserData {
|
|||||||
|
|
||||||
const createNewUsers = async ({ numberOfUsers }: CreateNewUsersArgs) => {
|
const createNewUsers = async ({ numberOfUsers }: CreateNewUsersArgs) => {
|
||||||
const prisma = DBClient.instance;
|
const prisma = DBClient.instance;
|
||||||
|
await DBClient.instance.$disconnect();
|
||||||
|
|
||||||
|
const passwords = Array.from({ length: numberOfUsers }, () =>
|
||||||
|
generator.generate({
|
||||||
|
length: 20,
|
||||||
|
symbols: true,
|
||||||
|
numbers: true,
|
||||||
|
uppercase: true,
|
||||||
|
strict: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
logger.info('Hashing passwords. This may take a while...');
|
||||||
|
const hashedPasswords = await Promise.all(
|
||||||
|
passwords.map((password) => hashPassword(password)),
|
||||||
|
);
|
||||||
|
|
||||||
|
logger.info('Creating new users. This may take a while...');
|
||||||
|
|
||||||
const password = 'passwoRd!3';
|
|
||||||
const hash = await hashPassword(password);
|
|
||||||
const data: UserData[] = [];
|
const data: UserData[] = [];
|
||||||
|
|
||||||
const takenUsernames: string[] = [];
|
const takenUsernames: string[] = [];
|
||||||
@@ -41,6 +60,7 @@ const createNewUsers = async ({ numberOfUsers }: CreateNewUsersArgs) => {
|
|||||||
.email({ firstName, lastName, provider: 'example.com' })
|
.email({ firstName, lastName, provider: 'example.com' })
|
||||||
.toLowerCase();
|
.toLowerCase();
|
||||||
|
|
||||||
|
const hash = hashedPasswords[i];
|
||||||
const userAvailable =
|
const userAvailable =
|
||||||
!takenUsernames.includes(username) && !takenEmails.includes(email);
|
!takenUsernames.includes(username) && !takenEmails.includes(email);
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import createNewUserFollows from './create/createNewUserFollows';
|
|||||||
await createAdminUser();
|
await createAdminUser();
|
||||||
logger.info('Admin user created successfully.');
|
logger.info('Admin user created successfully.');
|
||||||
|
|
||||||
const users = await createNewUsers({ numberOfUsers: 10000 });
|
const users = await createNewUsers({ numberOfUsers: 1000 });
|
||||||
logger.info('Users created successfully.');
|
logger.info('Users created successfully.');
|
||||||
|
|
||||||
const userAvatars = await createNewUserAvatars({ joinData: { users } });
|
const userAvatars = await createNewUserAvatars({ joinData: { users } });
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
const imageUrls = [
|
const imageUrls = [
|
||||||
'https://res.cloudinary.com/dxie9b7na/image/upload/v1683482214/cld-sample.jpg',
|
'https://res.cloudinary.com/dxie9b7na/image/upload/v1701056802/cloudinary-images/pexels-brett-sayles-1551944_era4te.jpg',
|
||||||
'https://res.cloudinary.com/dxie9b7na/image/upload/v1683482214/cld-sample-2.jpg',
|
'https://res.cloudinary.com/dxie9b7na/image/upload/v1701056801/cloudinary-images/pexels-ketut-subiyanto-5055809_fwkfoj.jpg',
|
||||||
'https://res.cloudinary.com/dxie9b7na/image/upload/v1683482214/cld-sample-3.jpg',
|
'https://res.cloudinary.com/dxie9b7na/image/upload/v1701056801/cloudinary-images/pexels-cottonbro-studio-5537954_zsxs7n.jpg',
|
||||||
'https://res.cloudinary.com/dxie9b7na/image/upload/v1683482214/cld-sample-4.jpg',
|
'https://res.cloudinary.com/dxie9b7na/image/upload/v1701056800/cloudinary-images/pexels-tembela-bohle-1089931_f7jcer.jpg',
|
||||||
'https://res.cloudinary.com/dxie9b7na/image/upload/v1683482214/cld-sample-5.jpg',
|
'https://res.cloudinary.com/dxie9b7na/image/upload/v1701056798/cloudinary-images/pexels-tembela-bohle-1089930_yzfjlv.jpg',
|
||||||
|
'https://res.cloudinary.com/dxie9b7na/image/upload/v1701056797/cloudinary-images/pexels-cottonbro-studio-5529918_e0jlle.jpg',
|
||||||
|
'https://res.cloudinary.com/dxie9b7na/image/upload/v1701056797/cloudinary-images/pexels-casalfilmsestudio-2076748_xymlox.jpg',
|
||||||
|
'https://res.cloudinary.com/dxie9b7na/image/upload/v1701056795/cloudinary-images/pexels-elevate-3009770_simouh.jpg',
|
||||||
|
'https://res.cloudinary.com/dxie9b7na/image/upload/v1701056793/cloudinary-images/pexels-elevate-1267700_jrno3s.jpg',
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export default imageUrls;
|
export default imageUrls;
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ const myThemes = {
|
|||||||
warning: 'hsl(50, 98%, 50%)',
|
warning: 'hsl(50, 98%, 50%)',
|
||||||
'primary-content': 'hsl(0, 0%, 98%)',
|
'primary-content': 'hsl(0, 0%, 98%)',
|
||||||
'error-content': 'hsl(0, 0%, 98%)',
|
'error-content': 'hsl(0, 0%, 98%)',
|
||||||
'base-100': 'hsl(227, 20%, 10%)',
|
'base-100': 'hsl(227, 20%, 20%)',
|
||||||
'base-200': 'hsl(227, 20%, 8%)',
|
'base-200': 'hsl(227, 20%, 13%)',
|
||||||
'base-300': 'hsl(227, 20%, 1%)',
|
'base-300': 'hsl(227, 20%, 10%)',
|
||||||
},
|
},
|
||||||
light: {
|
light: {
|
||||||
primary: 'hsl(180, 15%, 60%)',
|
primary: 'hsl(180, 15%, 70%)',
|
||||||
secondary: 'hsl(21, 54%, 83%)',
|
secondary: 'hsl(21, 54%, 83%)',
|
||||||
error: 'hsl(4, 87%, 74%)',
|
error: 'hsl(4, 87%, 74%)',
|
||||||
accent: 'hsl(93, 27%, 73%)',
|
accent: 'hsl(93, 27%, 73%)',
|
||||||
|
|||||||
Reference in New Issue
Block a user