@@ -1,25 +0,0 @@
|
||||
{
|
||||
"rules": {
|
||||
"comma-dangle": [
|
||||
"error",
|
||||
{
|
||||
"arrays": "never",
|
||||
"objects": "never",
|
||||
"imports": "never",
|
||||
"exports": "never",
|
||||
"functions": "never"
|
||||
}
|
||||
]
|
||||
},
|
||||
"extends": [
|
||||
"next",
|
||||
"next/core-web-vitals",
|
||||
"plugin:jsx-a11y/strict",
|
||||
"prettier",
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:react-hooks/recommended"
|
||||
],
|
||||
"plugins": ["@typescript-eslint", "react-hooks", "jsx-a11y"]
|
||||
}
|
||||
6
.github/workflows/main.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x, 16.x, 18.x, 20.x]
|
||||
node-version: [18.x, 20.x, 22.x]
|
||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@@ -34,6 +34,10 @@ jobs:
|
||||
# # - run: npm run start
|
||||
# - run: npm run test
|
||||
|
||||
# Corepack
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
# YARN
|
||||
- uses: borales/actions-yarn@v3.0.0
|
||||
with:
|
||||
|
||||
21
.gitignore
vendored
@@ -3,7 +3,12 @@
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/versions
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
@@ -23,12 +28,14 @@
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
|
||||
# yarn
|
||||
.yarn/*
|
||||
!.yarn/releases
|
||||
!.yarn/plugins
|
||||
.pnp.*
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
893
.yarn/releases/yarn-4.1.0.cjs
vendored
@@ -1,7 +0,0 @@
|
||||
nodeLinker: node-modules
|
||||
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||
spec: "@yarnpkg/plugin-interactive-tools"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.6.4.cjs
|
||||
@@ -1,7 +1 @@
|
||||
compressionLevel: mixed
|
||||
|
||||
enableGlobalCache: false
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
yarnPath: .yarn/releases/yarn-4.1.0.cjs
|
||||
|
||||
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Lucid Kobold
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,64 +0,0 @@
|
||||
import {
|
||||
format,
|
||||
getDaysInMonth,
|
||||
isBefore,
|
||||
setDate,
|
||||
startOfDay
|
||||
} from "date-fns";
|
||||
|
||||
/**
|
||||
* Generated a valid sticker value for use when generating a sticker obj.
|
||||
* @returns {ValidStickerVal} a number that will represent a valid sticker value.
|
||||
*/
|
||||
const generateSticker = (): -2 | -1 | 0 | 1 | 2 => {
|
||||
const sticker = Math.floor(Math.random() * (2 - -2 + 1)) + -2;
|
||||
|
||||
if (
|
||||
sticker === -2 ||
|
||||
sticker === -1 ||
|
||||
sticker === 0 ||
|
||||
sticker === 1 ||
|
||||
sticker === 2
|
||||
) {
|
||||
return sticker;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Update so seeder takes in a month or date to then generate the stickers for it.
|
||||
/**
|
||||
* This seeder is to simulate the date and sticker info from the database.
|
||||
* Filling up an array for the current month with sticker from ths first to
|
||||
* the day before the current date, leaving the rest of the month empty.
|
||||
* @returns {StickerDays} an array with populated sticker objects that correspond to the current month's info.
|
||||
*/
|
||||
const stickersSeeder = (): StickerDays => {
|
||||
const stickers = [] as Sticker[];
|
||||
|
||||
const now = startOfDay(new Date());
|
||||
const daysOfThisMonth = getDaysInMonth(now);
|
||||
|
||||
for (let i = 1; i <= daysOfThisMonth; i++) {
|
||||
const currDate = setDate(now, i);
|
||||
|
||||
const sticker = isBefore(currDate, now) ? generateSticker() : null;
|
||||
|
||||
const id =
|
||||
format(currDate, "yyyyddLL") + `/${sticker === null ? 0 : sticker}`;
|
||||
|
||||
const newSticker: Sticker = {
|
||||
id: id,
|
||||
date: currDate.toJSON(),
|
||||
sticker: sticker,
|
||||
edited: false,
|
||||
manual: false
|
||||
};
|
||||
|
||||
stickers.push(newSticker);
|
||||
}
|
||||
|
||||
if (stickers.length === daysOfThisMonth) {
|
||||
return stickers;
|
||||
}
|
||||
};
|
||||
|
||||
export default stickersSeeder;
|
||||
34
eslint.config.mjs
Normal file
@@ -0,0 +1,34 @@
|
||||
import { dirname } from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { FlatCompat } from "@eslint/eslintrc";
|
||||
import jsxA11y from "eslint-plugin-jsx-a11y";
|
||||
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
|
||||
import reactPlugin from "eslint-plugin-react";
|
||||
import reactHooks from "eslint-plugin-react-hooks";
|
||||
import eslint from "@eslint/js";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname
|
||||
});
|
||||
|
||||
const eslintConfig = [
|
||||
...compat.extends("next/core-web-vitals", "next/typescript"),
|
||||
eslintPluginPrettierRecommended,
|
||||
reactPlugin.configs.flat.recommended,
|
||||
reactPlugin.configs.flat["jsx-runtime"],
|
||||
eslint.configs.recommended,
|
||||
{
|
||||
plugins: {
|
||||
jsxA11y: jsxA11y.configs.strict,
|
||||
"react-hooks": reactHooks,
|
||||
tseslint: tseslint.configs.recommended,
|
||||
"tseslint-styles": tseslint.configs.stylistic
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
export default eslintConfig;
|
||||
17
example.env
@@ -1,17 +0,0 @@
|
||||
# Environment variables declared in this file are automatically made available to Prisma.
|
||||
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
|
||||
|
||||
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
|
||||
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
|
||||
|
||||
# This is for local/dev. Make sure to update ./prisma/schema.prisma to use the dev config.
|
||||
DATABASE_URL="postgresql://postgres:randompassword@localhost:5432/dbname?schema=public"
|
||||
|
||||
# These are values from Vercel. Make sure to update ./prisma/schema.prisma to use the vercel config.
|
||||
POSTGRES_DATABASE="dbname"
|
||||
POSTGRES_PASSWORD="randompassword"
|
||||
POSTGRES_HOST="region.postgres.vercel-storage.com"
|
||||
POSTGRES_USER="postgres"
|
||||
POSTGRES_PRISMA_URL="postgres://postgres:randompassword@region.postgres.vercel-storage.com/dbname?pgbouncer=true&connect_timeout=15"
|
||||
POSTGRES_URL_NON_POOLING="postgres://postgres:randompassword@region.postgres.vercel-storage.com/dbname"
|
||||
POSTGRES_URL="postgres://postgres:randompassword@region.postgres.vercel-storage.com/dbname"
|
||||
@@ -1,14 +0,0 @@
|
||||
# This section is only applicable during the beta and will be removed when the app is completed.
|
||||
NEXT_PUBLIC_APP_VERSION="0.2.0"
|
||||
|
||||
# Auth Secrets
|
||||
NEXTAUTH_URL=http://localhost:3000
|
||||
NEXTAUTH_SECRET=""
|
||||
# Used when sending emails to users
|
||||
EMAIL_SERVER_USER=""
|
||||
EMAIL_SERVER_PASSWORD=""
|
||||
SMTP_SERVER_HOST=""
|
||||
SMTP_SERVER_PORT=""
|
||||
EMAIL_FROM=""
|
||||
GOOGLE_ID=""
|
||||
GOOGLE_SECRET=""
|
||||
@@ -1,179 +0,0 @@
|
||||
import {
|
||||
getDate,
|
||||
endOfMonth,
|
||||
format,
|
||||
startOfMonth,
|
||||
set,
|
||||
isAfter,
|
||||
isBefore,
|
||||
subMonths,
|
||||
addDays
|
||||
} from "date-fns";
|
||||
|
||||
const weekDays: WeekDays = {
|
||||
sunday: [
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday"
|
||||
],
|
||||
monday: [
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
"Saturday",
|
||||
"Sunday"
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Using date-fns, this function checks if currDate is within the month of selectedDate or not.
|
||||
* @param {Date} selectedDate The current month.
|
||||
* @param {Date} currDate The date to be compared to the selected month.
|
||||
* @returns True if currDate is outside of the month of selectedDate, false if otherwise.
|
||||
*/
|
||||
const isOverflow = (
|
||||
selectedDate: Date,
|
||||
currDate: Date
|
||||
): {
|
||||
isOverflow: boolean;
|
||||
overflowDirection: "prev" | "next" | null;
|
||||
} => {
|
||||
let flag = false;
|
||||
let direction: "next" | "prev" | null = null;
|
||||
|
||||
const start = startOfMonth(selectedDate);
|
||||
const end = endOfMonth(selectedDate);
|
||||
|
||||
if (isBefore(currDate, start)) {
|
||||
flag = true;
|
||||
direction = "prev";
|
||||
}
|
||||
|
||||
if (isAfter(currDate, end)) {
|
||||
flag = true;
|
||||
direction = "next";
|
||||
}
|
||||
|
||||
return { isOverflow: flag, overflowDirection: direction };
|
||||
};
|
||||
|
||||
/**
|
||||
* A function that will return a month layout when given a date. It produces
|
||||
* an object with 6 weeks that include overflow from the previous and next month
|
||||
* with all dates aligned with the day of the week.
|
||||
* @param selectedDate The date of the month to generate a month layout for.
|
||||
* @returns The month layout object for the provided month.
|
||||
*/
|
||||
const populateMonth = (selectedDate: Date): MonthLayout => {
|
||||
const endLastMonth = getDate(endOfMonth(subMonths(selectedDate, 1)));
|
||||
const startOfSelectedMonth = format(startOfMonth(selectedDate), "iii");
|
||||
|
||||
const ISOToIndex = {
|
||||
sunday: {
|
||||
Sun: 0,
|
||||
Mon: 1,
|
||||
Tue: 2,
|
||||
Wed: 3,
|
||||
Thu: 4,
|
||||
Fri: 5,
|
||||
Sat: 6
|
||||
},
|
||||
monday: {
|
||||
Mon: -1,
|
||||
Tue: 0,
|
||||
Wed: 1,
|
||||
Thu: 2,
|
||||
Fri: 3,
|
||||
Sat: 4,
|
||||
Sun: 5
|
||||
}
|
||||
};
|
||||
|
||||
const sundays = {
|
||||
week1: new Array(7).fill(null),
|
||||
week2: new Array(7).fill(null),
|
||||
week3: new Array(7).fill(null),
|
||||
week4: new Array(7).fill(null),
|
||||
week5: new Array(7).fill(null),
|
||||
week6: new Array(7).fill(null)
|
||||
};
|
||||
|
||||
// The date of the first day in the overflow
|
||||
const sunStartDay =
|
||||
endLastMonth - (ISOToIndex.sunday[startOfSelectedMonth] - 1);
|
||||
|
||||
let sunCurrDate = set(subMonths(selectedDate, 1), {
|
||||
date: sunStartDay
|
||||
});
|
||||
|
||||
for (const week in sundays) {
|
||||
const thisWeek = sundays[week];
|
||||
|
||||
thisWeek.forEach((e, i) => {
|
||||
const overflowInfo = isOverflow(selectedDate, sunCurrDate);
|
||||
|
||||
const day: MonthDay = {
|
||||
...overflowInfo,
|
||||
date: sunCurrDate.toJSON()
|
||||
};
|
||||
|
||||
sunCurrDate = addDays(sunCurrDate, 1);
|
||||
|
||||
sundays[week][i] = day;
|
||||
});
|
||||
}
|
||||
|
||||
const mondays = {
|
||||
week1: new Array(7).fill(null),
|
||||
week2: new Array(7).fill(null),
|
||||
week3: new Array(7).fill(null),
|
||||
week4: new Array(7).fill(null),
|
||||
week5: new Array(7).fill(null),
|
||||
week6: new Array(7).fill(null)
|
||||
};
|
||||
|
||||
// The date of the first day in the overflow
|
||||
const monStartDay = endLastMonth - ISOToIndex.monday[startOfSelectedMonth];
|
||||
|
||||
let monCurrDate = set(subMonths(selectedDate, 1), {
|
||||
date: monStartDay
|
||||
});
|
||||
|
||||
for (const week in mondays) {
|
||||
const thisWeek = mondays[week];
|
||||
|
||||
thisWeek.forEach((e, i) => {
|
||||
const overflowInfo = isOverflow(selectedDate, monCurrDate);
|
||||
|
||||
const day: MonthDay = {
|
||||
...overflowInfo,
|
||||
date: monCurrDate.toJSON()
|
||||
};
|
||||
|
||||
monCurrDate = addDays(monCurrDate, 1);
|
||||
|
||||
mondays[week][i] = day;
|
||||
});
|
||||
}
|
||||
|
||||
const output = {
|
||||
sunday: {
|
||||
weekdays: weekDays.sunday,
|
||||
month: sundays
|
||||
},
|
||||
monday: {
|
||||
weekdays: weekDays.monday,
|
||||
month: mondays
|
||||
}
|
||||
};
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
export default populateMonth;
|
||||
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Function to convert the version string to a number tha represents the most recent major release.
|
||||
* @param {string }version The version string.
|
||||
* @returns {number} a number that represents the most recent major release.
|
||||
*/
|
||||
const versionStringToNumber = (version: string): number => {
|
||||
const versionStrArr: string[] = version.split(".");
|
||||
|
||||
const versionArr: number[] = versionStrArr.map((str) => parseInt(str));
|
||||
|
||||
if (versionArr[0] === 0 && versionArr[1] === 0 && versionArr[2] > 1) {
|
||||
versionArr[1] = 1;
|
||||
}
|
||||
|
||||
const versionStr = `${versionArr[0]}` + "." + `${versionArr[1]}`;
|
||||
|
||||
const versionNum: number = parseFloat(versionStr);
|
||||
|
||||
return versionNum;
|
||||
};
|
||||
|
||||
export default versionStringToNumber;
|
||||
2
next-env.d.ts
vendored
@@ -2,4 +2,4 @@
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
|
||||
9
next.config.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
experimental: {
|
||||
optimizePackageImports: ["@chakra-ui/react"]
|
||||
}
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
5405
package-lock.json
generated
Normal file
63
package.json
@@ -1,13 +1,15 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "lucid-creations-website",
|
||||
"homepage": "https://new.lucidcreations.media/",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"description": "This is a personal website that I have no specific goals for other than to have fun and share things that I want to.",
|
||||
"author": {
|
||||
"name": "Lucid Creations Media",
|
||||
"url": "https://lucidcreations.media",
|
||||
"email": "social@lucidcreations.media"
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
@@ -16,39 +18,32 @@
|
||||
"pretty": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@chakra-ui/react": "^2.8.2",
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@fontsource/anonymous-pro": "^5.0.12",
|
||||
"@fontsource/anybody": "^5.0.19",
|
||||
"@fontsource/kalam": "^5.0.12",
|
||||
"@fontsource/montserrat": "^5.0.17",
|
||||
"@fontsource/tilt-neon": "^5.0.4",
|
||||
"@iconify/react": "^4.1.1",
|
||||
"@reduxjs/toolkit": "^2.2.2",
|
||||
"date-fns": "^3.6.0",
|
||||
"formik": "^2.4.5",
|
||||
"framer-motion": "^11.0.20",
|
||||
"next": "14.1.4",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-redux": "^9.1.0",
|
||||
"sharp": "^0.33.3"
|
||||
"@chakra-ui/react": "^3.24.2",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"next": "15.4.6",
|
||||
"next-themes": "^0.4.6",
|
||||
"react": "^19.1.1",
|
||||
"react-dom": "^19.1.1",
|
||||
"react-icons": "^5.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.30",
|
||||
"@types/react": "^18.2.70",
|
||||
"@types/react-redux": "^7.1.33",
|
||||
"@typescript-eslint/eslint-plugin": "^7.4.0",
|
||||
"@typescript-eslint/parser": "^7.4.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-next": "<13.4.9",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
||||
"eslint-plugin-react": "^7.34.1",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"prettier": "^3.2.5",
|
||||
"typescript": "^5.4.3"
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "^9.33.0",
|
||||
"@types/node": "^24.2.1",
|
||||
"@types/react": "^19.1.9",
|
||||
"@types/react-dom": "^19.1.7",
|
||||
"@typescript-eslint/eslint-plugin": "^8.39.0",
|
||||
"@typescript-eslint/parser": "^8.39.0",
|
||||
"eslint": "^9.33.0",
|
||||
"eslint-config-next": "15.4.6",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
"eslint-plugin-prettier": "^5.5.4",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"prettier": "3.6.2",
|
||||
"typescript": "^5.9.2",
|
||||
"typescript-eslint": "^8.39.0"
|
||||
},
|
||||
"packageManager": "yarn@4.1.0"
|
||||
"packageManager": "yarn@4.9.2"
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,212 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="708px" height="708px" viewBox="0 0 708 708" enable-background="new 0 0 708 708" xml:space="preserve"> <image id="image0" width="708" height="708" x="0" y="0"
|
||||
xlink:href="data:image/png;base64,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" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 16 KiB |
BIN
public/images/logo/New Logo (transparent).png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
public/images/logo/favicon/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/images/logo/favicon/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
public/images/logo/favicon/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
public/images/logo/favicon/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 726 B |
BIN
public/images/logo/favicon/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
public/images/logo/favicon/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 18 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 565.83 767.39"><defs><style>.b{fill:#fff;}</style></defs><path class="b" d="M454.31,163.14h89.44L422.36,28.42v102.76c0,17.62,14.33,31.96,31.96,31.96Z"/><path class="b" d="M454.31,198.55c-37.15,0-67.38-30.22-67.38-67.37V.45C228.59,.15,103.31,0,33.48,0,15.02,0,0,15.02,0,33.47V733.33c0,18.45,15.02,33.47,33.48,33.47h43.41l.65,.58h455.76c.79-.17,1.72-.33,2.77-.42,15.49-1.33,28.18-14.13,29.57-29.78,.13-1.41,.2-2.66,.2-3.85V198.57l-111.52-.02Zm24.29,207.29c-1.99,1.95-4.25,3.65-6.55,5.24-11.81,8.13-22.84,17.18-33.09,27.21-6.32,6.18-12.28,12.69-17.99,19.43-6.27,7.41-10.84,15.71-14.08,24.9-7,19.92-17.49,37.98-30.25,54.73-14.72,19.32-27.55,39.83-38.81,61.33-3.17,6.06-6.35,12.09-10.69,17.44-9.67,11.92-22.08,19.36-37.12,22.21-12.18,2.31-23.48-.42-33.89-6.97-11.74-7.39-20.41-17.4-25.99-30.16-8.39-19.2-19.42-36.81-32.48-53.16-5.23-6.55-10.63-12.97-15.34-19.92-10.44-15.4-18.45-32-24.58-49.55-.97-2.78-1.94-5.57-3.07-8.29-.53-1.27-1.28-2.54-2.21-3.56-9.96-10.91-19.96-21.79-29.98-32.65-6.4-6.94-13.86-12.63-21.64-17.92-5.24-3.56-10.14-7.53-14.64-11.99-.13-.13-.23-.28-.4-.47,1.91-2.94,4.49-5.09,7.78-6.1,3.52-1.08,7.15-1.79,10.73-2.65,1.17-.28,2.35-.57,3.78-.91-2.36-1.55-4.47-2.96-6.6-4.35-2.75-1.8-5.54-3.54-8.25-5.39-.97-.66-1.87-1.46-2.63-2.35-1.54-1.81-1.43-3.73,.37-5.26,1.02-.87,2.22-1.61,3.45-2.17,5.4-2.47,10.84-4.84,16.27-7.26,.91-.4,1.8-.85,2.71-1.27,2.7-1.25,3.58-3.46,3.24-6.28-.33-2.71-.82-5.41-.99-8.13-.14-2.08-.08-4.21,.22-6.27,.77-5.37-.08-10.54-1.72-15.6-3.71-11.44-7.48-22.86-11.24-34.28-3.91-11.87-7.89-23.73-11.73-35.62-2.52-7.83-.76-15.02,4.12-21.39,3.86-5.05,10.09-6.27,15.57-3.02,3.08,1.83,5.88,4.23,8.51,6.68,15,14,31.31,26.21,48.93,36.7,11.56,6.89,23.54,12.94,35.86,18.32,1.98,.86,3.57,.62,5.29-.79,2.99-2.46,6.22-4.63,9.27-7.02,6.04-4.72,10.38-10.72,13.35-17.79,.92-2.19,2.15-4.31,3.57-6.21,2.98-3.98,7.21-5.43,12.07-5.29,3.96,.12,7.7,1.25,11.46,2.34,.45,.13,.91,.26,1.47,.42,.91-3.21,1.8-6.36,2.7-9.51,1.98-6.96,4.01-13.9,7.53-20.29,1.76-3.21,3.64-6.36,6.29-8.94,3.72-3.62,8.54-4.01,12.1-1.03,1.69,1.41,2.87,3.2,3.59,5.25,3.42,9.78,6.79,19.58,10.17,29.38,.28,.8,.5,1.62,.78,2.42,.75,2.12,1.55,2.49,3.71,1.92,2.1-.56,4.2-1.17,6.34-1.51,5.13-.84,9.95-.2,14,3.46,2.51,2.27,4.23,5.1,5.64,8.14,.87,1.87,1.64,3.8,2.58,5.63,2.12,4.15,5.21,7.43,9.26,9.74,3.11,1.77,5.25,4.49,7.38,7.24,.54,.7,1.06,1.42,1.63,2.1,1.56,1.85,2.95,2.28,5.2,1.34,3.64-1.52,7.27-3.1,10.85-4.76,28.71-13.33,54.57-30.89,77.67-52.52,1.72-1.61,3.53-3.17,5.48-4.48,6.33-4.21,13.53-2.95,18.19,3.06,4.08,5.26,5.41,11.28,4.11,17.67-1.28,6.28-3.04,12.47-4.72,18.66-3.59,13.22-7.52,26.33-12.9,38.94-2.4,5.63-5.16,11.11-7.87,16.59-1.25,2.53-1.37,5.17-1.38,7.87-.03,7.69-.06,15.37-.08,23.06,0,1.96,.69,2.85,2.73,3.69,5.73,2.37,11.45,4.74,17.17,7.14,1.36,.57,2.69,1.22,3.97,1.94,.89,.5,1.76,1.1,2.51,1.8,1.6,1.51,1.78,3.27,.34,4.92-1.08,1.23-2.38,2.33-3.74,3.25-4.2,2.82-8.48,5.52-12.73,8.27-.3,.19-.59,.41-1.04,.73,3.18,.73,6.19,1.4,9.18,2.12,3.56,.85,7.03,1.97,10.26,3.76,2.78,1.54,3.3,3.82,1.04,6.03Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 510 B |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 15 KiB |
@@ -1,23 +0,0 @@
|
||||
# Used for many other (non-commercial) purposes as well
|
||||
User-agent: CCBot
|
||||
Disallow: /
|
||||
|
||||
# For new training only
|
||||
User-agent: GPTBot
|
||||
Disallow: /
|
||||
|
||||
# Not for training, only for user requests
|
||||
User-agent: ChatGPT-User
|
||||
Disallow: /
|
||||
|
||||
# Marker for disabling Bard and Vertex AI
|
||||
User-agent: Google-Extended
|
||||
Disallow: /
|
||||
|
||||
# Speech synthesis only?
|
||||
User-agent: FacebookBot
|
||||
Disallow: /
|
||||
|
||||
# Multi-purpose, commercial uses; including LLMs
|
||||
User-agent: Omgilibot
|
||||
Disallow: /
|
||||
14
src/app/layout.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from "react";
|
||||
import { Provider } from "@/components/ui/provider";
|
||||
|
||||
export default function RootLayout(props: { children: React.ReactNode }) {
|
||||
const { children } = props;
|
||||
return (
|
||||
<html suppressHydrationWarning>
|
||||
<link rel="icon" href="/images/logo/favicon/favicon.ico" sizes="any" />
|
||||
<body>
|
||||
<Provider>{children}</Provider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
113
src/app/page.tsx
Normal file
@@ -0,0 +1,113 @@
|
||||
import { Button, Heading, HStack, Link, Text, VStack } from "@chakra-ui/react";
|
||||
import newLogo from "../../public/images/logo/New Logo (transparent).png";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<VStack
|
||||
w="100vw"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
spaceY={12}
|
||||
pt="5vh"
|
||||
pb="20vh"
|
||||
>
|
||||
<VStack spaceY={2}>
|
||||
<Image height={250} src={newLogo} alt="New LCM logo" />
|
||||
<Heading
|
||||
lineHeight="1"
|
||||
w="80vw"
|
||||
as="h1"
|
||||
color="cyan"
|
||||
fontSize="4rem"
|
||||
textAlign="center"
|
||||
>
|
||||
{"Lucid Creations Media Website"}
|
||||
</Heading>
|
||||
</VStack>
|
||||
|
||||
<VStack w="80vw" spaceY={2}>
|
||||
<Text w="100%" textAlign="left" fontSize="lg">
|
||||
{"The LCM website and eShop has been temporarily discontinued."}
|
||||
</Text>
|
||||
<Text w="100%" textAlign="left" fontSize="lg">
|
||||
{
|
||||
"Over the years there have been many external factors that interfered with my ability to dedicate time and find motivation to work on my creative passions. This includes erotica, streaming, hypno files, and more."
|
||||
}
|
||||
</Text>
|
||||
<Text w="100%" textAlign="left" fontSize="lg">
|
||||
{
|
||||
"It has also interfered with my ability to learn new skills such as music creation and digital art."
|
||||
}
|
||||
</Text>
|
||||
<Text w="100%" textAlign="left" fontSize="lg">
|
||||
{
|
||||
"Last year I faced a layoff and haven't been able to get back into my field. I can no longer afford the costs of hosting this website on it's current platform. The website generated no sales and thus I had to make the difficult decision to shut the site down for now."
|
||||
}
|
||||
</Text>
|
||||
<Text w="100%" textAlign="left" fontSize="lg">
|
||||
{
|
||||
'I have no time frame for when or if I will reopen the eShop. I do wish to at some point, on a more modern platform. I know that the next few months will be hell for me and I will have no time to dedicate to any of this. I will have to see how things are once I start getting more free time and if I can start working on a new website, "remastering" old hypno files, and making new ones for the relaunch.'
|
||||
}
|
||||
</Text>
|
||||
<Text w="100%" textAlign="left" fontSize="lg">
|
||||
{
|
||||
"Since LCM is not registered as an LLC yet I have been contemplating rebranding the company one last time. A few weeks before coming to this decision and making this page I was being pulled to shelf Kobold as Lucid's default form. I have been enjoying hearing/seeing everyone refer to me as wolf/werwolf so much that I might keep it this way. Just like when I changed my original fursona and alias it might be time to flip to a new chapter in my life."
|
||||
}
|
||||
</Text>
|
||||
<Text w="100%" textAlign="left" fontSize="lg">
|
||||
{
|
||||
'For a little while I was debating using "Kobold Kid", my new vanity domain name, as the new brand, but I have a new idea. I will sit on it for a few months before I make any decisions.'
|
||||
}
|
||||
</Text>
|
||||
<Text w="100%" textAlign="left" fontSize="lg">
|
||||
{
|
||||
"Another option I was considering is keeping Kobold as marketing/mascot, but I am not sure about it."
|
||||
}
|
||||
</Text>
|
||||
</VStack>
|
||||
|
||||
<VStack spaceY={6} w="80vw">
|
||||
<Heading as="h2" color="cyan" fontSize="2.5rem">
|
||||
{"Other LCM Resources"}
|
||||
</Heading>
|
||||
|
||||
<HStack gap="6" wrap="wrap">
|
||||
<Button variant="solid" bgColor="teal" fontSize="xl">
|
||||
<Link
|
||||
target="_blank"
|
||||
color="whiteAlpha.950"
|
||||
href="https://community.lucidcreations.media/"
|
||||
>
|
||||
{"The Cove"}
|
||||
</Link>
|
||||
</Button>
|
||||
<Button variant="solid" bgColor="teal" fontSize="xl">
|
||||
<Link
|
||||
target="_blank"
|
||||
color="whiteAlpha.950"
|
||||
href="https://vrchat.com/home/group/grp_781bbe4b-51ec-4025-a14f-cf23ced90507"
|
||||
>
|
||||
{"Dreamy Drove"}
|
||||
</Link>
|
||||
</Button>
|
||||
</HStack>
|
||||
<Heading as="h2" color="cyan" fontSize="2.5rem">
|
||||
{"Lucid's Socials"}
|
||||
</Heading>
|
||||
|
||||
<HStack gap="6" wrap="wrap">
|
||||
<Button variant="solid" bgColor="teal" fontSize="xl">
|
||||
<Link
|
||||
target="_blank"
|
||||
color="whiteAlpha.950"
|
||||
href="https://koboldkid.com/"
|
||||
>
|
||||
{"Kobold Kid Website"}
|
||||
</Link>
|
||||
</Button>
|
||||
</HStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from "react";
|
||||
import { Box, Link, Button, BoxProps, Text } from "@chakra-ui/react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
interface CustomButtonProps {
|
||||
text: string;
|
||||
link: string;
|
||||
type: "primary" | "secondary" | "footer";
|
||||
}
|
||||
|
||||
const MotionBox = motion<BoxProps>(Box);
|
||||
|
||||
const CustomButton = ({ text, link, type }: CustomButtonProps): JSX.Element => {
|
||||
return (
|
||||
<MotionBox whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }}>
|
||||
<Link href={link} target="_blank" rel="noopener">
|
||||
<Button variant={type}>
|
||||
<Text>{text}</Text>
|
||||
</Button>
|
||||
</Link>
|
||||
</MotionBox>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomButton;
|
||||
@@ -1,24 +0,0 @@
|
||||
import React from "react";
|
||||
import { Box, Link, Button, BoxProps, Text } from "@chakra-ui/react";
|
||||
import { Icon } from "@iconify/react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
const MotionBox = motion<BoxProps>(Box);
|
||||
|
||||
const GitHub = (): JSX.Element => {
|
||||
return (
|
||||
<MotionBox whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }}>
|
||||
<Link
|
||||
href="work/lcm/LucidCreationsWebsite/src/components/buttons/KoFi.tsx"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<Button variant="primary" leftIcon={<Icon icon="mdi:github" />}>
|
||||
<Text>{"View Codebase"}</Text>
|
||||
</Button>
|
||||
</Link>
|
||||
</MotionBox>
|
||||
);
|
||||
};
|
||||
|
||||
export default GitHub;
|
||||
@@ -1,24 +0,0 @@
|
||||
import React from "react";
|
||||
import { Box, Link, Button, BoxProps, Text } from "@chakra-ui/react";
|
||||
import { Icon } from "@iconify/react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
const MotionBox = motion<BoxProps>(Box);
|
||||
|
||||
const KoFi = (): JSX.Element => {
|
||||
return (
|
||||
<MotionBox whileHover={{ scale: 1.1 }} whileTap={{ scale: 0.9 }}>
|
||||
<Link
|
||||
href="https://ko-fi.com/lucidcreationsmedia"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<Button variant="kofi" leftIcon={<Icon icon="cib:ko-fi" />}>
|
||||
<Text>{"Fund The App"}</Text>
|
||||
</Button>
|
||||
</Link>
|
||||
</MotionBox>
|
||||
);
|
||||
};
|
||||
|
||||
export default KoFi;
|
||||
@@ -1,28 +0,0 @@
|
||||
export interface LinkObj {
|
||||
href?: string;
|
||||
name?: string;
|
||||
type: "primary" | "secondary" | "ko-fi" | "GitHub";
|
||||
}
|
||||
|
||||
type Links = LinkObj[];
|
||||
|
||||
const links: Links = [
|
||||
{
|
||||
href: "https://docs.google.com/document/d/1y1tbTG6TYoLMEde4XHzInByyHQ0T6Aw2RF6Y4Z7Yabs",
|
||||
name: "Roadmap and Progress",
|
||||
type: "secondary"
|
||||
},
|
||||
// {
|
||||
// type: "ko-fi"
|
||||
// },
|
||||
{
|
||||
href: "https://t.me/LucidCreationsMedia",
|
||||
name: "Dev Updates",
|
||||
type: "secondary"
|
||||
},
|
||||
{
|
||||
type: "GitHub"
|
||||
}
|
||||
];
|
||||
|
||||
export default links;
|
||||
@@ -1,77 +0,0 @@
|
||||
import React from "react";
|
||||
import { Box, HStack, VStack } from "@chakra-ui/react";
|
||||
import CustomButton from "./Custom";
|
||||
import links, { LinkObj } from "./data/links";
|
||||
import KoFi from "./KoFi";
|
||||
import GitHub from "./GitHub";
|
||||
|
||||
const Buttons = (): JSX.Element => {
|
||||
return (
|
||||
<Box h="auto" w="100%">
|
||||
<HStack
|
||||
display={{ base: "none", lg: "flex" }}
|
||||
h="auto"
|
||||
w="100%"
|
||||
justifyContent="center"
|
||||
alignContent="center"
|
||||
spacing={4}
|
||||
>
|
||||
{links.map((link: LinkObj) => {
|
||||
const { href, name, type } = link;
|
||||
|
||||
if (type === "primary" || type === "secondary") {
|
||||
return (
|
||||
<CustomButton
|
||||
key={name.replaceAll(" ", "-")}
|
||||
link={href}
|
||||
text={name}
|
||||
type={type}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (type === "ko-fi") {
|
||||
return <KoFi key={type} />;
|
||||
}
|
||||
|
||||
if (type === "GitHub") {
|
||||
return <GitHub key={type} />;
|
||||
}
|
||||
})}
|
||||
</HStack>
|
||||
<VStack
|
||||
display={{ base: "flex", lg: "none" }}
|
||||
h="auto"
|
||||
w="100%"
|
||||
justifyContent="center"
|
||||
alignContent="center"
|
||||
spacing={4}
|
||||
>
|
||||
{links.map((link: LinkObj) => {
|
||||
const { href, name, type } = link;
|
||||
|
||||
if (type === "primary" || type === "secondary") {
|
||||
return (
|
||||
<CustomButton
|
||||
key={name.replaceAll(" ", "-")}
|
||||
link={href}
|
||||
text={name}
|
||||
type={type}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (type === "ko-fi") {
|
||||
return <KoFi key={type} />;
|
||||
}
|
||||
|
||||
if (type === "GitHub") {
|
||||
return <GitHub key={type} />;
|
||||
}
|
||||
})}
|
||||
</VStack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Buttons;
|
||||
@@ -1,27 +0,0 @@
|
||||
import { Button, Heading, Text, Link, VStack } from "@chakra-ui/react";
|
||||
import React from "react";
|
||||
|
||||
const AboutProject = (): JSX.Element => {
|
||||
const description = `This project and website is a replacement for the current Lucid Creations Media Website. It is going to being designed to be faster, more user friendly, and better accessible compared to Wordpress. This platform is being built on React and Next.js`;
|
||||
|
||||
return (
|
||||
<VStack
|
||||
justifyContent="center"
|
||||
alignContent="center"
|
||||
w="100%"
|
||||
my="10"
|
||||
px={{ base: "5vw", md: "15vw", lg: "20vw", xl: "30vw" }}
|
||||
spacing="4"
|
||||
>
|
||||
<Heading w="100%">{"About This Website"}</Heading>
|
||||
<Text w="100%">{description}</Text>
|
||||
<Link href="htps://lucidcreations.media" target="_blank" rel="noopener">
|
||||
<Button type="button" variant="secondary">
|
||||
<Text>{"Visit the current website"}</Text>
|
||||
</Button>
|
||||
</Link>
|
||||
</VStack>
|
||||
);
|
||||
};
|
||||
|
||||
export default AboutProject;
|
||||
@@ -1,84 +0,0 @@
|
||||
import React from "react";
|
||||
import Image from "next/image";
|
||||
import { Flex, HStack, Text, VStack } from "@chakra-ui/react";
|
||||
import BrandText from "../../theme/components/BrandText";
|
||||
import { Icon } from "@iconify/react";
|
||||
import mp3SVG from "../../../public/images/mp3.svg";
|
||||
|
||||
const WhatIMakeBanner = (): JSX.Element => {
|
||||
return (
|
||||
<VStack
|
||||
bgColor="brand.cosmic"
|
||||
w="100%"
|
||||
alignContent="center"
|
||||
justifyContent="center"
|
||||
py="10"
|
||||
px={{ base: "0", lg: "5vw", "2xl": "10vw" }}
|
||||
>
|
||||
<VStack w="100%" alignContent="center" pb={{ base: "10", md: "6" }}>
|
||||
<BrandText type="Heading" headerLevel="h2" text={"What I Make"} />
|
||||
</VStack>
|
||||
<Flex
|
||||
w="100%"
|
||||
justifyContent="space-around"
|
||||
alignContent="center"
|
||||
direction={{ base: "column", md: "row" }}
|
||||
gap="5rem"
|
||||
>
|
||||
<VStack spacing="4" w="100%">
|
||||
<BrandText type="Heading" headerLevel="h3" text={"Communities"} />
|
||||
<VStack spacing="4" alignContent="start" justifyContent="center">
|
||||
<HStack spacing="4">
|
||||
<Text fontSize="5xl">
|
||||
<Icon icon="ic:baseline-discord" />
|
||||
</Text>
|
||||
<BrandText type="Text" size="xl" text={"Lucid's Cove"} />
|
||||
</HStack>
|
||||
<HStack spacing="4">
|
||||
<Text fontSize="5xl">
|
||||
<Icon icon="ic:baseline-telegram" />
|
||||
</Text>
|
||||
<BrandText type="Text" size="xl" text={"Lucid's Cove"} />
|
||||
</HStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
<VStack spacing="4" w="100%">
|
||||
<BrandText type="Heading" headerLevel="h3" text={"Content"} />
|
||||
<VStack spacing="4" alignContent="start" justifyContent="center">
|
||||
<HStack spacing="4" w="100%">
|
||||
<Text fontSize="5xl">
|
||||
<Icon icon="heroicons-solid:pencil" />
|
||||
</Text>
|
||||
<BrandText type="Text" size="xl" text={"Erotic Stories"} />
|
||||
</HStack>
|
||||
<HStack spacing="4" w="100%">
|
||||
<Text fontSize="5xl">
|
||||
<Image height="35" width="35" src={mp3SVG} alt="MP3 Icon" />
|
||||
</Text>
|
||||
<BrandText type="Text" size="xl" text={"Hypno Audio Files"} />
|
||||
</HStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
<VStack spacing="4" w="100%">
|
||||
<BrandText type="Heading" headerLevel="h3" text={"Streams"} />
|
||||
<VStack spacing="4" alignContent="start" justifyContent="center">
|
||||
<HStack spacing="4">
|
||||
<Text fontSize="5xl">
|
||||
<Icon icon="mdi:twitch" />
|
||||
</Text>
|
||||
<BrandText type="Text" size="xl" text={"LucidKobold"} />
|
||||
</HStack>
|
||||
<HStack spacing="4">
|
||||
<Text fontSize="5xl">
|
||||
<Icon icon="mdi:youtube" />
|
||||
</Text>
|
||||
<BrandText type="Text" size="xl" text={"LucidKobold"} />
|
||||
</HStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Flex>
|
||||
</VStack>
|
||||
);
|
||||
};
|
||||
|
||||
export default WhatIMakeBanner;
|
||||
@@ -1,32 +0,0 @@
|
||||
import { Heading, VStack } from "@chakra-ui/react";
|
||||
import React from "react";
|
||||
import WhatIMakeBanner from "./WhatIMakeBanner";
|
||||
import AboutProject from "./AboutProject";
|
||||
|
||||
const TempHero = (): JSX.Element => {
|
||||
return (
|
||||
<VStack
|
||||
bg="brand.content"
|
||||
h="100%"
|
||||
w="100%"
|
||||
spacing="0"
|
||||
justifyContent="center"
|
||||
alignContent="center"
|
||||
>
|
||||
<WhatIMakeBanner />
|
||||
<AboutProject />
|
||||
<VStack
|
||||
w="100%"
|
||||
h="36.3vh"
|
||||
justifyContent="space-around"
|
||||
alignContent="center"
|
||||
>
|
||||
<Heading size="3xl" as="h2">
|
||||
{"Placeholder section"}
|
||||
</Heading>
|
||||
</VStack>
|
||||
</VStack>
|
||||
);
|
||||
};
|
||||
|
||||
export default TempHero;
|
||||
@@ -1,37 +0,0 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Box,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalContent,
|
||||
ModalOverlay
|
||||
} from "@chakra-ui/react";
|
||||
import LoadingSpinner from "./LoadingSpinner";
|
||||
|
||||
const LoadingOverlay = (): JSX.Element => {
|
||||
return (
|
||||
<Modal
|
||||
isCentered
|
||||
isOpen
|
||||
onClose={() => null}
|
||||
motionPreset="slideInBottom"
|
||||
scrollBehavior="inside"
|
||||
size="xs"
|
||||
>
|
||||
<ModalOverlay bg="loading.overlayBg" />
|
||||
<ModalContent bg="transparent" boxShadow="none">
|
||||
{/* <ModalHeader>
|
||||
</ModalHeader> */}
|
||||
<ModalBody border="0px">
|
||||
<Box h="100%" w="100%" textAlign="center">
|
||||
<LoadingSpinner />
|
||||
</Box>
|
||||
</ModalBody>
|
||||
{/* <ModalFooter>
|
||||
</ModalFooter> */}
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoadingOverlay;
|
||||
@@ -1,16 +0,0 @@
|
||||
import React from "react";
|
||||
import { Spinner } from "@chakra-ui/react";
|
||||
|
||||
const LoadingSpinner = (): JSX.Element => {
|
||||
return (
|
||||
<Spinner
|
||||
thickness="4px"
|
||||
speed="0.50s"
|
||||
emptyColor="loading.spinnerEmptySpace"
|
||||
color="loading.spinnerColor"
|
||||
size="xl"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoadingSpinner;
|
||||
111
src/components/ui/color-mode.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
||||
/* eslint-disable prettier/prettier */
|
||||
/* eslint-disable no-unused-vars */
|
||||
"use client";
|
||||
|
||||
import type { IconButtonProps, SpanProps } from "@chakra-ui/react";
|
||||
import { ClientOnly, IconButton, Skeleton, Span } from "@chakra-ui/react";
|
||||
import { ThemeProvider, useTheme } from "next-themes";
|
||||
import type { ThemeProviderProps } from "next-themes";
|
||||
import * as React from "react";
|
||||
import { LuMoon, LuSun } from "react-icons/lu";
|
||||
|
||||
export interface ColorModeProviderProps extends ThemeProviderProps { }
|
||||
|
||||
export function ColorModeProvider(props: ColorModeProviderProps) {
|
||||
return (
|
||||
<ThemeProvider attribute="class" disableTransitionOnChange {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
export type ColorMode = "light" | "dark";
|
||||
|
||||
export interface UseColorModeReturn {
|
||||
colorMode: ColorMode;
|
||||
setColorMode: (colorMode: ColorMode) => void;
|
||||
toggleColorMode: () => void;
|
||||
}
|
||||
|
||||
export function useColorMode(): UseColorModeReturn {
|
||||
const { resolvedTheme, setTheme, forcedTheme } = useTheme();
|
||||
const colorMode = forcedTheme || resolvedTheme;
|
||||
const toggleColorMode = () => {
|
||||
setTheme(resolvedTheme === "dark" ? "light" : "dark");
|
||||
};
|
||||
return {
|
||||
colorMode: colorMode as ColorMode,
|
||||
setColorMode: setTheme,
|
||||
toggleColorMode
|
||||
};
|
||||
}
|
||||
|
||||
export function useColorModeValue<T>(light: T, dark: T) {
|
||||
const { colorMode } = useColorMode();
|
||||
return colorMode === "dark" ? dark : light;
|
||||
}
|
||||
|
||||
export function ColorModeIcon() {
|
||||
const { colorMode } = useColorMode();
|
||||
return colorMode === "dark" ? <LuMoon /> : <LuSun />;
|
||||
}
|
||||
|
||||
interface ColorModeButtonProps extends Omit<IconButtonProps, "aria-label"> { }
|
||||
|
||||
export const ColorModeButton = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
ColorModeButtonProps
|
||||
>(function ColorModeButton(props, ref) {
|
||||
const { toggleColorMode } = useColorMode();
|
||||
return (
|
||||
<ClientOnly fallback={<Skeleton boxSize="8" />}>
|
||||
<IconButton
|
||||
onClick={toggleColorMode}
|
||||
variant="ghost"
|
||||
aria-label="Toggle color mode"
|
||||
size="sm"
|
||||
ref={ref}
|
||||
{...props}
|
||||
css={{
|
||||
_icon: {
|
||||
width: "5",
|
||||
height: "5"
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ColorModeIcon />
|
||||
</IconButton>
|
||||
</ClientOnly>
|
||||
);
|
||||
});
|
||||
|
||||
export const LightMode = React.forwardRef<HTMLSpanElement, SpanProps>(
|
||||
function LightMode(props, ref) {
|
||||
return (
|
||||
<Span
|
||||
color="fg"
|
||||
display="contents"
|
||||
className="chakra-theme light"
|
||||
colorPalette="gray"
|
||||
colorScheme="light"
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const DarkMode = React.forwardRef<HTMLSpanElement, SpanProps>(
|
||||
function DarkMode(props, ref) {
|
||||
return (
|
||||
<Span
|
||||
color="fg"
|
||||
display="contents"
|
||||
className="chakra-theme dark"
|
||||
colorPalette="gray"
|
||||
colorScheme="dark"
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
12
src/components/ui/provider.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { ChakraProvider, defaultSystem } from "@chakra-ui/react";
|
||||
import { ColorModeProvider, type ColorModeProviderProps } from "./color-mode";
|
||||
|
||||
export function Provider(props: ColorModeProviderProps) {
|
||||
return (
|
||||
<ChakraProvider value={defaultSystem}>
|
||||
<ColorModeProvider {...props} />
|
||||
</ChakraProvider>
|
||||
);
|
||||
}
|
||||
43
src/components/ui/toaster.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Toaster as ChakraToaster,
|
||||
Portal,
|
||||
Spinner,
|
||||
Stack,
|
||||
Toast,
|
||||
createToaster
|
||||
} from "@chakra-ui/react";
|
||||
|
||||
export const toaster = createToaster({
|
||||
placement: "bottom-end",
|
||||
pauseOnPageIdle: true
|
||||
});
|
||||
|
||||
export const Toaster = () => {
|
||||
return (
|
||||
<Portal>
|
||||
<ChakraToaster toaster={toaster} insetInline={{ mdDown: "4" }}>
|
||||
{(toast) => (
|
||||
<Toast.Root width={{ md: "sm" }}>
|
||||
{toast.type === "loading" ? (
|
||||
<Spinner size="sm" color="blue.solid" />
|
||||
) : (
|
||||
<Toast.Indicator />
|
||||
)}
|
||||
<Stack gap="1" flex="1" maxWidth="100%">
|
||||
{toast.title && <Toast.Title>{toast.title}</Toast.Title>}
|
||||
{toast.description && (
|
||||
<Toast.Description>{toast.description}</Toast.Description>
|
||||
)}
|
||||
</Stack>
|
||||
{toast.action && (
|
||||
<Toast.ActionTrigger>{toast.action.label}</Toast.ActionTrigger>
|
||||
)}
|
||||
{toast.closable && <Toast.CloseTrigger />}
|
||||
</Toast.Root>
|
||||
)}
|
||||
</ChakraToaster>
|
||||
</Portal>
|
||||
);
|
||||
};
|
||||
46
src/components/ui/tooltip.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { Tooltip as ChakraTooltip, Portal } from "@chakra-ui/react";
|
||||
import * as React from "react";
|
||||
|
||||
export interface TooltipProps extends ChakraTooltip.RootProps {
|
||||
showArrow?: boolean;
|
||||
portalled?: boolean;
|
||||
portalRef?: React.RefObject<HTMLElement>;
|
||||
content: React.ReactNode;
|
||||
contentProps?: ChakraTooltip.ContentProps;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
|
||||
function Tooltip(props, ref) {
|
||||
const {
|
||||
showArrow,
|
||||
children,
|
||||
disabled,
|
||||
portalled = true,
|
||||
content,
|
||||
contentProps,
|
||||
portalRef,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
if (disabled) return children;
|
||||
|
||||
return (
|
||||
<ChakraTooltip.Root {...rest}>
|
||||
<ChakraTooltip.Trigger asChild>{children}</ChakraTooltip.Trigger>
|
||||
<Portal disabled={!portalled} container={portalRef}>
|
||||
<ChakraTooltip.Positioner>
|
||||
<ChakraTooltip.Content ref={ref} {...contentProps}>
|
||||
{showArrow && (
|
||||
<ChakraTooltip.Arrow>
|
||||
<ChakraTooltip.ArrowTip />
|
||||
</ChakraTooltip.Arrow>
|
||||
)}
|
||||
{content}
|
||||
</ChakraTooltip.Content>
|
||||
</ChakraTooltip.Positioner>
|
||||
</Portal>
|
||||
</ChakraTooltip.Root>
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -1,66 +0,0 @@
|
||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { format } from "date-fns";
|
||||
import populate from "../../../lib/populateMonth";
|
||||
|
||||
interface CalenderSlice {
|
||||
currDate: string;
|
||||
selectedDateInfo: SelectedDateInfo;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
const getCurrDate = (): Date => new Date();
|
||||
const dateParse = (date: Date) => date.toJSON();
|
||||
const dateFormatter = (date: Date): string => format(date, "LLLL uuuu");
|
||||
|
||||
const initialState: CalenderSlice = {
|
||||
currDate: dateParse(getCurrDate()),
|
||||
selectedDateInfo: {
|
||||
date: dateParse(getCurrDate()),
|
||||
title: dateFormatter(getCurrDate()),
|
||||
layout: populate(getCurrDate())
|
||||
},
|
||||
isLoading: true
|
||||
};
|
||||
|
||||
// TODO: Add a function that validated if a month has at least one sticker in it. Use that within the nav function (when filter is enabled).
|
||||
|
||||
// TODO: Add a function that will give the closest date, if available, when the nav func detects an empty month.
|
||||
// Use the chart creation date to aid with this. (When filter is enabled)
|
||||
|
||||
/**
|
||||
* TODO: Add logic that prevents navigation to the future and too far in the past. (Use chart creation date)
|
||||
* Update to use a promise and return appropriate errors. Display those errors on the front end.
|
||||
* Update the use of this function on the front to handle the fails of the promise.
|
||||
*/
|
||||
|
||||
// TODO: (When filter is enabled) Update the calender update function that will take in a direction so that the the navigation buttons will take the user to the next month with stickers. Assuming there was a gap with empty months.
|
||||
|
||||
const calenderSlice = createSlice({
|
||||
name: "Calender",
|
||||
initialState,
|
||||
reducers: {
|
||||
// Update month info
|
||||
updateMonth(state: CalenderSlice, action: PayloadAction<string>) {
|
||||
const { payload } = action;
|
||||
|
||||
const toDateObj: Date = new Date(payload);
|
||||
|
||||
state.selectedDateInfo.date = payload;
|
||||
state.selectedDateInfo.title = dateFormatter(toDateObj);
|
||||
state.selectedDateInfo.layout = populate(toDateObj);
|
||||
},
|
||||
// Update current date
|
||||
updateCurrDate(state: CalenderSlice) {
|
||||
state.currDate = dateParse(new Date());
|
||||
},
|
||||
// Update isLoading
|
||||
updateLoading(state: CalenderSlice, action: PayloadAction<boolean>) {
|
||||
const { payload } = action;
|
||||
state.isLoading = payload;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const { updateMonth, updateCurrDate, updateLoading } =
|
||||
calenderSlice.actions;
|
||||
export default calenderSlice.reducer;
|
||||
@@ -1,62 +0,0 @@
|
||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { format, getDate, isSameDay } from "date-fns";
|
||||
import stickersSeeder from "../../../data/stickerSeeder";
|
||||
|
||||
interface StickersSlice {
|
||||
stickersMonth: StickerDays;
|
||||
}
|
||||
|
||||
interface UpdateStickerSlicePayload {
|
||||
stickerDate: string;
|
||||
sticker: StickerVal;
|
||||
}
|
||||
|
||||
const initialState: StickersSlice = {
|
||||
stickersMonth: stickersSeeder()
|
||||
};
|
||||
|
||||
const stickersSlice = createSlice({
|
||||
name: "Stickers",
|
||||
initialState,
|
||||
reducers: {
|
||||
addEditSticker(
|
||||
state: StickersSlice,
|
||||
actions: PayloadAction<UpdateStickerSlicePayload>
|
||||
) {
|
||||
const { stickerDate, sticker } = actions.payload;
|
||||
|
||||
const dateObj = new Date(stickerDate);
|
||||
|
||||
// Getting index for the stickers array, sticker from the stickers array, and the date from the sticker.
|
||||
const index: number = getDate(dateObj) - 1;
|
||||
const currSticker: Sticker = state.stickersMonth[index];
|
||||
|
||||
// Updating the edited status by checking if the sticker date is today's date.
|
||||
const edited = currSticker.edited
|
||||
? true
|
||||
: isSameDay(new Date(stickerDate), new Date())
|
||||
? false
|
||||
: true;
|
||||
currSticker.edited = edited;
|
||||
|
||||
// TODO: Add manually added here.
|
||||
|
||||
// Updating the id of the sticker.
|
||||
const id = format(dateObj, "yyyyddLL") + sticker;
|
||||
|
||||
// Updating the information of the sticker.
|
||||
const newSticker: Sticker = {
|
||||
id: id,
|
||||
date: stickerDate,
|
||||
sticker: sticker,
|
||||
edited: edited,
|
||||
manual: false
|
||||
};
|
||||
|
||||
state.stickersMonth[index] = newSticker;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const { addEditSticker } = stickersSlice.actions;
|
||||
export default stickersSlice.reducer;
|
||||
@@ -1,140 +0,0 @@
|
||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { addMonths, endOfDay } from "date-fns";
|
||||
import versionStringToNumber from "../../../lib/versionStringToNumber";
|
||||
|
||||
export interface StorageState {
|
||||
exp: string;
|
||||
version: number;
|
||||
completed: boolean;
|
||||
}
|
||||
|
||||
const endOfToday: Date = endOfDay(new Date());
|
||||
|
||||
const generateExpDate = (): string => {
|
||||
return endOfDay(addMonths(endOfToday, 1)).toJSON();
|
||||
};
|
||||
|
||||
const generateVersion = (): number => {
|
||||
const versionStr: string = process.env.NEXT_PUBLIC_APP_VERSION;
|
||||
|
||||
return versionStringToNumber(versionStr);
|
||||
};
|
||||
|
||||
// * Storage Helpers * //
|
||||
|
||||
const setTempStorage = (storageState: StorageState): void => {
|
||||
sessionStorage.setItem("completedTutorial", JSON.stringify(storageState));
|
||||
};
|
||||
|
||||
const getTempStorage = (): StorageState | null => {
|
||||
return JSON.parse(sessionStorage.getItem("completedTutorial"));
|
||||
};
|
||||
|
||||
const clearTempStorage = (): void => {
|
||||
sessionStorage.removeItem("completedTutorial");
|
||||
};
|
||||
|
||||
const setStorage = (storageState: StorageState): void => {
|
||||
localStorage.setItem("completedTutorial", JSON.stringify(storageState));
|
||||
};
|
||||
|
||||
const getStorage = (): StorageState | null => {
|
||||
return JSON.parse(localStorage.getItem("completedTutorial"));
|
||||
};
|
||||
|
||||
const clearStorage = (): void => {
|
||||
localStorage.removeItem("completedTutorial");
|
||||
};
|
||||
|
||||
interface TutorialSlice {
|
||||
completedTutorial: boolean | null;
|
||||
storageState: StorageState | null;
|
||||
rememberCompleted: boolean;
|
||||
currWeek: MonthDay[] | null;
|
||||
}
|
||||
|
||||
const initialState: TutorialSlice = {
|
||||
completedTutorial: null,
|
||||
storageState: null,
|
||||
rememberCompleted: false,
|
||||
currWeek: null
|
||||
};
|
||||
|
||||
const tutorialSlice = createSlice({
|
||||
name: "Tutorial",
|
||||
initialState,
|
||||
reducers: {
|
||||
// Set temp complete
|
||||
setTempTutorialComplete(state: TutorialSlice) {
|
||||
const exp: string = generateExpDate();
|
||||
const version: number = generateVersion();
|
||||
const storageState: StorageState = {
|
||||
exp,
|
||||
version,
|
||||
completed: true
|
||||
};
|
||||
|
||||
setTempStorage(storageState);
|
||||
state.storageState = storageState;
|
||||
state.completedTutorial = true;
|
||||
},
|
||||
// Set completed (remember)
|
||||
setTutorialCompleted(state: TutorialSlice) {
|
||||
const exp: string = generateExpDate();
|
||||
const version: number = generateVersion();
|
||||
const storageState: StorageState = {
|
||||
exp,
|
||||
version,
|
||||
completed: true
|
||||
};
|
||||
|
||||
setStorage(storageState);
|
||||
state.storageState = storageState;
|
||||
state.completedTutorial = true;
|
||||
},
|
||||
// Clear states and storages
|
||||
clearTutorialCompleted(state: TutorialSlice) {
|
||||
clearTempStorage();
|
||||
clearStorage();
|
||||
state.storageState = null;
|
||||
state.completedTutorial = null;
|
||||
},
|
||||
// Get and set states
|
||||
getAndSetTutorial(state: TutorialSlice) {
|
||||
const temp = getTempStorage();
|
||||
const local = getStorage();
|
||||
|
||||
if (temp !== null || local !== null) {
|
||||
state.storageState = temp !== null ? temp : local;
|
||||
state.completedTutorial =
|
||||
temp !== null ? temp.completed : local.completed;
|
||||
}
|
||||
|
||||
if (temp === null && local === null) {
|
||||
state.completedTutorial = false;
|
||||
}
|
||||
},
|
||||
// Toggle remember completed
|
||||
toggleRememberCompleted(state: TutorialSlice) {
|
||||
const { rememberCompleted } = state;
|
||||
|
||||
state.rememberCompleted = !rememberCompleted;
|
||||
},
|
||||
// Set current week
|
||||
setCurrentWeek(state: TutorialSlice, action: PayloadAction<MonthDay[]>) {
|
||||
const { payload } = action;
|
||||
|
||||
state.currWeek = payload;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const {
|
||||
setTempTutorialComplete,
|
||||
setTutorialCompleted,
|
||||
clearTutorialCompleted,
|
||||
getAndSetTutorial,
|
||||
toggleRememberCompleted,
|
||||
setCurrentWeek
|
||||
} = tutorialSlice.actions;
|
||||
export default tutorialSlice.reducer;
|
||||
@@ -1,37 +0,0 @@
|
||||
import "@fontsource/montserrat/500.css";
|
||||
import "@fontsource/tilt-neon/400.css";
|
||||
import "@fontsource/anonymous-pro/400.css";
|
||||
import "@fontsource/kalam/400.css";
|
||||
import "@fontsource/anybody/400.css";
|
||||
|
||||
import type { AppProps } from "next/app";
|
||||
import React from "react";
|
||||
import { ChakraProvider } from "@chakra-ui/react";
|
||||
import AppTheme from "../theme/AppTheme";
|
||||
import { Provider } from "react-redux";
|
||||
import { store } from "../redux/store";
|
||||
import Layout from "../theme/layout/Layout";
|
||||
import Head from "next/head";
|
||||
|
||||
function LCMPottyChart({ Component, pageProps }: AppProps): JSX.Element {
|
||||
return (
|
||||
<React.StrictMode>
|
||||
<ChakraProvider theme={AppTheme}>
|
||||
<Layout {...pageProps}>
|
||||
<Head>
|
||||
<title>{"LCM Website"}</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, user-scalable=yes, initial-scale=1.0"
|
||||
/>
|
||||
</Head>
|
||||
<Provider store={store}>
|
||||
<Component {...pageProps} />
|
||||
</Provider>
|
||||
</Layout>
|
||||
</ChakraProvider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
}
|
||||
|
||||
export default LCMPottyChart;
|
||||
@@ -1,56 +0,0 @@
|
||||
import NextDocument, { Html, Head, Main, NextScript } from "next/document";
|
||||
import React from "react";
|
||||
import { ColorModeScript } from "@chakra-ui/react";
|
||||
import AppTheme from "../theme/AppTheme";
|
||||
|
||||
const description =
|
||||
"Official website for Lucid Creations Media. Where you can back us, donate to us, and purchase our official content such as hypno audio files.";
|
||||
|
||||
const logo = "images/logo.svg";
|
||||
const logoOG = "/images/logo.png";
|
||||
|
||||
class Document extends NextDocument {
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<Html>
|
||||
<Head>
|
||||
<meta name="theme-color" content="#3138dc" />
|
||||
<link rel="icon" href={logo} sizes="32x32 192x192" />
|
||||
<link rel="apple-touch-icon" href={logo} />
|
||||
<meta property="og:title" content="Lucid Creations Media Website" />
|
||||
<meta name="og:description" content={description} />
|
||||
<meta property="og:type" content="eCommerce" />
|
||||
<meta property="og:image" content={logoOG} />
|
||||
<meta property="og:image:type" content="image/png" />
|
||||
<meta property="og:image:alt" content="Lucid Creations Media Logo" />
|
||||
<meta property="og:url" content="https://lucidcreations.media" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta property="title" content="Lucid Creations Media Website" />
|
||||
<meta name="description" content={description} />
|
||||
<meta property="type" content="eCommerce" />
|
||||
<meta property="image" content={logoOG} />
|
||||
<meta property="image:type" content="image/png" />
|
||||
<meta property="image:alt" content="Lucid Creations Media Logo" />
|
||||
<meta property="url" content="https://https://lucidcreations.media" />
|
||||
<meta httpEquiv="content-language" content="en_US" />
|
||||
<meta charSet="UTF-8" />
|
||||
<meta name="keywords" content={description} />
|
||||
<meta name="copyright" content="Lucid Creations Media" />
|
||||
<meta name="page-topic" content="eCommerce" />
|
||||
<meta name="audience" content="E" />
|
||||
<meta name="robots" content="index, follow" />
|
||||
</Head>
|
||||
<html lang="en" />
|
||||
<body>
|
||||
<ColorModeScript
|
||||
initialColorMode={AppTheme.config.initialColorMode}
|
||||
/>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Document;
|
||||
@@ -1,17 +0,0 @@
|
||||
import React from "react";
|
||||
import { Provider } from "react-redux";
|
||||
import { store } from "../redux/store";
|
||||
import { Box } from "@chakra-ui/react";
|
||||
import TempHero from "../components/hero";
|
||||
|
||||
const IndexPage = (): JSX.Element => {
|
||||
return (
|
||||
<Box textAlign="center" w="100%" h="auto" pt="50px" minWidth="min-content">
|
||||
<Provider store={store}>
|
||||
<TempHero />
|
||||
</Provider>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default IndexPage;
|
||||
@@ -1,5 +0,0 @@
|
||||
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
|
||||
import { RootState, AppDispatch } from "./store";
|
||||
|
||||
export const useAppDispatch = () => useDispatch<AppDispatch>();
|
||||
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|
||||
@@ -1,15 +0,0 @@
|
||||
import { configureStore } from "@reduxjs/toolkit";
|
||||
import calenderReducer from "../features/calender";
|
||||
import stickersReducer from "../features/calender/stickers";
|
||||
import tutorialReducer from "../features/tutorial";
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
calender: calenderReducer,
|
||||
stickers: stickersReducer,
|
||||
tutorial: tutorialReducer
|
||||
}
|
||||
});
|
||||
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
@@ -1,69 +0,0 @@
|
||||
import { extendTheme, ThemeConfig } from "@chakra-ui/react";
|
||||
// import { createBreakpoints } from "@chakra-ui/theme-tools";
|
||||
import "@fontsource/montserrat";
|
||||
import "@fontsource/tilt-neon";
|
||||
import "@fontsource/anonymous-pro";
|
||||
import "@fontsource/kalam";
|
||||
import "@fontsource/anybody";
|
||||
import buttons from "./components/buttonStyles";
|
||||
|
||||
const config: ThemeConfig = {
|
||||
initialColorMode: "dark",
|
||||
useSystemColorMode: false
|
||||
};
|
||||
|
||||
// const breakpoints = createBreakpoints({
|
||||
// sm: "30em",
|
||||
// md: "48em",
|
||||
// lg: "75em",
|
||||
// xl: "85em",
|
||||
// "2xl": "100em",
|
||||
// });
|
||||
|
||||
const fonts = {
|
||||
heading: `'Tilt Neon', system-ui`,
|
||||
body: `'Montserrat', sans-serif`,
|
||||
mono: `'Anonymous Pro', monospace`,
|
||||
brand: `'Kalam', cursive`,
|
||||
LCM: `'Anybody', system-ui`
|
||||
};
|
||||
|
||||
const AppTheme = extendTheme({
|
||||
config,
|
||||
colors: {
|
||||
brand: {
|
||||
main: "#3138dc",
|
||||
primary: "#0068ff",
|
||||
secondary: "#0086ff",
|
||||
cosmic: "#314a9e",
|
||||
hover: "#00aec1",
|
||||
warning: "#ffbd48",
|
||||
danger: "#FC8181",
|
||||
valid: "#00c17c",
|
||||
footer: "#0097a7",
|
||||
footerText: "black",
|
||||
content: "#2d3748",
|
||||
kofi: "#FF5E5B"
|
||||
},
|
||||
loading: {
|
||||
overlayBg: "#171923cb",
|
||||
spinnerColor: "#0088ff",
|
||||
spinnerEmptySpace: "#2D374860"
|
||||
}
|
||||
},
|
||||
styles: {
|
||||
global: {
|
||||
body: {
|
||||
bg: "gray.900"
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Button: buttons
|
||||
},
|
||||
fonts
|
||||
// breakpoints,
|
||||
});
|
||||
|
||||
export default AppTheme;
|
||||
export { fonts };
|
||||
@@ -1,29 +0,0 @@
|
||||
import { Heading, Text } from "@chakra-ui/react";
|
||||
import React from "react";
|
||||
import { fonts } from "../AppTheme";
|
||||
|
||||
interface BrandTextProps {
|
||||
type: "Heading" | "Text";
|
||||
text: string;
|
||||
headerLevel?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
||||
size?: string;
|
||||
}
|
||||
|
||||
const BrandText = ({
|
||||
type,
|
||||
text,
|
||||
headerLevel,
|
||||
size
|
||||
}: BrandTextProps): JSX.Element => {
|
||||
return type === "Heading" ? (
|
||||
<Heading fontFamily={fonts.brand} fontSize={size} as={headerLevel}>
|
||||
{text}
|
||||
</Heading>
|
||||
) : (
|
||||
<Text fontFamily={fonts.brand} fontSize={size}>
|
||||
{text}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
export default BrandText;
|
||||
@@ -1,177 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import { darken, mode, whiten } from "@chakra-ui/theme-tools";
|
||||
import { Dict } from "@chakra-ui/utils";
|
||||
|
||||
const buttonStyles = {
|
||||
// style object for base or default style
|
||||
baseStyle: {},
|
||||
// styles for different sizes ("sm", "md", "lg")
|
||||
sizes: {},
|
||||
// styles for different visual variants ("outline", "solid")
|
||||
variants: {
|
||||
primary: (props: Dict<never>) => ({
|
||||
bg: "brand.primary",
|
||||
fontSize: "xl",
|
||||
py: 3,
|
||||
px: 4,
|
||||
color: "whiteAlpha",
|
||||
_hover: {
|
||||
bg: mode(
|
||||
whiten("brand.primary", 20),
|
||||
darken("brand.primary", 20)
|
||||
)(props)
|
||||
}
|
||||
}),
|
||||
secondary: (props: Dict<never>) => ({
|
||||
bg: "brand.secondary",
|
||||
fontSize: "xl",
|
||||
py: 3,
|
||||
px: 4,
|
||||
color: "whiteAlpha",
|
||||
_hover: {
|
||||
bg: mode(
|
||||
whiten("brand.secondary", 20),
|
||||
darken("brand.secondary", 20)
|
||||
)(props)
|
||||
}
|
||||
}),
|
||||
skip: (props: Dict<never>) => ({
|
||||
bg: "transparent",
|
||||
fontSize: "xl",
|
||||
py: 3,
|
||||
px: 4,
|
||||
color: "whiteAlpha.800",
|
||||
_hover: {
|
||||
bg: mode(whiten("brand.danger", 20), darken("brand.danger", 20))(props),
|
||||
color: "whiteAlpha.900"
|
||||
}
|
||||
}),
|
||||
stickerButton: (props: Dict<never>) => ({
|
||||
bg: "transparent",
|
||||
fontSize: "4rem",
|
||||
px: 2,
|
||||
py: 14,
|
||||
_hover: {
|
||||
bg: mode(
|
||||
whiten("brand.secondary", 20),
|
||||
darken("brand.secondary", 20)
|
||||
)(props)
|
||||
}
|
||||
}),
|
||||
nav: (props: Dict<never>) => ({
|
||||
bg: "transparent",
|
||||
fontSize: "md",
|
||||
px: 2,
|
||||
_hover: {
|
||||
bg: mode(
|
||||
whiten("brand.secondary", 20),
|
||||
darken("brand.secondary", 20)
|
||||
)(props)
|
||||
}
|
||||
}),
|
||||
stickyNav: (/* props: Dict<never> | StyleFunctionProps */) => ({
|
||||
bg: "transparent",
|
||||
fontSize: "md",
|
||||
px: 2,
|
||||
_hover: {
|
||||
textDecoration: "underline"
|
||||
}
|
||||
}),
|
||||
footer: (props: Dict<never>) => ({
|
||||
bg: "brand.main",
|
||||
fontSize: "lg",
|
||||
py: 3,
|
||||
px: 4,
|
||||
color: "whiteAlpha",
|
||||
_hover: {
|
||||
bg: mode(whiten("brand.main", 20), darken("brand.main", 20))(props)
|
||||
}
|
||||
}),
|
||||
backToTop: (props: Dict<never>) => ({
|
||||
bg: "rgba(23, 25, 35, 0.5)",
|
||||
fontSize: "lg",
|
||||
py: 2,
|
||||
px: 4,
|
||||
color: "rgba(0, 134, 255, 0.6)",
|
||||
boxShadow:
|
||||
"rgba(0, 134, 255, 0.05) 0px 0px 15px, rgba(0, 134, 255, 0.1) 0px 0px 3px 1px",
|
||||
border: "1px solid rgba(0, 134, 255, 0.15)",
|
||||
_hover: {
|
||||
bg: mode(
|
||||
whiten("brand.secondary", 20),
|
||||
darken("brand.secondary", 20)
|
||||
)(props),
|
||||
boxShadow:
|
||||
"rgba(0, 104, 255, 0.5) 0px 0px 15px, rgba(0, 104, 255, 0.3) 0px 0px 3px 1px",
|
||||
color: "whiteAlpha.900",
|
||||
border: "1px solid rgba(0, 134, 255, 1)"
|
||||
}
|
||||
}),
|
||||
submit: (props: Dict<never>) => ({
|
||||
fontSize: "lg",
|
||||
py: 2,
|
||||
px: 4,
|
||||
type: "submit",
|
||||
_hover: {
|
||||
color: "whiteAlpha.900",
|
||||
bg: mode(whiten("brand.valid", 20), darken("brand.valid", 20))(props),
|
||||
_disabled: {
|
||||
color: mode(
|
||||
whiten("brand.danger", 20),
|
||||
darken("brand.danger", 20)
|
||||
)(props),
|
||||
boxShadow:
|
||||
"rgba(252, 129, 129, .95) 0px 0px 15px, rgba(252, 129, 129, 0.75) 0px 0px 3px 1px",
|
||||
border: "1px solid #FC8181"
|
||||
}
|
||||
}
|
||||
}),
|
||||
mobileNav: (props: Dict<never>) => ({
|
||||
// bg: "transparent",
|
||||
fontSize: "md",
|
||||
px: 2,
|
||||
boxShadow:
|
||||
"rgba(0, 134, 255, 0.30) 0px 0px 15px, rgba(0, 134, 255, 0.15) 0px 0px 3px 1px",
|
||||
_hover: {
|
||||
bg: mode(
|
||||
whiten("brand.secondary", 20),
|
||||
darken("brand.secondary", 20)
|
||||
)(props),
|
||||
boxShadow:
|
||||
"rgba(0, 134, 255, 0.5) 0px 0px 15px, rgba(0, 134, 255, 0.3) 0px 0px 3px 1px"
|
||||
},
|
||||
_expanded: {
|
||||
bg: "brand.primary",
|
||||
boxShadow:
|
||||
"rgba(0, 134, 255, 0.5) 0px 0px 15px, rgba(0, 134, 255, 0.3) 0px 0px 3px 1px",
|
||||
border: "1px solid #0068ff"
|
||||
}
|
||||
}),
|
||||
kofi: (props: Dict<never>) => ({
|
||||
bg: "brand.kofi",
|
||||
fontSize: "lg",
|
||||
p: 3,
|
||||
color: "whiteAlpha",
|
||||
_hover: {
|
||||
bg: mode(whiten("brand.kofi", 20), darken("brand.kofi", 20))(props)
|
||||
}
|
||||
}),
|
||||
twitter: (props: Dict<never>) => ({
|
||||
bg: "brand.twitter",
|
||||
fontSize: "lg",
|
||||
py: 3,
|
||||
px: 4,
|
||||
color: "whiteAlpha",
|
||||
_hover: {
|
||||
bg: mode(
|
||||
whiten("brand.twitter", 20),
|
||||
darken("brand.twitter", 20)
|
||||
)(props)
|
||||
}
|
||||
})
|
||||
},
|
||||
// default values for `size` and `variant`
|
||||
defaultProps: {}
|
||||
};
|
||||
|
||||
export default buttonStyles;
|
||||
@@ -1,32 +0,0 @@
|
||||
import React, { FC } from "react";
|
||||
import { Button, Flex, Link } from "@chakra-ui/react";
|
||||
import { Icon } from "@iconify/react";
|
||||
|
||||
interface BackToTopButtonProps {
|
||||
show: boolean;
|
||||
}
|
||||
|
||||
const BackToTopButton: FC<BackToTopButtonProps> = ({
|
||||
show
|
||||
}: BackToTopButtonProps) => {
|
||||
return (
|
||||
<Flex
|
||||
display={show ? "flex" : "none"}
|
||||
pos="fixed"
|
||||
top="85vh"
|
||||
right={{
|
||||
base: "1.25rem",
|
||||
sm: "2rem",
|
||||
md: "3rem"
|
||||
}}
|
||||
>
|
||||
<Link href="/#top">
|
||||
<Button variant="backToTop">
|
||||
<Icon icon="akar-icons:chevron-up" />
|
||||
</Button>
|
||||
</Link>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default BackToTopButton;
|
||||
@@ -1,31 +0,0 @@
|
||||
import React from "react";
|
||||
import { Button, HStack, Link, Text } from "@chakra-ui/react";
|
||||
import navItems, { NavItem } from "./navItems";
|
||||
|
||||
const DesktopNav = (): JSX.Element => {
|
||||
return (
|
||||
<HStack
|
||||
as="nav"
|
||||
display={{ base: "none", lg: "flex" }}
|
||||
h="auto"
|
||||
w="auto"
|
||||
spacing={4}
|
||||
// m="auto"
|
||||
justifyContent="center"
|
||||
alignContent="center"
|
||||
alignItems="center"
|
||||
>
|
||||
{navItems.map((navItem: NavItem) => {
|
||||
return (
|
||||
<Link id={"dekstop-" + navItem[0]} key={navItem[0]} href={navItem[1]}>
|
||||
<Button variant="nav">
|
||||
<Text>{navItem[0]}</Text>
|
||||
</Button>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</HStack>
|
||||
);
|
||||
};
|
||||
|
||||
export default DesktopNav;
|
||||
@@ -1,37 +0,0 @@
|
||||
import React /*, { useEffect, useRef, useState }*/ from "react";
|
||||
import { Box, Text, VStack, Link } from "@chakra-ui/react";
|
||||
// import BackToTopButton from "./BackToTopButton";
|
||||
import Buttons from "../../components/buttons";
|
||||
|
||||
const Footer = (): JSX.Element => {
|
||||
return (
|
||||
<Box bg="brand.footer" as="footer" w="100%" h="auto">
|
||||
{/* <BackToTopButton show={showBackToTop} /> */}
|
||||
<VStack
|
||||
h="auto"
|
||||
w="auto"
|
||||
py={12}
|
||||
spacing={5}
|
||||
justifyItems="center"
|
||||
justifyContent="center"
|
||||
>
|
||||
<VStack spacing={4}>
|
||||
<Buttons />
|
||||
<Text color="brand.footerText" fontSize="xs">
|
||||
©
|
||||
{` 2021 - ${new Date().getFullYear()} `}
|
||||
<Link
|
||||
href="https://lucidcreations.media"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
>
|
||||
{"Lucid Creations Media"}
|
||||
</Link>
|
||||
</Text>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
@@ -1,195 +0,0 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import Image from "next/image";
|
||||
import {
|
||||
Heading,
|
||||
HStack,
|
||||
Box,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuButton
|
||||
} from "@chakra-ui/react";
|
||||
import { Icon } from "@iconify/react";
|
||||
import DesktopNav from "./DesktopNav";
|
||||
import MobileNav from "./MobileNav";
|
||||
import appLogo from "../../../public/images/logo.svg";
|
||||
import { fonts } from "../AppTheme";
|
||||
|
||||
const Header = (): JSX.Element => {
|
||||
const appName = "Lucid Creations Media";
|
||||
const appVersion = process.env.NEXT_PUBLIC_APP_VERSION_HEADER || "";
|
||||
|
||||
// Add transparency while not at the top of the page.
|
||||
const [transparentNavbar, setTransparentNavbar] = useState<boolean>(false);
|
||||
const lastScroll = useRef<number>(0);
|
||||
|
||||
const handleScroll = (): void => {
|
||||
// Sticky Nav
|
||||
if (window.scrollY >= 20) {
|
||||
setTransparentNavbar(true);
|
||||
} else {
|
||||
setTransparentNavbar(false);
|
||||
}
|
||||
|
||||
// Scroll Position.
|
||||
const currentScroll =
|
||||
window.scrollY || window.pageYOffset || document.body.scrollTop;
|
||||
|
||||
// Update Scroll Position Reference
|
||||
lastScroll.current = currentScroll <= 0 ? 0 : currentScroll;
|
||||
// setScroll(lastScroll.current = currentScroll <= 0 ? 0 : currentScroll)
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!window) {
|
||||
console.log("waiting for mount");
|
||||
} else if (window) {
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
}
|
||||
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
// Mobile Menu Icon && Open/Close
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const [hover, setHover] = useState<boolean>(false);
|
||||
|
||||
const menuIcon = (): JSX.Element => {
|
||||
const iconType = {
|
||||
default: <Icon icon="bx:bx-menu-alt-right" />,
|
||||
hover: <Icon icon="bx:bx-menu" />,
|
||||
open: <Icon icon="bx:bx-x" />
|
||||
};
|
||||
|
||||
if (open) {
|
||||
return iconType.open;
|
||||
} else if (hover) {
|
||||
return iconType.hover;
|
||||
} else {
|
||||
return iconType.default;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
zIndex={1}
|
||||
w="100%"
|
||||
pos="fixed"
|
||||
top={0}
|
||||
alignItems="center"
|
||||
boxShadow={
|
||||
open
|
||||
? "none"
|
||||
: "rgba(0, 134, 255, 0.75) 0px 0px 15px, rgba(0, 134, 255, 0.5) 0px 0px 3px 1px"
|
||||
}
|
||||
bg={
|
||||
open
|
||||
? "brand.main"
|
||||
: transparentNavbar
|
||||
? "rgba(49, 56, 220, 0.9)"
|
||||
: "brand.main"
|
||||
}
|
||||
transition=".5s ease"
|
||||
borderRadius="0px 0px 10px 10px"
|
||||
_hover={{
|
||||
bg: "brand.main",
|
||||
boxShadow: open
|
||||
? "none"
|
||||
: "rgba(0, 134, 255, 0.9) 0px 0px 15px, rgba(0, 134, 255, 0.7) 0px 0px 3px 1px"
|
||||
}}
|
||||
h={open ? "125px" : "auto"}
|
||||
>
|
||||
{/* Logo | Site Name */}
|
||||
<HStack
|
||||
display={{ base: "flex", lg: "none" }}
|
||||
position="absolute"
|
||||
width="100%"
|
||||
height={12}
|
||||
top={0}
|
||||
ml={4}
|
||||
spacing="5px"
|
||||
justifyContent={{
|
||||
base: "flex-start",
|
||||
sm: "center"
|
||||
}}
|
||||
alignItems="center"
|
||||
_hover={{
|
||||
cursor: "default"
|
||||
}}
|
||||
>
|
||||
<Image height="30" width="30" src={appLogo} alt="App Logo" />
|
||||
|
||||
<Heading as="h1" size="md" fontFamily={fonts.LCM} fontWeight="400">
|
||||
{appName}
|
||||
</Heading>
|
||||
<Heading color="whiteAlpha.500" as="h2" size="sm">
|
||||
{appVersion}
|
||||
</Heading>
|
||||
</HStack>
|
||||
|
||||
{/* Desktop Nav Items and Mobile Menu Button */}
|
||||
<HStack
|
||||
w="100%"
|
||||
px={4}
|
||||
h={12}
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<HStack
|
||||
w="100%"
|
||||
h="auto"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<Box w="auto" display={{ base: "flex", lg: "none " }}></Box>
|
||||
<Box w="100%" display={{ base: "none", lg: "flex" }} m="auto">
|
||||
<HStack
|
||||
width="100%"
|
||||
alignItems="center"
|
||||
height="auto"
|
||||
spacing="5px"
|
||||
_hover={{
|
||||
cursor: "default"
|
||||
}}
|
||||
>
|
||||
<Image height="30" width="30" src={appLogo} alt="App Logo" />
|
||||
<Heading
|
||||
as="h1"
|
||||
size="md"
|
||||
fontFamily={fonts.LCM}
|
||||
fontWeight="400"
|
||||
>
|
||||
{appName}
|
||||
</Heading>
|
||||
<Heading color="whiteAlpha.500" as="h2" size="sm">
|
||||
{appVersion}
|
||||
</Heading>
|
||||
</HStack>
|
||||
</Box>
|
||||
<DesktopNav />
|
||||
</HStack>
|
||||
<Menu isLazy lazyBehavior="unmount" isOpen={open}>
|
||||
<MenuButton
|
||||
id="mobile-menu-button"
|
||||
as={IconButton}
|
||||
aria-label="Mobile Menu"
|
||||
icon={menuIcon()}
|
||||
display={{
|
||||
base: "inline-flex",
|
||||
lg: "none"
|
||||
}}
|
||||
bg={transparentNavbar ? "transparent" : "rgba(255, 255, 255, .15)"}
|
||||
border={transparentNavbar ? "1px solid #0068ff" : "none"}
|
||||
variant="mobileNav"
|
||||
type="button"
|
||||
onClick={() => setOpen(!open)}
|
||||
onMouseEnter={() => setHover(true)}
|
||||
onMouseLeave={() => setHover(false)}
|
||||
/>
|
||||
<MobileNav updateOpen={setOpen} />
|
||||
</Menu>
|
||||
</HStack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
@@ -1,24 +0,0 @@
|
||||
import React, { FC, ReactNode } from "react";
|
||||
import type { AppProps } from "next/app";
|
||||
import Header from "../layout/Header";
|
||||
import { Box } from "@chakra-ui/layout";
|
||||
import Footer from "./Footer";
|
||||
|
||||
interface LayoutProps {
|
||||
children: ReactNode;
|
||||
elementType?: string;
|
||||
}
|
||||
|
||||
const Layout: FC<LayoutProps> = (
|
||||
{ children }: LayoutProps,
|
||||
{ pageProps }: AppProps
|
||||
) => {
|
||||
return (
|
||||
<Box w="100%">
|
||||
<Header {...pageProps} />
|
||||
<main>{children}</main>
|
||||
<Footer />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
export default Layout;
|
||||
@@ -1,57 +0,0 @@
|
||||
import React, { FC, Fragment } from "react";
|
||||
import {
|
||||
Button,
|
||||
Link,
|
||||
MenuDivider,
|
||||
MenuItem,
|
||||
MenuList,
|
||||
Text
|
||||
} from "@chakra-ui/react";
|
||||
import navItems, { NavItem } from "./navItems";
|
||||
|
||||
interface MobileNavProps {
|
||||
updateOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const MobileNav: FC<MobileNavProps> = ({ updateOpen }: MobileNavProps) => {
|
||||
return (
|
||||
<MenuList
|
||||
as="nav"
|
||||
display={{ base: "block", lg: "none" }}
|
||||
h="auto"
|
||||
w="100%"
|
||||
p={0}
|
||||
border="none"
|
||||
boxShadow="none"
|
||||
bg="brand.main"
|
||||
>
|
||||
{navItems.map((navItem: NavItem, index: number) => {
|
||||
return (
|
||||
<MenuItem
|
||||
id={"mobile-" + navItem[0]}
|
||||
key={navItem[0]}
|
||||
w="auto"
|
||||
h="auto"
|
||||
p={0}
|
||||
_hover={{
|
||||
backgroundColor: "none"
|
||||
}}
|
||||
_focus={{
|
||||
backgroundColor: "none"
|
||||
}}
|
||||
>
|
||||
<Link onClick={() => updateOpen(false)} href={navItem[1]}>
|
||||
{index === 0 ? <MenuDivider /> : <Fragment></Fragment>}
|
||||
<Button w="100vw" variant={"nav"} p={0} m="auto">
|
||||
<Text>{navItem[0]}</Text>
|
||||
</Button>
|
||||
<MenuDivider />
|
||||
</Link>
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
</MenuList>
|
||||
);
|
||||
};
|
||||
|
||||
export default MobileNav;
|
||||
@@ -1,6 +0,0 @@
|
||||
export type NavItem = [string, string];
|
||||
export type NavItems = NavItem[];
|
||||
|
||||
const navItems: NavItems = [["Home", "/"]];
|
||||
|
||||
export default navItems;
|
||||
@@ -1,30 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"target": "ESNext",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
56
types/Calender.d.ts
vendored
@@ -1,56 +0,0 @@
|
||||
type Days =
|
||||
| "Sunday"
|
||||
| "Monday"
|
||||
| "Tuesday"
|
||||
| "Wednesday"
|
||||
| "Thursday"
|
||||
| "Friday"
|
||||
| "Saturday";
|
||||
|
||||
type DaysOfWeek = Days[];
|
||||
|
||||
interface WeekDays {
|
||||
sunday: DaysOfWeek;
|
||||
monday: DaysOfWeek;
|
||||
}
|
||||
|
||||
interface MonthDay {
|
||||
date: string;
|
||||
isOverflow: boolean;
|
||||
overflowDirection: "prev" | "next" | null;
|
||||
}
|
||||
|
||||
interface Month {
|
||||
week1: MonthDay[];
|
||||
week2: MonthDay[];
|
||||
week3: MonthDay[];
|
||||
week4: MonthDay[];
|
||||
week5: MonthDay[];
|
||||
week6: MonthDay[];
|
||||
}
|
||||
|
||||
interface WeekLayout {
|
||||
weekdays: DaysOfWeek;
|
||||
month: Month;
|
||||
}
|
||||
|
||||
interface MonthLayout {
|
||||
sunday: WeekLayout;
|
||||
monday: WeekLayout;
|
||||
}
|
||||
|
||||
interface UpdateCalenderPropsDateLayout {
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
}
|
||||
interface UpdateCalendarProps {
|
||||
date: UpdateCalenderPropsDateLayout;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
interface SelectedDateInfo {
|
||||
date: string;
|
||||
title: string;
|
||||
layout: MonthLayout;
|
||||
}
|
||||
24
types/Stickers.d.ts
vendored
@@ -1,24 +0,0 @@
|
||||
type StickerVal = -2 | -1 | 0 | 1 | 2 | null;
|
||||
|
||||
type ValidStickerVal = -2 | -1 | 0 | 1 | 2;
|
||||
|
||||
interface AddEditStickerProps {
|
||||
date: Date;
|
||||
sticker: ValidStickerVal;
|
||||
}
|
||||
|
||||
interface Sticker {
|
||||
id: string;
|
||||
date: string;
|
||||
sticker: StickerVal;
|
||||
edited: boolean;
|
||||
manual: boolean;
|
||||
}
|
||||
|
||||
type StickerDays = Sticker[];
|
||||
|
||||
interface StickerModal {
|
||||
isOpen: boolean;
|
||||
selectedSticker: StickerVal;
|
||||
step: number;
|
||||
}
|
||||
139
types/cache-life.d.ts
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
// Type definitions for Next.js cacheLife configs
|
||||
|
||||
declare module "next/cache" {
|
||||
export { unstable_cache } from "next/dist/server/web/spec-extension/unstable-cache";
|
||||
export {
|
||||
revalidateTag,
|
||||
revalidatePath,
|
||||
unstable_expireTag,
|
||||
unstable_expirePath
|
||||
} from "next/dist/server/web/spec-extension/revalidate";
|
||||
export { unstable_noStore } from "next/dist/server/web/spec-extension/unstable-no-store";
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"default"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 900 seconds (15 minutes)
|
||||
* expire: never
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 15 minutes, start revalidating new values in the background.
|
||||
* It lives for the maximum age of the server cache. If this entry has no traffic for a while, it may serve an old value the next request.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "default"): void;
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"seconds"` profile.
|
||||
* ```
|
||||
* stale: 0 seconds
|
||||
* revalidate: 1 seconds
|
||||
* expire: 60 seconds (1 minute)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 0 seconds before checking with the server.
|
||||
* If the server receives a new request after 1 seconds, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 minute it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "seconds"): void;
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"minutes"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 60 seconds (1 minute)
|
||||
* expire: 3600 seconds (1 hour)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 minute, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 hour it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "minutes"): void;
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"hours"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 3600 seconds (1 hour)
|
||||
* expire: 86400 seconds (1 day)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 hour, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 day it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "hours"): void;
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"days"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 86400 seconds (1 day)
|
||||
* expire: 604800 seconds (1 week)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 day, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 1 week it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "days"): void;
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"weeks"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 604800 seconds (1 week)
|
||||
* expire: 2592000 seconds (30 days)
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 1 week, start revalidating new values in the background.
|
||||
* If this entry has no traffic for 30 days it will expire. The next request will recompute it.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "weeks"): void;
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` for a timespan defined by the `"max"` profile.
|
||||
* ```
|
||||
* stale: 300 seconds (5 minutes)
|
||||
* revalidate: 2592000 seconds (30 days)
|
||||
* expire: never
|
||||
* ```
|
||||
*
|
||||
* This cache may be stale on clients for 5 minutes before checking with the server.
|
||||
* If the server receives a new request after 30 days, start revalidating new values in the background.
|
||||
* It lives for the maximum age of the server cache. If this entry has no traffic for a while, it may serve an old value the next request.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: "max"): void;
|
||||
|
||||
/**
|
||||
* Cache this `"use cache"` using a custom timespan.
|
||||
* ```
|
||||
* stale: ... // seconds
|
||||
* revalidate: ... // seconds
|
||||
* expire: ... // seconds
|
||||
* ```
|
||||
*
|
||||
* This is similar to Cache-Control: max-age=`stale`,s-max-age=`revalidate`,stale-while-revalidate=`expire-revalidate`
|
||||
*
|
||||
* If a value is left out, the lowest of other cacheLife() calls or the default, is used instead.
|
||||
*/
|
||||
export function unstable_cacheLife(profile: {
|
||||
/**
|
||||
* This cache may be stale on clients for ... seconds before checking with the server.
|
||||
*/
|
||||
stale?: number;
|
||||
/**
|
||||
* If the server receives a new request after ... seconds, start revalidating new values in the background.
|
||||
*/
|
||||
revalidate?: number;
|
||||
/**
|
||||
* If this entry has no traffic for ... seconds it will expire. The next request will recompute it.
|
||||
*/
|
||||
expire?: number;
|
||||
}): void;
|
||||
|
||||
export { cacheTag as unstable_cacheTag } from "next/dist/server/use-cache/cache-tag";
|
||||
}
|
||||
1
types/package.json
Normal file
@@ -0,0 +1 @@
|
||||
{"type": "module"}
|
||||