Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b82ca7de7 |
@ -1,4 +1,4 @@
|
||||
|
||||
require('dotenv').config();
|
||||
|
||||
module.exports = {
|
||||
production: {
|
||||
@ -12,22 +12,23 @@ module.exports = {
|
||||
seederStorage: 'sequelize',
|
||||
},
|
||||
development: {
|
||||
username: 'postgres',
|
||||
dialect: 'postgres',
|
||||
password: '',
|
||||
database: 'db_diego_coffee___cocktail_studio',
|
||||
host: process.env.DB_HOST || 'localhost',
|
||||
username: process.env.DB_USER,
|
||||
password: process.env.DB_PASS,
|
||||
database: process.env.DB_NAME,
|
||||
host: process.env.DB_HOST,
|
||||
port: process.env.DB_PORT,
|
||||
logging: console.log,
|
||||
seederStorage: 'sequelize',
|
||||
},
|
||||
dev_stage: {
|
||||
dialect: 'postgres',
|
||||
username: process.env.DB_USER,
|
||||
password: process.env.DB_PASS,
|
||||
database: process.env.DB_NAME,
|
||||
host: process.env.DB_HOST,
|
||||
port: process.env.DB_PORT,
|
||||
logging: console.log,
|
||||
seederStorage: 'sequelize',
|
||||
}
|
||||
};
|
||||
dev_stage: {
|
||||
dialect: 'postgres',
|
||||
username: process.env.DB_USER,
|
||||
password: process.env.DB_PASS,
|
||||
database: process.env.DB_NAME,
|
||||
host: process.env.DB_HOST,
|
||||
port: process.env.DB_PORT,
|
||||
logging: console.log,
|
||||
seederStorage: 'sequelize',
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,59 @@
|
||||
|
||||
module.exports = {
|
||||
up: async (queryInterface, Sequelize) => {
|
||||
const createdAt = new Date();
|
||||
const updatedAt = new Date();
|
||||
|
||||
// Get Public role ID
|
||||
const [publicRole] = await queryInterface.sequelize.query(
|
||||
`SELECT id FROM roles WHERE name = 'Public' LIMIT 1;`,
|
||||
{ type: queryInterface.sequelize.QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
if (!publicRole) return;
|
||||
|
||||
const publicRoleId = publicRole.id;
|
||||
|
||||
// Permissions to grant to Public role
|
||||
const permissionsToGrant = [
|
||||
'READ_MENU_ITEMS',
|
||||
'READ_CATEGORIES',
|
||||
'READ_PROMOTIONS',
|
||||
'READ_LOCATIONS',
|
||||
'CREATE_PITCHES',
|
||||
'CREATE_RESERVATIONS'
|
||||
];
|
||||
|
||||
// Find permission IDs
|
||||
const permissions = await queryInterface.sequelize.query(
|
||||
`SELECT id FROM permissions WHERE name IN (:permissionsToGrant);`,
|
||||
{
|
||||
replacements: { permissionsToGrant },
|
||||
type: queryInterface.sequelize.QueryTypes.SELECT
|
||||
}
|
||||
);
|
||||
|
||||
const rolesPermissionsPermissions = permissions.map(p => ({
|
||||
createdAt,
|
||||
updatedAt,
|
||||
roles_permissionsId: publicRoleId,
|
||||
permissionId: p.id
|
||||
}));
|
||||
|
||||
await queryInterface.bulkInsert('rolesPermissionsPermissions', rolesPermissionsPermissions);
|
||||
},
|
||||
|
||||
down: async (queryInterface, Sequelize) => {
|
||||
const [publicRole] = await queryInterface.sequelize.query(
|
||||
`SELECT id FROM roles WHERE name = 'Public' LIMIT 1;`,
|
||||
{ type: queryInterface.sequelize.QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
if (!publicRole) return;
|
||||
|
||||
await queryInterface.sequelize.query(
|
||||
`DELETE FROM "rolesPermissionsPermissions" WHERE "roles_permissionsId" = :publicRoleId;`,
|
||||
{ replacements: { publicRoleId: publicRole.id } }
|
||||
);
|
||||
}
|
||||
};
|
||||
154
backend/src/db/seeders/20260130000000-diego-menu-items.js
Normal file
154
backend/src/db/seeders/20260130000000-diego-menu-items.js
Normal file
@ -0,0 +1,154 @@
|
||||
const { v4: uuid } = require('uuid');
|
||||
|
||||
module.exports = {
|
||||
up: async (queryInterface, Sequelize) => {
|
||||
const createdAt = new Date();
|
||||
const updatedAt = new Date();
|
||||
|
||||
// Clear existing items to avoid duplicates and ensure clean state
|
||||
await queryInterface.bulkDelete('menu_items', null, {});
|
||||
await queryInterface.bulkDelete('categories', null, {});
|
||||
|
||||
const categories = [
|
||||
{
|
||||
id: uuid(),
|
||||
name: 'Coffee',
|
||||
description: 'Specialty coffee and lattes.',
|
||||
createdAt,
|
||||
updatedAt
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
name: 'Cocktail',
|
||||
description: 'Creative cocktails and "Drink the feelings".',
|
||||
createdAt,
|
||||
updatedAt
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
name: 'Food',
|
||||
description: 'Cozy and chaotic food pairings.',
|
||||
createdAt,
|
||||
updatedAt
|
||||
}
|
||||
];
|
||||
|
||||
await queryInterface.bulkInsert('categories', categories);
|
||||
|
||||
const getCatId = (name) => categories.find(c => c.name === name).id;
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
id: uuid(),
|
||||
title: 'Orange Coffee',
|
||||
description: 'Bright orange, smooth coffee, sneaky dark chocolate finish.',
|
||||
price: 150.00,
|
||||
item_type: 'Coffee',
|
||||
categoryId: getCatId('Coffee'),
|
||||
ingredients: 'Espresso, Fresh Orange Juice, Dark Chocolate Syrup',
|
||||
is_featured: true,
|
||||
is_available: true,
|
||||
createdAt,
|
||||
updatedAt
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
title: 'Spanish Latté',
|
||||
description: 'Creamy and sweet, a classic favorite. Available iced or hot.',
|
||||
price: 180.00,
|
||||
item_type: 'Coffee',
|
||||
categoryId: getCatId('Coffee'),
|
||||
ingredients: 'Espresso, Condensed Milk, Fresh Milk',
|
||||
is_featured: true,
|
||||
is_available: true,
|
||||
createdAt,
|
||||
updatedAt
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
title: 'CEO Latté',
|
||||
description: 'A strong, bold latte for the boss in you. Served hot.',
|
||||
price: 170.00,
|
||||
item_type: 'Coffee',
|
||||
categoryId: getCatId('Coffee'),
|
||||
ingredients: 'Extra Shot Espresso, Steamed Milk, Secret Sweetener',
|
||||
is_featured: true,
|
||||
is_available: true,
|
||||
createdAt,
|
||||
updatedAt
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
title: 'Spice & Star',
|
||||
description: 'Buttery, cinnamon-spiced, sparkling with warm star anise.',
|
||||
price: 250.00,
|
||||
item_type: 'Cocktail',
|
||||
categoryId: getCatId('Cocktail'),
|
||||
ingredients: 'Spiced Rum, Cinnamon Syrup, Star Anise, Butter-washed Bourbon',
|
||||
is_featured: true,
|
||||
is_available: true,
|
||||
createdAt,
|
||||
updatedAt
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
title: 'Spania Salada',
|
||||
description: 'A salty-sweet twist on the classic Spanish Latté.',
|
||||
price: 220.00,
|
||||
item_type: 'Cocktail',
|
||||
categoryId: getCatId('Cocktail'),
|
||||
ingredients: 'Espresso, Salted Caramel, Condensed Milk, Sea Salt',
|
||||
is_featured: true,
|
||||
is_available: true,
|
||||
createdAt,
|
||||
updatedAt
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
title: 'Honey Chai Matcha Latté',
|
||||
description: 'One-in-a-million matcha. A soothing blend of matcha, honey, and chai spices.',
|
||||
price: 190.00,
|
||||
item_type: 'Coffee',
|
||||
categoryId: getCatId('Coffee'),
|
||||
ingredients: 'Ceremonial Grade Matcha, Honey, Chai Spice Blend, Oat Milk',
|
||||
is_featured: true,
|
||||
is_available: true,
|
||||
createdAt,
|
||||
updatedAt
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
title: 'Cinnamon Oat',
|
||||
description: 'Cozy oat-based coffee with a hint of cinnamon.',
|
||||
price: 180.00,
|
||||
item_type: 'Coffee',
|
||||
categoryId: getCatId('Coffee'),
|
||||
ingredients: 'Espresso, Oat Milk, Cinnamon, Maple Syrup',
|
||||
is_featured: true,
|
||||
is_available: true,
|
||||
createdAt,
|
||||
updatedAt
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
title: 'Diego Burger',
|
||||
description: 'Our signature chaotic burger. Collab with ohso.socialph.',
|
||||
price: 220.00,
|
||||
item_type: 'Food',
|
||||
categoryId: getCatId('Food'),
|
||||
ingredients: 'Beef Patty, Secret Chaos Sauce, Brioche Bun, Caramelized Onions',
|
||||
is_featured: true,
|
||||
is_available: true,
|
||||
createdAt,
|
||||
updatedAt
|
||||
}
|
||||
];
|
||||
|
||||
return queryInterface.bulkInsert('menu_items', menuItems);
|
||||
},
|
||||
|
||||
down: async (queryInterface, Sequelize) => {
|
||||
await queryInterface.bulkDelete('menu_items', null, {});
|
||||
await queryInterface.bulkDelete('categories', null, {});
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,55 @@
|
||||
|
||||
module.exports = {
|
||||
up: async (queryInterface, Sequelize) => {
|
||||
const createdAt = new Date();
|
||||
const updatedAt = new Date();
|
||||
|
||||
const [publicRole] = await queryInterface.sequelize.query(
|
||||
`SELECT id FROM roles WHERE name = 'Public' LIMIT 1;`
|
||||
);
|
||||
|
||||
if (!publicRole || !publicRole[0]) {
|
||||
console.error("Public role not found");
|
||||
return;
|
||||
}
|
||||
|
||||
const publicRoleId = publicRole[0].id;
|
||||
|
||||
const permissionsToGrant = [
|
||||
'READ_MENU_ITEMS',
|
||||
'CREATE_RESERVATIONS',
|
||||
'READ_LOCATIONS',
|
||||
'READ_CATEGORIES',
|
||||
'CREATE_PITCHES',
|
||||
'READ_MEDIA'
|
||||
];
|
||||
|
||||
const [permissions] = await queryInterface.sequelize.query(
|
||||
`SELECT id, name FROM permissions WHERE name IN (${permissionsToGrant.map(p => `'${p}'`).join(',')});`
|
||||
);
|
||||
|
||||
const rolePermissions = permissions.map(permission => ({
|
||||
createdAt,
|
||||
updatedAt,
|
||||
roles_permissionsId: publicRoleId,
|
||||
permissionId: permission.id
|
||||
}));
|
||||
|
||||
return queryInterface.bulkInsert('rolesPermissionsPermissions', rolePermissions, {
|
||||
ignoreDuplicates: true
|
||||
});
|
||||
},
|
||||
|
||||
down: async (queryInterface, Sequelize) => {
|
||||
// Usually we don't want to remove these in down as it might break things,
|
||||
// but for completeness:
|
||||
const [publicRole] = await queryInterface.sequelize.query(
|
||||
`SELECT id FROM roles WHERE name = 'Public' LIMIT 1;`
|
||||
);
|
||||
if (publicRole && publicRole[0]) {
|
||||
return queryInterface.bulkDelete('rolesPermissionsPermissions', {
|
||||
roles_permissionsId: publicRole[0].id
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
52
backend/src/db/seeders/20260130000002-diego-locations.js
Normal file
52
backend/src/db/seeders/20260130000002-diego-locations.js
Normal file
@ -0,0 +1,52 @@
|
||||
const { v4: uuid } = require('uuid');
|
||||
|
||||
module.exports = {
|
||||
up: async (queryInterface, Sequelize) => {
|
||||
const createdAt = new Date();
|
||||
const updatedAt = new Date();
|
||||
|
||||
// Clear reservations first to avoid foreign key constraints
|
||||
await queryInterface.bulkDelete('reservations', null, {});
|
||||
await queryInterface.bulkDelete('locations', null, {});
|
||||
|
||||
const locations = [
|
||||
{
|
||||
id: uuid(),
|
||||
name: 'Lucena (Main Playground)',
|
||||
address: 'Bonifacio Dr., Pleasantville, Lucena',
|
||||
hours: '3PM - 11PM',
|
||||
city: 'Lucena',
|
||||
is_open: true,
|
||||
createdAt,
|
||||
updatedAt
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
name: 'Lucban',
|
||||
address: 'Town Center, Lucban, Quezon',
|
||||
hours: 'Closing Soon',
|
||||
city: 'Lucban',
|
||||
is_open: true,
|
||||
createdAt,
|
||||
updatedAt
|
||||
},
|
||||
{
|
||||
id: uuid(),
|
||||
name: 'Sariaya',
|
||||
address: 'Quiminiano St., Brgy 3, Arellano Subd., Sariaya',
|
||||
hours: '3PM - 11PM',
|
||||
city: 'Sariaya',
|
||||
is_open: true,
|
||||
createdAt,
|
||||
updatedAt
|
||||
}
|
||||
];
|
||||
|
||||
return queryInterface.bulkInsert('locations', locations);
|
||||
},
|
||||
|
||||
down: async (queryInterface, Sequelize) => {
|
||||
await queryInterface.bulkDelete('reservations', null, {});
|
||||
await queryInterface.bulkDelete('locations', null, {});
|
||||
}
|
||||
};
|
||||
@ -109,21 +109,21 @@ app.use('/api/roles', passport.authenticate('jwt', {session: false}), rolesRoute
|
||||
|
||||
app.use('/api/permissions', passport.authenticate('jwt', {session: false}), permissionsRoutes);
|
||||
|
||||
app.use('/api/menu_items', passport.authenticate('jwt', {session: false}), menu_itemsRoutes);
|
||||
app.use('/api/menu_items', menu_itemsRoutes);
|
||||
|
||||
app.use('/api/categories', passport.authenticate('jwt', {session: false}), categoriesRoutes);
|
||||
app.use('/api/categories', categoriesRoutes);
|
||||
|
||||
app.use('/api/promotions', passport.authenticate('jwt', {session: false}), promotionsRoutes);
|
||||
|
||||
app.use('/api/reservations', passport.authenticate('jwt', {session: false}), reservationsRoutes);
|
||||
app.use('/api/reservations', reservationsRoutes);
|
||||
|
||||
app.use('/api/pitches', passport.authenticate('jwt', {session: false}), pitchesRoutes);
|
||||
app.use('/api/pitches', pitchesRoutes);
|
||||
|
||||
app.use('/api/locations', passport.authenticate('jwt', {session: false}), locationsRoutes);
|
||||
app.use('/api/locations', locationsRoutes);
|
||||
|
||||
app.use('/api/orders', passport.authenticate('jwt', {session: false}), ordersRoutes);
|
||||
|
||||
app.use('/api/media', passport.authenticate('jwt', {session: false}), mediaRoutes);
|
||||
app.use('/api/media', mediaRoutes);
|
||||
|
||||
app.use('/api/pages', passport.authenticate('jwt', {session: false}), pagesRoutes);
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import React, {useEffect, useRef} from 'react'
|
||||
import React, {useEffect, useRef, useState} from 'react'
|
||||
import Link from 'next/link'
|
||||
import { useState } from 'react'
|
||||
import { mdiChevronUp, mdiChevronDown } from '@mdi/js'
|
||||
import BaseDivider from './BaseDivider'
|
||||
import BaseIcon from './BaseIcon'
|
||||
@ -129,4 +128,4 @@ export default function NavBarItem({ item }: Props) {
|
||||
}
|
||||
|
||||
return <div className={componentClass} ref={excludedRef}>{NavBarItemComponentContents}</div>
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
import React, { ReactNode, useEffect } from 'react'
|
||||
import { useState } from 'react'
|
||||
import React, { ReactNode, useEffect, useState } from 'react'
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { mdiForwardburger, mdiBackburger, mdiMenu } from '@mdi/js'
|
||||
import menuAside from '../menuAside'
|
||||
@ -126,4 +125,4 @@ export default function LayoutAuthenticated({
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -47,7 +47,30 @@ const menuNavBar: MenuNavBarItem[] = [
|
||||
]
|
||||
|
||||
export const webPagesNavBar = [
|
||||
|
||||
{
|
||||
href: '#home',
|
||||
label: 'Home',
|
||||
},
|
||||
{
|
||||
href: '#about',
|
||||
label: 'About',
|
||||
},
|
||||
{
|
||||
href: '#menu',
|
||||
label: 'Menu',
|
||||
},
|
||||
{
|
||||
href: '#locations',
|
||||
label: 'Locations',
|
||||
},
|
||||
{
|
||||
href: '#contact',
|
||||
label: 'Contact',
|
||||
},
|
||||
{
|
||||
href: '/login',
|
||||
label: 'Admin',
|
||||
}
|
||||
];
|
||||
|
||||
export default menuNavBar
|
||||
export default menuNavBar
|
||||
@ -114,35 +114,6 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
|
||||
React.useEffect(() => {
|
||||
// Tour is disabled by default in generated projects.
|
||||
return;
|
||||
const isCompleted = (stepKey: string) => {
|
||||
return localStorage.getItem(`completed_${stepKey}`) === 'true';
|
||||
};
|
||||
if (router.pathname === '/login' && !isCompleted('loginSteps')) {
|
||||
setSteps(loginSteps);
|
||||
setStepName('loginSteps');
|
||||
setStepsEnabled(true);
|
||||
}else if (router.pathname === '/dashboard' && !isCompleted('appSteps')) {
|
||||
setTimeout(() => {
|
||||
setSteps(appSteps);
|
||||
setStepName('appSteps');
|
||||
setStepsEnabled(true);
|
||||
}, 1000);
|
||||
} else if (router.pathname === '/users/users-list' && !isCompleted('usersSteps')) {
|
||||
setTimeout(() => {
|
||||
setSteps(usersSteps);
|
||||
setStepName('usersSteps');
|
||||
setStepsEnabled(true);
|
||||
}, 1000);
|
||||
} else if (router.pathname === '/roles/roles-list' && !isCompleted('rolesSteps')) {
|
||||
setTimeout(() => {
|
||||
setSteps(rolesSteps);
|
||||
setStepName('rolesSteps');
|
||||
setStepsEnabled(true);
|
||||
}, 1000);
|
||||
} else {
|
||||
setSteps([]);
|
||||
setStepsEnabled(false);
|
||||
}
|
||||
}, [router.pathname]);
|
||||
|
||||
const handleExit = () => {
|
||||
@ -161,6 +132,10 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
|
||||
{getLayout(
|
||||
<>
|
||||
<Head>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Pacifico&family=Ubuntu:wght@300;400;500;700&display=swap" rel="stylesheet" />
|
||||
|
||||
<meta name="description" content={description} />
|
||||
|
||||
<meta property="og:url" content={url} />
|
||||
@ -198,4 +173,4 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
|
||||
)
|
||||
}
|
||||
|
||||
export default appWithTranslation(MyApp);
|
||||
export default appWithTranslation(MyApp);
|
||||
17
frontend/src/pages/_document.tsx
Normal file
17
frontend/src/pages/_document.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { Html, Head, Main, NextScript } from 'next/document'
|
||||
|
||||
export default function Document() {
|
||||
return (
|
||||
<Html>
|
||||
<Head>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Pacifico&family=Ubuntu:wght@300;400;500;700&display=swap" rel="stylesheet" />
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
)
|
||||
}
|
||||
@ -1,166 +1,706 @@
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import type { ReactElement } from 'react';
|
||||
import Head from 'next/head';
|
||||
import Link from 'next/link';
|
||||
import BaseButton from '../components/BaseButton';
|
||||
import CardBox from '../components/CardBox';
|
||||
import SectionFullScreen from '../components/SectionFullScreen';
|
||||
import axios from 'axios';
|
||||
import LayoutGuest from '../layouts/Guest';
|
||||
import BaseDivider from '../components/BaseDivider';
|
||||
import BaseButtons from '../components/BaseButtons';
|
||||
import { getPageTitle } from '../config';
|
||||
import { useAppSelector } from '../stores/hooks';
|
||||
import CardBoxComponentTitle from "../components/CardBoxComponentTitle";
|
||||
import { getPexelsImage, getPexelsVideo } from '../helpers/pexels';
|
||||
import SectionMain from '../components/SectionMain';
|
||||
import BaseButton from '../components/BaseButton';
|
||||
import {
|
||||
mdiCoffee,
|
||||
mdiGlassCocktail,
|
||||
mdiHamburger,
|
||||
mdiMapMarker,
|
||||
mdiEmail,
|
||||
mdiCreation,
|
||||
mdiCalendarClock,
|
||||
mdiInstagram,
|
||||
mdiArrowDown,
|
||||
mdiBottleWine
|
||||
} from '@mdi/js';
|
||||
import BaseIcon from '../components/BaseIcon';
|
||||
import CardBoxModal from '../components/CardBoxModal';
|
||||
|
||||
const DecorativeElements = () => (
|
||||
<div className="fixed inset-0 pointer-events-none overflow-hidden z-0">
|
||||
<div className="absolute top-[10%] left-[5%] animate-float opacity-10">
|
||||
<BaseIcon path={mdiCoffee} size={120} className="text-diego-orange" />
|
||||
</div>
|
||||
<div className="absolute top-[40%] right-[5%] animate-float opacity-10 delay-1000">
|
||||
<BaseIcon path={mdiGlassCocktail} size={150} className="text-diego-orange" />
|
||||
</div>
|
||||
<div className="absolute bottom-[10%] left-[15%] animate-float opacity-10 delay-500">
|
||||
<BaseIcon path={mdiBottleWine} size={100} className="text-diego-orange" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default function Starter() {
|
||||
const [illustrationImage, setIllustrationImage] = useState({
|
||||
src: undefined,
|
||||
photographer: undefined,
|
||||
photographer_url: undefined,
|
||||
})
|
||||
const [illustrationVideo, setIllustrationVideo] = useState({video_files: []})
|
||||
const [contentType, setContentType] = useState('video');
|
||||
const [contentPosition, setContentPosition] = useState('left');
|
||||
const textColor = useAppSelector((state) => state.style.linkColor);
|
||||
const Navbar = () => {
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
|
||||
const title = 'Diego Coffee & Cocktail Studio'
|
||||
|
||||
// Fetch Pexels image/video
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
const image = await getPexelsImage();
|
||||
const video = await getPexelsVideo();
|
||||
setIllustrationImage(image);
|
||||
setIllustrationVideo(video);
|
||||
}
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const imageBlock = (image) => (
|
||||
<div
|
||||
className='hidden md:flex flex-col justify-end relative flex-grow-0 flex-shrink-0 w-1/3'
|
||||
style={{
|
||||
backgroundImage: `${
|
||||
image
|
||||
? `url(${image?.src?.original})`
|
||||
: 'linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5))'
|
||||
}`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'left center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
}}
|
||||
>
|
||||
<div className='flex justify-center w-full bg-blue-300/20'>
|
||||
<a
|
||||
className='text-[8px]'
|
||||
href={image?.photographer_url}
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
Photo by {image?.photographer} on Pexels
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const videoBlock = (video) => {
|
||||
if (video?.video_files?.length > 0) {
|
||||
return (
|
||||
<div className='hidden md:flex flex-col justify-end relative flex-grow-0 flex-shrink-0 w-1/3'>
|
||||
<video
|
||||
className='absolute top-0 left-0 w-full h-full object-cover'
|
||||
autoPlay
|
||||
loop
|
||||
muted
|
||||
>
|
||||
<source src={video?.video_files[0]?.link} type='video/mp4'/>
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
<div className='flex justify-center w-full bg-blue-300/20 z-10'>
|
||||
<a
|
||||
className='text-[8px]'
|
||||
href={video?.user?.url}
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
Video by {video.user.name} on Pexels
|
||||
</a>
|
||||
</div>
|
||||
</div>)
|
||||
}
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setScrolled(window.scrollY > 50);
|
||||
};
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={
|
||||
contentPosition === 'background'
|
||||
? {
|
||||
backgroundImage: `${
|
||||
illustrationImage
|
||||
? `url(${illustrationImage.src?.original})`
|
||||
: 'linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5))'
|
||||
}`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'left center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
}
|
||||
: {}
|
||||
}
|
||||
>
|
||||
<Head>
|
||||
<title>{getPageTitle('Starter Page')}</title>
|
||||
</Head>
|
||||
<nav className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${scrolled ? 'bg-diego-navy/95 backdrop-blur-md py-4 shadow-2xl' : 'bg-transparent py-8'}`}>
|
||||
<div className="container mx-auto px-6 flex justify-between items-center">
|
||||
<Link href="#home" className="flex items-center space-x-2 group">
|
||||
<div className="bg-diego-orange p-2 rounded-xl group-hover:rotate-12 transition-transform">
|
||||
<BaseIcon path={mdiCreation} size={24} color="white" />
|
||||
</div>
|
||||
<span className="text-3xl font-heading text-white group-hover:text-diego-orange transition-colors">Diego</span>
|
||||
</Link>
|
||||
<div className="hidden md:flex items-center space-x-10">
|
||||
{['Home', 'About', 'Menu', 'Locations', 'Contact'].map((item) => (
|
||||
<a
|
||||
key={item}
|
||||
href={`#${item.toLowerCase()}`}
|
||||
className="text-white font-black uppercase tracking-[0.2em] text-xs hover:text-diego-orange transition-colors"
|
||||
>
|
||||
{item}
|
||||
</a>
|
||||
))}
|
||||
<a
|
||||
href="https://instagram.com/diego.byatelorie"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-white hover:text-diego-orange transition-colors"
|
||||
>
|
||||
<BaseIcon path={mdiInstagram} size={24} />
|
||||
</a>
|
||||
</div>
|
||||
<a href="#contact" className="bg-diego-orange hover:bg-orange-600 text-white px-6 py-2 rounded-full font-black uppercase tracking-widest text-[10px] shadow-xl transform hover:scale-105 transition-all">
|
||||
Book Event
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
<SectionFullScreen bg='violet'>
|
||||
<div
|
||||
className={`flex ${
|
||||
contentPosition === 'right' ? 'flex-row-reverse' : 'flex-row'
|
||||
} min-h-screen w-full`}
|
||||
>
|
||||
{contentType === 'image' && contentPosition !== 'background'
|
||||
? imageBlock(illustrationImage)
|
||||
: null}
|
||||
{contentType === 'video' && contentPosition !== 'background'
|
||||
? videoBlock(illustrationVideo)
|
||||
: null}
|
||||
<div className='flex items-center justify-center flex-col space-y-4 w-full lg:w-full'>
|
||||
<CardBox className='w-full md:w-3/5 lg:w-2/3'>
|
||||
<CardBoxComponentTitle title="Welcome to your Diego Coffee & Cocktail Studio app!"/>
|
||||
|
||||
<div className="space-y-3">
|
||||
<p className='text-center '>This is a React.js/Node.js app generated by the <a className={`${textColor}`} href="https://flatlogic.com/generator">Flatlogic Web App Generator</a></p>
|
||||
<p className='text-center '>For guides and documentation please check
|
||||
your local README.md and the <a className={`${textColor}`} href="https://flatlogic.com/documentation">Flatlogic documentation</a></p>
|
||||
</div>
|
||||
|
||||
<BaseButtons>
|
||||
<BaseButton
|
||||
href='/login'
|
||||
label='Login'
|
||||
color='info'
|
||||
className='w-full'
|
||||
/>
|
||||
const DiegoHero = () => (
|
||||
<section id="home" className="relative min-h-screen flex items-center justify-center bg-diego-navy text-white overflow-hidden">
|
||||
<div className="absolute inset-0 opacity-20">
|
||||
<div className="absolute top-20 left-10 w-96 h-96 bg-diego-orange rounded-full blur-[120px] animate-pulse"></div>
|
||||
<div className="absolute bottom-20 right-10 w-[500px] h-[500px] bg-blue-500 rounded-full blur-[150px] animate-pulse delay-700"></div>
|
||||
</div>
|
||||
<div className="container mx-auto px-6 relative z-10 text-center">
|
||||
<div className="mb-8 inline-block animate-chaos-shake">
|
||||
<BaseIcon path={mdiCreation} size={64} className="text-diego-orange animate-sparkle" />
|
||||
</div>
|
||||
<h1 className="text-7xl md:text-[12rem] font-heading text-diego-orange mb-4 drop-shadow-2xl hover:rotate-2 transition-transform cursor-default select-none">
|
||||
Diego
|
||||
</h1>
|
||||
<p className="text-2xl md:text-5xl font-light mb-12 italic tracking-[0.2em] uppercase opacity-90">
|
||||
Coffee • Cocktails • Chaos 💙
|
||||
</p>
|
||||
<h2 className="text-4xl md:text-6xl font-bold mb-16 max-w-4xl mx-auto leading-[1.1] tracking-tight">
|
||||
A little playground in Lucena. <br className="hidden md:block" />
|
||||
<span className="text-diego-orange bg-white/5 px-4 rounded-3xl backdrop-blur-sm">Beautifully unhinged.</span>
|
||||
</h2>
|
||||
<div className="flex flex-col md:flex-row items-center justify-center space-y-6 md:space-y-0 md:space-x-8">
|
||||
<a href="#menu" className="group bg-diego-orange hover:bg-orange-600 text-white px-12 py-5 rounded-full text-2xl font-black transition-all transform hover:scale-110 shadow-[0_20px_50px_rgba(255,117,24,0.4)] flex items-center space-x-4">
|
||||
<span>Drink the feelings</span>
|
||||
<BaseIcon path={mdiArrowDown} size={24} className="group-hover:translate-y-1 transition-transform" />
|
||||
</a>
|
||||
<a href="#contact" className="border-4 border-white hover:bg-white hover:text-diego-navy text-white px-12 py-5 rounded-full text-2xl font-black transition-all transform hover:scale-105 uppercase tracking-widest">
|
||||
Play with Diego
|
||||
</a>
|
||||
</div>
|
||||
<div className="mt-20">
|
||||
<p className="text-white/40 font-black text-sm uppercase tracking-[0.5em] animate-bounce">This is your sign</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
</BaseButtons>
|
||||
</CardBox>
|
||||
const BrandStory = () => (
|
||||
<section id="about" className="py-32 bg-white text-diego-navy relative overflow-hidden">
|
||||
<div className="absolute top-0 right-0 -mr-20 -mt-20 w-96 h-96 bg-diego-orange/5 rounded-full blur-3xl"></div>
|
||||
<div className="container mx-auto px-6">
|
||||
<div className="flex flex-col lg:flex-row items-center gap-20">
|
||||
<div className="lg:w-1/2 mb-12 lg:mb-0">
|
||||
<div className="inline-block px-6 py-2 bg-diego-navy text-white text-sm font-black rounded-full mb-10 uppercase tracking-[0.3em]">The Brand Story</div>
|
||||
<h2 className="text-6xl md:text-9xl font-heading text-diego-orange mb-10 -ml-2 leading-none">Our Story</h2>
|
||||
<p className="text-2xl md:text-4xl leading-snug mb-10 font-light tracking-tight">
|
||||
Mabuhay to Diego! From beachfront brews to cozy haunts, we bring fun to every sip.
|
||||
Diego is more than just a shop; it's your <span className="font-bold underline decoration-diego-orange decoration-[10px] underline-offset-8">playground in Quezon</span>.
|
||||
</p>
|
||||
<div className="relative mb-12">
|
||||
<div className="absolute -left-10 top-0 bottom-0 w-2 bg-diego-orange rounded-full"></div>
|
||||
<p className="text-2xl leading-relaxed italic text-diego-navy/70 pl-6">
|
||||
"Making specialty coffee and cocktails accessible, fun, and beautifully chaotic for everyone."
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-10 bg-diego-navy text-white rounded-[4rem] rounded-tr-none shadow-2xl transform -rotate-1 hover:rotate-0 transition-transform relative group">
|
||||
<div className="absolute -top-6 -right-6 w-20 h-20 bg-diego-orange rounded-full flex items-center justify-center animate-chaos-shake group-hover:scale-110 transition-transform">
|
||||
<BaseIcon path={mdiCreation} size={32} color="white" />
|
||||
</div>
|
||||
<h3 className="text-4xl font-heading mb-6 text-diego-orange">Celebrating 2 Years!</h3>
|
||||
<p className="text-xl opacity-90">Our main playground in Pleasantville, Lucena is still the heart of the chaos. Join the party! #PlayWithDiego</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="lg:w-1/2 relative">
|
||||
<div className="grid grid-cols-2 gap-6 relative z-10">
|
||||
<div className="space-y-6">
|
||||
<div className="h-80 bg-diego-navy rounded-4xl overflow-hidden shadow-2xl transform -rotate-2">
|
||||
<img src="https://images.pexels.com/photos/1233528/pexels-photo-1233528.jpeg?auto=compress&cs=tinysrgb&w=800" alt="Drink" className="w-full h-full object-cover" />
|
||||
</div>
|
||||
<div className="h-64 bg-diego-orange rounded-4xl overflow-hidden shadow-2xl transform rotate-2">
|
||||
<img src="https://images.pexels.com/photos/312418/pexels-photo-312418.jpeg?auto=compress&cs=tinysrgb&w=800" alt="Vibe" className="w-full h-full object-cover" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-6 mt-12">
|
||||
<div className="h-64 bg-gray-200 rounded-4xl overflow-hidden shadow-2xl transform rotate-3">
|
||||
<img src="https://images.pexels.com/photos/1015568/pexels-photo-1015568.jpeg?auto=compress&cs=tinysrgb&w=800" alt="Shop" className="w-full h-full object-cover" />
|
||||
</div>
|
||||
<div className="h-80 bg-diego-navy rounded-4xl overflow-hidden shadow-2xl transform -rotate-1">
|
||||
<img src="https://images.pexels.com/photos/2396220/pexels-photo-2396220.jpeg?auto=compress&cs=tinysrgb&w=800" alt="Details" className="w-full h-full object-cover" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute -bottom-10 -left-10 w-48 h-48 bg-white border-[12px] border-diego-orange rounded-full flex items-center justify-center text-diego-navy shadow-[0_30px_60px_rgba(0,0,0,0.1)] z-20 animate-spin-slow">
|
||||
<p className="text-center font-black text-2xl leading-tight">100%<br/>UNHINGED</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</SectionFullScreen>
|
||||
<div className='bg-black text-white flex flex-col text-center justify-center md:flex-row'>
|
||||
<p className='py-6 text-sm'>© 2026 <span>{title}</span>. All rights reserved</p>
|
||||
<Link className='py-6 ml-4 text-sm' href='/privacy-policy/'>
|
||||
Privacy Policy
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
const MenuPreview = () => {
|
||||
const [activeTab, setActiveTab] = useState('Coffee');
|
||||
const [items, setItems] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [selectedItem, setSelectedItem] = useState<any>(null);
|
||||
|
||||
const categories = [
|
||||
{ name: 'Coffee', icon: mdiCoffee },
|
||||
{ name: 'Cocktail', icon: mdiGlassCocktail },
|
||||
{ name: 'Food', icon: mdiHamburger }
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
const fetchItems = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const response = await axios.get('/menu_items');
|
||||
setItems(response.data.rows || []);
|
||||
} catch (error) {
|
||||
console.error('Error fetching menu items:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
fetchItems();
|
||||
}, []);
|
||||
|
||||
const filteredItems = items.filter(item => item.item_type === activeTab);
|
||||
|
||||
return (
|
||||
<section id="menu" className="py-32 bg-gray-50 relative overflow-hidden">
|
||||
<div className="absolute top-1/2 left-0 w-96 h-96 bg-diego-orange/5 blur-3xl rounded-full"></div>
|
||||
<div className="container mx-auto px-6 text-center relative z-10">
|
||||
<h2 className="text-7xl md:text-9xl font-heading text-diego-orange mb-6">Playground Menu</h2>
|
||||
<p className="mb-20 text-2xl font-black tracking-[0.3em] text-diego-navy uppercase opacity-60 italic">Experiment with flavors</p>
|
||||
|
||||
<div className="flex flex-wrap justify-center mb-20 gap-6">
|
||||
{categories.map((cat) => (
|
||||
<button
|
||||
key={cat.name}
|
||||
onClick={() => setActiveTab(cat.name)}
|
||||
className={`flex items-center space-x-4 px-10 py-5 rounded-[2rem] transition-all transform duration-300 ${
|
||||
activeTab === cat.name
|
||||
? 'bg-diego-orange text-white scale-110 shadow-[0_20px_40px_rgba(255,117,24,0.3)] rotate-2'
|
||||
: 'bg-white text-diego-navy hover:bg-gray-100 hover:scale-105 shadow-md'
|
||||
}`}
|
||||
>
|
||||
<BaseIcon path={cat.icon} size={32} />
|
||||
<span className="font-black text-xl uppercase tracking-widest">{cat.name}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<div className="py-32 flex flex-col items-center">
|
||||
<div className="w-24 h-24 border-8 border-diego-orange border-t-transparent rounded-full animate-spin mb-8 shadow-xl"></div>
|
||||
<p className="font-black text-2xl text-diego-navy animate-pulse uppercase tracking-widest">Organizing the chaos...</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-12">
|
||||
{filteredItems.map((item, idx) => (
|
||||
<div
|
||||
key={item.id}
|
||||
onClick={() => setSelectedItem(item)}
|
||||
className={`group bg-white p-12 rounded-[4rem] shadow-xl hover:shadow-[0_40px_80px_rgba(0,0,0,0.1)] transition-all duration-500 border border-gray-100 text-left cursor-pointer relative overflow-hidden ${idx % 2 === 0 ? 'lg:translate-y-12' : ''}`}
|
||||
>
|
||||
<div className="absolute top-0 right-0 w-32 h-32 bg-diego-orange/5 rounded-bl-[4rem] transition-all group-hover:bg-diego-orange/20"></div>
|
||||
{item.is_featured && (
|
||||
<div className="absolute top-6 left-6 bg-diego-orange text-white px-4 py-1 rounded-full text-[10px] font-black uppercase tracking-widest animate-sparkle shadow-lg">
|
||||
Must Try
|
||||
</div>
|
||||
)}
|
||||
<div className="flex justify-between items-start mb-8 relative z-10 pt-4">
|
||||
<h3 className="text-4xl font-bold group-hover:text-diego-orange transition-colors leading-tight pr-4">{item.title}</h3>
|
||||
<div className="flex flex-col items-end">
|
||||
<span className="text-diego-orange font-black text-3xl">₱{item.price}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-gray-500 mb-10 text-xl leading-relaxed relative z-10 font-light">{item.description}</p>
|
||||
<div className="flex items-center justify-between relative z-10">
|
||||
<div className="flex items-center space-x-3 text-sm font-black text-diego-navy uppercase tracking-widest group-hover:text-diego-orange transition-all">
|
||||
<span>View Ingredients</span>
|
||||
<BaseIcon path={mdiCreation} size={20} className="group-hover:rotate-45 transition-transform" />
|
||||
</div>
|
||||
<div className="w-12 h-12 rounded-2xl bg-gray-50 flex items-center justify-center group-hover:bg-diego-orange group-hover:text-white transition-colors">
|
||||
<BaseIcon path={mdiArrowDown} size={20} className="-rotate-90" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-32 p-16 bg-diego-navy rounded-[5rem] text-white inline-block shadow-2xl transform rotate-1 relative overflow-hidden group">
|
||||
<div className="absolute inset-0 bg-diego-orange opacity-0 group-hover:opacity-10 transition-opacity"></div>
|
||||
<p className="text-3xl font-heading mb-4 italic">Feeling adventurous?</p>
|
||||
<p className="text-diego-orange text-2xl font-black tracking-[0.3em] uppercase animate-pulse">Ask our Baristas for the "Chaos special"!</p>
|
||||
<div className="absolute -bottom-10 -right-10 opacity-10 rotate-12 group-hover:scale-125 transition-transform">
|
||||
<BaseIcon path={mdiCreation} size={150} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CardBoxModal
|
||||
title={selectedItem?.title || ''}
|
||||
buttonColor="diegoOrange"
|
||||
buttonLabel="Got it!"
|
||||
isActive={!!selectedItem}
|
||||
onConfirm={() => setSelectedItem(null)}
|
||||
onCancel={() => setSelectedItem(null)}
|
||||
>
|
||||
<div className="p-6">
|
||||
<div className="flex items-center justify-center mb-10">
|
||||
<div className="w-24 h-24 bg-diego-orange/10 rounded-4xl flex items-center justify-center animate-chaos-shake">
|
||||
<BaseIcon path={mdiCreation} size={48} className="text-diego-orange" />
|
||||
</div>
|
||||
</div>
|
||||
<h4 className="text-diego-navy font-black uppercase tracking-[0.3em] text-xs mb-6 text-center opacity-50">
|
||||
What's inside the chaos
|
||||
</h4>
|
||||
<p className="text-3xl italic mb-10 text-center leading-tight">"{selectedItem?.description}"</p>
|
||||
<div className="flex flex-wrap justify-center gap-4 mb-10">
|
||||
{selectedItem?.ingredients?.split(',').map((ing: string, i: number) => (
|
||||
<span key={i} className="bg-diego-navy/5 px-6 py-3 rounded-2xl text-lg font-bold border border-diego-navy/5 text-diego-navy">
|
||||
{ing.trim()}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-10 pt-10 border-t-4 border-dashed border-gray-100 flex items-center justify-between">
|
||||
<div>
|
||||
<p className="font-heading text-3xl text-diego-navy">Diego Special</p>
|
||||
<p className="text-[10px] font-black uppercase tracking-[0.4em] text-diego-orange">#PlayWithDiego</p>
|
||||
</div>
|
||||
<span className="text-5xl font-black text-diego-orange">₱{selectedItem?.price}</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardBoxModal>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
const ContactBooking = ({ locations }: { locations: any[] }) => {
|
||||
const [activeForm, setActiveForm] = useState<'reservation' | 'pitch'>('reservation');
|
||||
const [formData, setFormData] = useState<any>({});
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [success, setSuccess] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
|
||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setSubmitting(true);
|
||||
setSuccess(false);
|
||||
setError('');
|
||||
|
||||
try {
|
||||
if (activeForm === 'reservation') {
|
||||
await axios.post('/reservations', {
|
||||
data: {
|
||||
...formData,
|
||||
reservation_start: new Date(formData.date + 'T' + formData.time),
|
||||
status: 'pending'
|
||||
}
|
||||
});
|
||||
} else {
|
||||
await axios.post('/pitches', {
|
||||
data: {
|
||||
...formData,
|
||||
submitted_at: new Date(),
|
||||
notified: false
|
||||
}
|
||||
});
|
||||
}
|
||||
setSuccess(true);
|
||||
setFormData({});
|
||||
} catch (err: any) {
|
||||
console.error('Form submission error:', err);
|
||||
setError(err.response?.data?.message || 'Something went wrong. Chaos in the server!');
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="contact" className="py-32 bg-diego-navy text-white relative overflow-hidden">
|
||||
<div className="absolute top-0 right-0 w-[800px] h-[800px] bg-diego-orange opacity-5 rounded-full -mr-[400px] -mt-[400px]"></div>
|
||||
<div className="container mx-auto px-6 relative z-10">
|
||||
<div className="flex flex-col lg:flex-row gap-24 items-center">
|
||||
<div className="lg:w-1/2">
|
||||
<h2 className="text-7xl md:text-9xl font-heading text-diego-orange mb-10 leading-none">Let's Play</h2>
|
||||
<p className="text-3xl md:text-4xl mb-16 font-light leading-snug opacity-90">
|
||||
Planning a birthday, wedding, or corporate event? Or maybe you have a wild collaboration idea?
|
||||
<span className="block mt-6 text-diego-orange font-bold text-5xl italic tracking-tighter animate-chaos-shake">"This is your sign"</span>
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-1 gap-8 mb-16">
|
||||
<div className="flex items-center space-x-8 p-10 bg-white/5 rounded-[3rem] hover:bg-white/10 transition-all border border-white/10 group cursor-default">
|
||||
<div className="bg-diego-orange p-6 rounded-3xl shadow-2xl group-hover:rotate-12 transition-transform">
|
||||
<BaseIcon path={mdiEmail} size={40} color="white" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-[10px] uppercase tracking-[0.4em] text-white/40 mb-2 font-black">Pitch your idea</p>
|
||||
<p className="text-3xl font-bold group-hover:text-diego-orange transition-colors">hello@diego.ph</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-8 p-10 bg-white/5 rounded-[3rem] hover:bg-white/10 transition-all border border-white/10 group cursor-default">
|
||||
<div className="bg-diego-orange p-6 rounded-3xl shadow-2xl group-hover:-rotate-12 transition-transform">
|
||||
<BaseIcon path={mdiMapMarker} size={40} color="white" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-[10px] uppercase tracking-[0.4em] text-white/40 mb-2 font-black">The Playgrounds</p>
|
||||
<p className="text-3xl font-bold group-hover:text-diego-orange transition-colors">Lucena • Sariaya</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-12 border-4 border-dashed border-white/10 rounded-[4rem] opacity-40 hover:opacity-100 transition-opacity text-center lg:text-left">
|
||||
<p className="font-heading text-4xl mb-4 italic text-diego-orange">Play with Diego</p>
|
||||
<p className="uppercase tracking-[0.5em] text-sm font-black opacity-60">#DiegoByAteLorie #PlayWithDiego</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="lg:w-1/2 w-full">
|
||||
<div className="bg-white text-diego-navy p-12 md:p-20 rounded-[5rem] shadow-[0_50px_100px_rgba(0,0,0,0.3)] relative overflow-hidden transform lg:rotate-1">
|
||||
<div className="flex mb-12 bg-gray-100 p-3 rounded-[2.5rem]">
|
||||
<button
|
||||
onClick={() => { setActiveForm('reservation'); setSuccess(false); }}
|
||||
className={`flex-1 py-5 rounded-[2rem] font-black uppercase tracking-widest text-xs transition-all duration-300 ${activeForm === 'reservation' ? 'bg-diego-orange text-white shadow-2xl' : 'text-diego-navy hover:bg-gray-200'}`}
|
||||
>
|
||||
Book Your Chaos
|
||||
</button>
|
||||
<button
|
||||
onClick={() => { setActiveForm('pitch'); setSuccess(false); }}
|
||||
className={`flex-1 py-5 rounded-[2rem] font-black uppercase tracking-widest text-xs transition-all duration-300 ${activeForm === 'pitch' ? 'bg-diego-orange text-white shadow-2xl' : 'text-diego-navy hover:bg-gray-200'}`}
|
||||
>
|
||||
Pitch an Idea
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{success ? (
|
||||
<div className="py-24 text-center animate-fade-in">
|
||||
<div className="w-32 h-32 bg-green-100 text-green-600 rounded-full flex items-center justify-center mx-auto mb-10 shadow-inner">
|
||||
<BaseIcon path={mdiCreation} size={64} className="animate-sparkle" />
|
||||
</div>
|
||||
<h3 className="text-5xl font-heading mb-6 text-diego-orange">Message Received!</h3>
|
||||
<p className="text-2xl text-gray-500 mb-12 font-light">The chaos is being organized. We'll get back to you soon!</p>
|
||||
<button
|
||||
onClick={() => setSuccess(false)}
|
||||
className="bg-diego-navy text-white px-10 py-4 rounded-2xl font-black uppercase tracking-widest text-xs hover:bg-diego-orange transition-colors shadow-xl"
|
||||
>
|
||||
Send another plan
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<form onSubmit={handleSubmit} className="space-y-10 animate-fade-in">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-10">
|
||||
<div className="relative group">
|
||||
<label className="block text-[10px] font-black mb-4 uppercase tracking-[0.3em] text-gray-400 group-focus-within:text-diego-orange transition-colors">Your Name</label>
|
||||
<input
|
||||
required
|
||||
name="name"
|
||||
value={formData.name || ''}
|
||||
onChange={handleInputChange}
|
||||
type="text"
|
||||
className="w-full bg-gray-50 border-4 border-transparent border-b-gray-100 focus:border-b-diego-orange rounded-2xl px-8 py-5 focus:outline-none transition-all font-bold text-lg"
|
||||
placeholder="Diego de la Vega"
|
||||
/>
|
||||
</div>
|
||||
<div className="relative group">
|
||||
<label className="block text-[10px] font-black mb-4 uppercase tracking-[0.3em] text-gray-400 group-focus-within:text-diego-orange transition-colors">Your Email</label>
|
||||
<input
|
||||
required
|
||||
name="email"
|
||||
value={formData.email || ''}
|
||||
onChange={handleInputChange}
|
||||
type="email"
|
||||
className="w-full bg-gray-50 border-4 border-transparent border-b-gray-100 focus:border-b-diego-orange rounded-2xl px-8 py-5 focus:outline-none transition-all font-bold text-lg"
|
||||
placeholder="diego@play.ph"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{activeForm === 'reservation' ? (
|
||||
<>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-10">
|
||||
<div className="relative group">
|
||||
<label className="block text-[10px] font-black mb-4 uppercase tracking-[0.3em] text-gray-400 group-focus-within:text-diego-orange transition-colors">Date</label>
|
||||
<input
|
||||
required
|
||||
name="date"
|
||||
value={formData.date || ''}
|
||||
onChange={handleInputChange}
|
||||
type="date"
|
||||
className="w-full bg-gray-50 border-4 border-transparent border-b-gray-100 focus:border-b-diego-orange rounded-2xl px-8 py-5 focus:outline-none transition-all font-bold text-lg"
|
||||
/>
|
||||
</div>
|
||||
<div className="relative group">
|
||||
<label className="block text-[10px] font-black mb-4 uppercase tracking-[0.3em] text-gray-400 group-focus-within:text-diego-orange transition-colors">Time</label>
|
||||
<input
|
||||
required
|
||||
name="time"
|
||||
value={formData.time || ''}
|
||||
onChange={handleInputChange}
|
||||
type="time"
|
||||
className="w-full bg-gray-50 border-4 border-transparent border-b-gray-100 focus:border-b-diego-orange rounded-2xl px-8 py-5 focus:outline-none transition-all font-bold text-lg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-10">
|
||||
<div className="relative group">
|
||||
<label className="block text-[10px] font-black mb-4 uppercase tracking-[0.3em] text-gray-400 group-focus-within:text-diego-orange transition-colors">Party Size</label>
|
||||
<input
|
||||
required
|
||||
name="party_size"
|
||||
value={formData.party_size || ''}
|
||||
onChange={handleInputChange}
|
||||
type="number"
|
||||
min="1"
|
||||
className="w-full bg-gray-50 border-4 border-transparent border-b-gray-100 focus:border-b-diego-orange rounded-2xl px-8 py-5 focus:outline-none transition-all font-bold text-lg"
|
||||
placeholder="2"
|
||||
/>
|
||||
</div>
|
||||
<div className="relative group">
|
||||
<label className="block text-[10px] font-black mb-4 uppercase tracking-[0.3em] text-gray-400 group-focus-within:text-diego-orange transition-colors">Location</label>
|
||||
<select
|
||||
required
|
||||
name="location"
|
||||
value={formData.location || ''}
|
||||
onChange={handleInputChange}
|
||||
className="w-full bg-gray-50 border-4 border-transparent border-b-gray-100 focus:border-b-diego-orange rounded-2xl px-8 py-5 focus:outline-none transition-all font-bold text-lg appearance-none cursor-pointer"
|
||||
>
|
||||
<option value="">Select Location</option>
|
||||
{locations.map(loc => (
|
||||
<option key={loc.id} value={loc.id}>{loc.name}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="relative group">
|
||||
<label className="block text-[10px] font-black mb-4 uppercase tracking-[0.3em] text-gray-400 group-focus-within:text-diego-orange transition-colors">Pitch Type</label>
|
||||
<select
|
||||
name="pitch_type"
|
||||
value={formData.pitch_type || 'event'}
|
||||
onChange={handleInputChange}
|
||||
className="w-full bg-gray-50 border-4 border-transparent border-b-gray-100 focus:border-b-diego-orange rounded-2xl px-8 py-5 focus:outline-none transition-all font-bold text-lg appearance-none cursor-pointer"
|
||||
>
|
||||
<option value="event">Event Space</option>
|
||||
<option value="collaboration">Brand Collaboration</option>
|
||||
<option value="sponsorship">Sponsorship</option>
|
||||
<option value="other">Something Else</option>
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="relative group">
|
||||
<label className="block text-[10px] font-black mb-4 uppercase tracking-[0.3em] text-gray-400 group-focus-within:text-diego-orange transition-colors">The Message</label>
|
||||
<textarea
|
||||
required
|
||||
name="message"
|
||||
value={formData.message || ''}
|
||||
onChange={handleInputChange}
|
||||
rows={4}
|
||||
className="w-full bg-gray-50 border-4 border-transparent border-b-gray-100 focus:border-b-diego-orange rounded-2xl px-8 py-5 focus:outline-none transition-all font-bold text-lg"
|
||||
placeholder="Tell us about your chaotic plan..."
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
{error && <p className="text-red-500 font-bold text-sm bg-red-50 p-6 rounded-2xl border-l-8 border-red-500 animate-chaos-shake">{error}</p>}
|
||||
|
||||
<button
|
||||
disabled={submitting}
|
||||
className={`group w-full bg-diego-orange hover:bg-orange-600 text-white font-black py-6 rounded-[2.5rem] transition-all duration-300 shadow-[0_20px_50px_rgba(255,117,24,0.3)] transform hover:-translate-y-2 flex items-center justify-center space-x-6 ${submitting ? 'opacity-50 cursor-not-allowed' : ''}`}
|
||||
>
|
||||
<span className="uppercase tracking-[0.4em] text-xl">{submitting ? 'Sending...' : 'Let's Play!'}</span>
|
||||
{!submitting && <BaseIcon path={mdiCreation} size={32} className="group-hover:rotate-180 transition-transform duration-500" />}
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
const Locations = ({ locations }: { locations: any[] }) => {
|
||||
return (
|
||||
<section id="locations" className="py-32 bg-white relative overflow-hidden">
|
||||
<div className="container mx-auto px-6 text-center">
|
||||
<h2 className="text-7xl md:text-[10rem] font-heading text-diego-orange mb-12 leading-none">Find the Chaos</h2>
|
||||
<p className="mb-24 text-2xl font-black tracking-[0.5em] text-diego-navy uppercase opacity-30 italic">Locate the Playground</p>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-16 mb-32">
|
||||
{locations.map((loc) => (
|
||||
<div key={loc.id} className="group cursor-default relative">
|
||||
<div className="h-96 bg-diego-navy rounded-[4rem] overflow-hidden mb-10 shadow-2xl relative border-8 border-white group-hover:rotate-2 transition-transform duration-500">
|
||||
<div className="absolute inset-0 bg-diego-navy/40 group-hover:bg-diego-navy/10 transition-colors z-10"></div>
|
||||
<img
|
||||
src={loc.name.includes('Lucena') ? "https://images.pexels.com/photos/1233528/pexels-photo-1233528.jpeg" : "https://images.pexels.com/photos/312418/pexels-photo-312418.jpeg"}
|
||||
alt={loc.name}
|
||||
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
|
||||
/>
|
||||
<div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity z-20">
|
||||
<div className="bg-white/90 backdrop-blur-md p-6 rounded-3xl shadow-2xl">
|
||||
<BaseIcon path={mdiMapMarker} size={48} className="text-diego-orange animate-bounce" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 className="text-4xl font-black text-diego-navy mb-4 group-hover:text-diego-orange transition-colors uppercase tracking-tighter leading-none">{loc.name}</h3>
|
||||
<p className="text-xl text-gray-400 mb-8 font-medium italic max-w-xs mx-auto">{loc.address}</p>
|
||||
<div className="inline-flex items-center space-x-3 bg-diego-navy text-white px-8 py-4 rounded-3xl shadow-xl group-hover:bg-diego-orange transition-colors">
|
||||
<BaseIcon path={mdiCalendarClock} size={24} className="text-diego-orange group-hover:text-white" />
|
||||
<span className="font-black text-xs uppercase tracking-[0.2em]">{loc.hours}</span>
|
||||
</div>
|
||||
{loc.name.includes('Lucban') && (
|
||||
<div className="mt-8 bg-red-50 text-red-600 px-6 py-3 rounded-2xl font-black uppercase tracking-widest text-[10px] animate-pulse border-2 border-red-100 inline-block">
|
||||
⚠️ Closing soon - Still open til Jan 24!
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-50 p-20 rounded-[5rem] border-4 border-dashed border-gray-200 max-w-5xl mx-auto relative overflow-hidden group">
|
||||
<div className="absolute -top-10 -left-10 w-40 h-40 bg-diego-orange/5 rounded-full group-hover:scale-150 transition-transform duration-700"></div>
|
||||
<h4 className="text-4xl font-heading mb-12 text-diego-navy">Special Holiday Hours</h4>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 text-left relative z-10">
|
||||
<div className="p-10 bg-white rounded-[3rem] shadow-xl border border-gray-100 transform -rotate-1 group-hover:rotate-0 transition-transform">
|
||||
<p className="font-black text-diego-orange uppercase text-xs tracking-[0.4em] mb-4">Dec 23 & 26–30</p>
|
||||
<p className="text-3xl font-bold text-diego-navy">3PM – 11PM</p>
|
||||
</div>
|
||||
<div className="p-10 bg-white rounded-[3rem] shadow-xl border border-gray-100 opacity-40 transform rotate-1 group-hover:rotate-0 transition-transform">
|
||||
<p className="font-black text-gray-400 uppercase text-xs tracking-[0.4em] mb-4">Dec 24–25 & 31</p>
|
||||
<p className="text-3xl font-bold text-gray-400 italic underline decoration-red-500 decoration-4">Closed for the Chaos</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default function DiegoApp() {
|
||||
const title = 'Diego Coffee & Cocktail Studio';
|
||||
const [locations, setLocations] = useState<any[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
axios.get('/locations').then(res => setLocations(res.data.rows || []));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="scroll-smooth font-sans text-diego-navy selection:bg-diego-orange selection:text-white bg-white">
|
||||
<Head>
|
||||
<title>{getPageTitle('Diego')}</title>
|
||||
<meta name="description" content="Diego Coffee & Cocktail Studio - Your playground in Quezon Province. Coffee, Cocktails, Chaos." />
|
||||
</Head>
|
||||
|
||||
<Navbar />
|
||||
<DecorativeElements />
|
||||
|
||||
<main>
|
||||
<DiegoHero />
|
||||
<BrandStory />
|
||||
<MenuPreview />
|
||||
<Locations locations={locations} />
|
||||
<ContactBooking locations={locations} />
|
||||
</main>
|
||||
|
||||
<footer className="bg-diego-navy text-white py-32 border-t border-white/5 relative overflow-hidden">
|
||||
<div className="absolute bottom-0 right-0 w-[600px] h-[600px] bg-diego-orange opacity-5 rounded-full -mb-[300px] -mr-[300px]"></div>
|
||||
<div className="container mx-auto px-6 relative z-10">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-4 gap-20 mb-20">
|
||||
<div className="lg:col-span-2">
|
||||
<h3 className="text-7xl font-heading text-diego-orange mb-8 leading-none">Diego</h3>
|
||||
<p className="text-2xl opacity-60 italic mb-12 max-w-md font-light leading-relaxed">
|
||||
Your little playground in Lucena and beyond. Drink the feelings, embrace the chaos, and play with Diego.
|
||||
</p>
|
||||
<div className="flex space-x-6">
|
||||
{['instagram', 'facebook', 'tiktok'].map(social => (
|
||||
<a key={social} href="#" className="w-16 h-16 bg-white/5 rounded-3xl flex items-center justify-center hover:bg-diego-orange hover:-translate-y-2 transition-all transform hover:rotate-12 group">
|
||||
<BaseIcon path={mdiCreation} size={28} className="group-hover:animate-chaos-shake" />
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-12 lg:col-span-2">
|
||||
<div>
|
||||
<h4 className="font-black uppercase tracking-[0.4em] text-xs mb-10 text-white/30">Navigation</h4>
|
||||
<ul className="space-y-6 text-xl font-bold">
|
||||
<li><a href="#home" className="hover:text-diego-orange transition-colors">Home</a></li>
|
||||
<li><a href="#about" className="hover:text-diego-orange transition-colors">The Story</a></li>
|
||||
<li><a href="#menu" className="hover:text-diego-orange transition-colors">Playground Menu</a></li>
|
||||
<li><a href="#locations" className="hover:text-diego-orange transition-colors">Locations</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-black uppercase tracking-[0.4em] text-xs mb-10 text-white/30">Admin & Legal</h4>
|
||||
<ul className="space-y-6 text-xl font-bold mb-12">
|
||||
<li><Link href="/privacy-policy" className="hover:text-diego-orange transition-colors">Privacy Chaos</Link></li>
|
||||
<li><Link href="/terms-of-use" className="hover:text-diego-orange transition-colors">Rules of the Playground</Link></li>
|
||||
</ul>
|
||||
<Link href="/login" className="inline-flex bg-diego-orange text-white px-10 py-5 rounded-3xl font-black uppercase tracking-[0.2em] text-xs hover:bg-white hover:text-diego-navy transition-all shadow-2xl transform -rotate-2 hover:rotate-0">
|
||||
Admin Portal
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pt-12 border-t border-white/10 flex flex-col md:flex-row justify-between items-center gap-8">
|
||||
<div className="text-center md:text-left">
|
||||
<p className="text-sm opacity-40 font-bold mb-2">© 2026 <span>{title}</span>. All feelings reserved.</p>
|
||||
<p className="text-[10px] uppercase tracking-[0.8em] opacity-20 font-black">Beautifully unhinged</p>
|
||||
</div>
|
||||
<div className="bg-white/5 px-8 py-4 rounded-2xl backdrop-blur-sm border border-white/5">
|
||||
<p className="text-xs uppercase tracking-[0.4em] text-diego-orange font-black">#PlayWithDiego</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Starter.getLayout = function getLayout(page: ReactElement) {
|
||||
DiegoApp.getLayout = function getLayout(page: ReactElement) {
|
||||
return <LayoutGuest>{page}</LayoutGuest>;
|
||||
};
|
||||
|
||||
};
|
||||
@ -6,7 +6,7 @@ module.exports = {
|
||||
content: [
|
||||
'./src/**/*.{js,ts,jsx,tsx}',
|
||||
],
|
||||
darkMode: 'class', // or 'media' or 'class'
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
asideScrollbars: {
|
||||
light: 'light',
|
||||
@ -35,13 +35,46 @@ module.exports = {
|
||||
'fade-in': {
|
||||
from: { opacity: 0 },
|
||||
to: { opacity: 1 }
|
||||
},
|
||||
'chaos-shake': {
|
||||
'0%, 100%': { transform: 'translateX(0) rotate(0)' },
|
||||
'10%': { transform: 'translateX(-2px) rotate(-1deg)' },
|
||||
'20%': { transform: 'translateX(2px) rotate(1deg)' },
|
||||
'30%': { transform: 'translateX(-2px) rotate(-1deg)' },
|
||||
'40%': { transform: 'translateX(2px) rotate(1deg)' },
|
||||
'50%': { transform: 'translateX(-2px) rotate(-1deg)' },
|
||||
'60%': { transform: 'translateX(2px) rotate(1deg)' },
|
||||
'70%': { transform: 'translateX(-2px) rotate(-1deg)' },
|
||||
'80%': { transform: 'translateX(2px) rotate(1deg)' },
|
||||
'90%': { transform: 'translateX(-2px) rotate(-1deg)' }
|
||||
},
|
||||
'sparkle': {
|
||||
'0%, 100%': { opacity: 1, transform: 'scale(1)' },
|
||||
'50%': { opacity: 0.5, transform: 'scale(1.2)' }
|
||||
},
|
||||
'float': {
|
||||
'0%, 100%': { transform: 'translateY(0)' },
|
||||
'50%': { transform: 'translateY(-20px)' }
|
||||
},
|
||||
'spin-slow': {
|
||||
from: { transform: 'rotate(0deg)' },
|
||||
to: { transform: 'rotate(360deg)' }
|
||||
}
|
||||
},
|
||||
animation: {
|
||||
'fade-out': 'fade-out 250ms ease-in-out',
|
||||
'fade-in': 'fade-in 250ms ease-in-out'
|
||||
'fade-in': 'fade-in 250ms ease-in-out',
|
||||
'chaos-shake': 'chaos-shake 0.5s ease-in-out infinite',
|
||||
'sparkle': 'sparkle 1.5s ease-in-out infinite',
|
||||
'float': 'float 3s ease-in-out infinite',
|
||||
'spin-slow': 'spin-slow 8s linear infinite',
|
||||
},
|
||||
colors: {
|
||||
diego: {
|
||||
orange: '#FF7518',
|
||||
navy: '#001F3F',
|
||||
accent: '#FF7518',
|
||||
},
|
||||
dark: {
|
||||
900: '#131618',
|
||||
800: '#21242A',
|
||||
@ -65,9 +98,7 @@ module.exports = {
|
||||
400: '#EFF0F6',
|
||||
300: '#F7F7FC'
|
||||
},
|
||||
|
||||
|
||||
midnightBlueTheme: {
|
||||
midnightBlueTheme: {
|
||||
text: '#D4D7E2',
|
||||
iconsColor: '#5A7BEB',
|
||||
mainBG: '#1E2338',
|
||||
@ -87,10 +118,13 @@ module.exports = {
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Ubuntu', 'sans-serif'],
|
||||
|
||||
},
|
||||
borderRadius: {
|
||||
'3xl': '2rem',
|
||||
cursive: ['Pacifico', 'cursive'],
|
||||
heading: ['Pacifico', 'cursive'],
|
||||
},
|
||||
borderRadius: {
|
||||
'3xl': '2rem',
|
||||
'4xl': '3rem',
|
||||
'5xl': '4rem',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user