booty
This commit is contained in:
parent
c99032044d
commit
5cb66c5012
34 changed files with 1236 additions and 132 deletions
|
@ -4,6 +4,19 @@
|
||||||
* This file will be included onto the page via the importmap() Twig function,
|
* This file will be included onto the page via the importmap() Twig function,
|
||||||
* which should already be in your base.html.twig.
|
* which should already be in your base.html.twig.
|
||||||
*/
|
*/
|
||||||
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import './styles/app.css';
|
import './styles/app.css';
|
||||||
|
import './styles/modes.css';
|
||||||
|
import './styles/emoji-footprint.css';
|
||||||
|
|
||||||
import './javascript/htmx.js';
|
// Import modules
|
||||||
|
import './javascript/theme.js';
|
||||||
|
import './javascript/emoji-footprint.js';
|
||||||
|
import './javascript/modes.js';
|
||||||
|
import './javascript/htmx.js';
|
||||||
|
import 'bootstrap';
|
||||||
|
import { initRadioState } from './javascript/radioState.js';
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
initRadioState();
|
||||||
|
});
|
19
assets/javascript/emoji-footprint.js
Normal file
19
assets/javascript/emoji-footprint.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Sparkle effect on mouse move
|
||||||
|
document.addEventListener('mousemove', function (e) {
|
||||||
|
const emojis = ['✨', '💖', '🌟', '💅', '🦄', '🎉', '🌈'];
|
||||||
|
const sparkle = document.createElement('div');
|
||||||
|
sparkle.className = 'emoji-footprint';
|
||||||
|
sparkle.textContent = emojis[Math.floor(Math.random() * emojis.length)];
|
||||||
|
sparkle.style.left = e.pageX + 'px';
|
||||||
|
sparkle.style.top = e.pageY + 'px';
|
||||||
|
document.body.appendChild(sparkle);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
sparkle.remove();
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
export function initEmojiFootprint() {
|
||||||
|
// The sparkle effect is already initialized when this module is imported
|
||||||
|
// This function can be used if we need to control when the effect starts
|
||||||
|
}
|
136
assets/javascript/modes.js
Normal file
136
assets/javascript/modes.js
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
// Bonkers mode functionality
|
||||||
|
function setEmojiLevelClass(mode) {
|
||||||
|
document.body.classList.remove('emoji-normal', 'emoji-enhanced', 'emoji-bonkers');
|
||||||
|
if (mode === 'bonkers') {
|
||||||
|
document.body.classList.add('emoji-bonkers');
|
||||||
|
} else if (mode === 'enhanced') {
|
||||||
|
document.body.classList.add('emoji-enhanced');
|
||||||
|
} else {
|
||||||
|
document.body.classList.add('emoji-normal');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initBonkersMode() {
|
||||||
|
// Check if we're in bonkers mode
|
||||||
|
const currentMode = document.documentElement.getAttribute('data-website-mode');
|
||||||
|
setEmojiLevelClass(currentMode);
|
||||||
|
|
||||||
|
if (currentMode === 'bonkers') {
|
||||||
|
// Apply bonkers mode immediately
|
||||||
|
document.body.classList.add('bonkers-mode');
|
||||||
|
|
||||||
|
// Start the fabulous effects
|
||||||
|
createExtraSparkles();
|
||||||
|
createSlayEffects();
|
||||||
|
|
||||||
|
console.log('🌈✨ Bonkers mode activated! ✨🌈');
|
||||||
|
} else {
|
||||||
|
// Remove bonkers mode if it was active
|
||||||
|
document.body.classList.remove('bonkers-mode');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to create extra sparkles during bonkers mode
|
||||||
|
function createExtraSparkles() {
|
||||||
|
const currentMode = document.documentElement.getAttribute('data-website-mode');
|
||||||
|
if (currentMode !== 'bonkers') return;
|
||||||
|
|
||||||
|
const extraEmojis = [
|
||||||
|
'💃', '🕺',
|
||||||
|
'🍑', '💦', '😏', '😈', '👅', '💋', '🥵', '😳', '🤤', '😍', '🥴',
|
||||||
|
'💕', '💖', '💗', '💘', '💝', '💞', '💟', '💌', '💏', '💑',
|
||||||
|
'🍆', '🥒', '🍌', '💦', '👀', '😉', '😌', '😍', '🥰', '😘',
|
||||||
|
'😚', '😋', '😏', '😫', '😩', '🥺', '🥵', '🥴',
|
||||||
|
'💖', '💗', '💕', '💞', '💓', '💗', '💖', '💘', '💝',
|
||||||
|
'💋', '💏', '💑'
|
||||||
|
];
|
||||||
|
const sparkle = document.createElement('div');
|
||||||
|
sparkle.className = 'emoji-footprint';
|
||||||
|
sparkle.textContent = extraEmojis[Math.floor(Math.random() * extraEmojis.length)];
|
||||||
|
sparkle.style.left = Math.random() * window.innerWidth + 'px';
|
||||||
|
sparkle.style.top = Math.random() * window.innerHeight + 'px';
|
||||||
|
document.body.appendChild(sparkle);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (sparkle.parentNode) {
|
||||||
|
sparkle.remove();
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
// Continue creating extra sparkles while in bonkers mode
|
||||||
|
const newMode = document.documentElement.getAttribute('data-website-mode');
|
||||||
|
if (newMode === 'bonkers') {
|
||||||
|
setTimeout(() => createExtraSparkles(), 150);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to create slay effects
|
||||||
|
function createSlayEffects() {
|
||||||
|
const currentMode = document.documentElement.getAttribute('data-website-mode');
|
||||||
|
if (currentMode !== 'bonkers') return;
|
||||||
|
|
||||||
|
// Create floating "SLAY" text effects
|
||||||
|
const slayWords = [
|
||||||
|
'SLAY', 'QUEEN', 'FABULOUS', 'ICONIC', 'LEGENDARY', 'STUNNING', 'GORGEOUS', 'FLAWLESS',
|
||||||
|
'DAZZLING', 'RADIANT', 'BREATHTAKING', 'EXQUISITE', 'DIVINE'
|
||||||
|
];
|
||||||
|
const slayElement = document.createElement('div');
|
||||||
|
slayElement.className = 'slay-text';
|
||||||
|
slayElement.textContent = slayWords[Math.floor(Math.random() * slayWords.length)];
|
||||||
|
slayElement.style.left = Math.random() * window.innerWidth + 'px';
|
||||||
|
slayElement.style.top = Math.random() * window.innerHeight + 'px';
|
||||||
|
document.body.appendChild(slayElement);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (slayElement.parentNode) {
|
||||||
|
slayElement.remove();
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
// Continue creating slay effects while in bonkers mode
|
||||||
|
const newMode = document.documentElement.getAttribute('data-website-mode');
|
||||||
|
if (newMode === 'bonkers') {
|
||||||
|
setTimeout(() => createSlayEffects(), 800);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch for mode changes
|
||||||
|
function watchModeChanges() {
|
||||||
|
// Create a MutationObserver to watch for changes to the data-website-mode attribute
|
||||||
|
const observer = new MutationObserver(function(mutations) {
|
||||||
|
mutations.forEach(function(mutation) {
|
||||||
|
if (mutation.type === 'attributes' && mutation.attributeName === 'data-website-mode') {
|
||||||
|
const newMode = document.documentElement.getAttribute('data-website-mode');
|
||||||
|
|
||||||
|
if (newMode === 'bonkers') {
|
||||||
|
document.body.classList.add('bonkers-mode');
|
||||||
|
setEmojiLevelClass(newMode);
|
||||||
|
|
||||||
|
// Start the fabulous effects
|
||||||
|
createExtraSparkles();
|
||||||
|
createSlayEffects();
|
||||||
|
|
||||||
|
console.log('🌈✨ Switched to bonkers mode! ✨🌈');
|
||||||
|
} else {
|
||||||
|
document.body.classList.remove('bonkers-mode');
|
||||||
|
setEmojiLevelClass(newMode);
|
||||||
|
console.log(`😴 Switched to ${newMode} mode`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start observing
|
||||||
|
observer.observe(document.documentElement, {
|
||||||
|
attributes: true,
|
||||||
|
attributeFilter: ['data-website-mode']
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize when DOM is loaded
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
initBonkersMode();
|
||||||
|
watchModeChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
export { initBonkersMode, watchModeChanges };
|
55
assets/javascript/numberInputs.js
Normal file
55
assets/javascript/numberInputs.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// Function to initialize number input buttons
|
||||||
|
function initNumberInputs(container = document) {
|
||||||
|
container.querySelectorAll('.number-input-wrapper').forEach(function(wrapper) {
|
||||||
|
const input = wrapper.querySelector('input[type="number"]');
|
||||||
|
const decreaseBtn = wrapper.querySelector('[data-action="decrease"]');
|
||||||
|
const increaseBtn = wrapper.querySelector('[data-action="increase"]');
|
||||||
|
|
||||||
|
if (!input || !decreaseBtn || !increaseBtn) return;
|
||||||
|
|
||||||
|
// Skip if already initialized
|
||||||
|
if (decreaseBtn.hasAttribute('data-initialized')) return;
|
||||||
|
|
||||||
|
const step = parseFloat(input.getAttribute('step')) || 1;
|
||||||
|
const min = 0;
|
||||||
|
const max = input.getAttribute('max') ? parseFloat(input.getAttribute('max')) : null;
|
||||||
|
|
||||||
|
decreaseBtn.addEventListener('click', function() {
|
||||||
|
const currentValue = parseFloat(input.value) || 0;
|
||||||
|
const newValue = currentValue - step;
|
||||||
|
|
||||||
|
if (min === null || newValue >= min) {
|
||||||
|
input.value = newValue;
|
||||||
|
input.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
increaseBtn.addEventListener('click', function() {
|
||||||
|
const currentValue = parseFloat(input.value) || 0;
|
||||||
|
const newValue = currentValue + step;
|
||||||
|
|
||||||
|
if (max === null || newValue <= max) {
|
||||||
|
input.value = newValue;
|
||||||
|
input.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Validate input on change
|
||||||
|
input.addEventListener('input', function() {
|
||||||
|
const value = parseFloat(this.value);
|
||||||
|
|
||||||
|
if (min !== null && value < min) {
|
||||||
|
this.value = min;
|
||||||
|
}
|
||||||
|
if (max !== null && value > max) {
|
||||||
|
this.value = max;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Mark as initialized
|
||||||
|
decreaseBtn.setAttribute('data-initialized', 'true');
|
||||||
|
increaseBtn.setAttribute('data-initialized', 'true');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export { initNumberInputs };
|
35
assets/javascript/radioState.js
Normal file
35
assets/javascript/radioState.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Radio button state management with localStorage
|
||||||
|
function initRadioState() {
|
||||||
|
// Store and retrieve radio button state
|
||||||
|
const radioButtons = document.querySelectorAll('input[name="mode"]');
|
||||||
|
|
||||||
|
// Load saved state on page load
|
||||||
|
const savedMode = localStorage.getItem('selectedMode');
|
||||||
|
if (savedMode) {
|
||||||
|
const radioToCheck = document.getElementById(savedMode);
|
||||||
|
if (radioToCheck) {
|
||||||
|
radioToCheck.checked = true;
|
||||||
|
// Set the data attribute to match the saved mode
|
||||||
|
document.documentElement.setAttribute('data-website-mode', savedMode);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If no saved state, set to the currently checked radio button
|
||||||
|
const checkedRadio = document.querySelector('input[name="mode"]:checked');
|
||||||
|
if (checkedRadio) {
|
||||||
|
document.documentElement.setAttribute('data-website-mode', checkedRadio.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save state when radio button changes
|
||||||
|
radioButtons.forEach(radio => {
|
||||||
|
radio.addEventListener('change', function() {
|
||||||
|
if (this.checked) {
|
||||||
|
localStorage.setItem('selectedMode', this.id);
|
||||||
|
// Update the data attribute when mode changes
|
||||||
|
document.documentElement.setAttribute('data-website-mode', this.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export { initRadioState };
|
18
assets/javascript/theme.js
Normal file
18
assets/javascript/theme.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Theme detection and switching
|
||||||
|
const getPreferredTheme = () => {
|
||||||
|
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
|
const setTheme = theme => {
|
||||||
|
document.documentElement.setAttribute('data-bs-theme', theme)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set initial theme
|
||||||
|
setTheme(getPreferredTheme())
|
||||||
|
|
||||||
|
// Listen for changes in user's preferred color scheme
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
||||||
|
setTheme(getPreferredTheme())
|
||||||
|
})
|
||||||
|
|
||||||
|
export { getPreferredTheme, setTheme };
|
|
@ -1,3 +1,179 @@
|
||||||
body {
|
/*
|
||||||
background-color: skyblue;
|
* =================================================================================================
|
||||||
}
|
* 💖 BUBBLEGUM PUNK THEME (LIGHT) 💖
|
||||||
|
*
|
||||||
|
* This isn't just a theme. It's a statement.
|
||||||
|
* Unapologetically loud, pink, and quirky.
|
||||||
|
* =================================================================================================
|
||||||
|
*/
|
||||||
|
:root,
|
||||||
|
[data-bs-theme=light] {
|
||||||
|
/* --- CORE VIBE --- */
|
||||||
|
--bs-pink: #FF007A; /* 💖 Hyper Pink (Our Queen) */
|
||||||
|
--bs-green: #CFFF50; /* 🧪 Toxic Slime */
|
||||||
|
--bs-purple: #A328D6; /* 👾 Graffiti Purple */
|
||||||
|
--bs-yellow: #F9F871; /* ⚡ Neon Lemon */
|
||||||
|
--bs-cyan: #00F5D4; /* 💎 Glitchy Teal */
|
||||||
|
--bs-blue: #00A9E0; /* 💦 Splash Zone */
|
||||||
|
|
||||||
|
/* Let's redefine ALL the core colors to match the new energy */
|
||||||
|
--bs-primary: var(--bs-pink);
|
||||||
|
--bs-secondary: var(--bs-green);
|
||||||
|
--bs-success: var(--bs-cyan);
|
||||||
|
--bs-info: var(--bs-blue);
|
||||||
|
--bs-warning: var(--bs-yellow);
|
||||||
|
--bs-danger: #FF3D3D; /* 🚨 Code Red Rave */
|
||||||
|
|
||||||
|
/* --- BACKGROUNDS & TEXT --- */
|
||||||
|
/* No more boring white! */
|
||||||
|
--bs-body-bg: #FFF5FD; /* A soft, dreamy pink canvas */
|
||||||
|
--bs-body-color: #4A003D; /* Dark Plum (instead of black) for text */
|
||||||
|
--bs-heading-color: var(--bs-purple); /* Make headings POP */
|
||||||
|
--bs-secondary-color: rgba(74, 0, 61, 0.75); /* Plum, but softer */
|
||||||
|
--bs-tertiary-color: rgba(74, 0, 61, 0.5);
|
||||||
|
|
||||||
|
/* Make cards and containers pure white to contrast the pink background */
|
||||||
|
--bs-tertiary-bg: #FFFFFF;
|
||||||
|
--bs-secondary-bg: #FEF9FE;
|
||||||
|
|
||||||
|
/* --- LINKS & CODE --- */
|
||||||
|
--bs-link-color: var(--bs-pink);
|
||||||
|
--bs-link-hover-color: var(--bs-purple);
|
||||||
|
--bs-code-color: var(--bs-purple);
|
||||||
|
|
||||||
|
/* --- BORDERS & SHADOWS: LET'S GET QUIRKY --- */
|
||||||
|
--bs-border-width: 2px; /* Chunky borders! */
|
||||||
|
--bs-border-color: #FFD6F5; /* Pink-tinted border color */
|
||||||
|
--bs-border-color-translucent: rgba(74, 0, 61, 0.2);
|
||||||
|
--bs-border-radius: 1rem; /* Super bubbly and round */
|
||||||
|
--bs-border-radius-sm: 0.5rem;
|
||||||
|
--bs-border-radius-lg: 1.5rem;
|
||||||
|
--bs-border-radius-pill: 50rem;
|
||||||
|
|
||||||
|
/* Say goodbye to black shadows, hello to colored glows! */
|
||||||
|
--bs-box-shadow: 0 4px 12px rgba(255, 0, 122, 0.2);
|
||||||
|
--bs-box-shadow-sm: 0 2px 4px rgba(255, 0, 122, 0.15);
|
||||||
|
--bs-box-shadow-lg: 0 8px 30px rgba(255, 0, 122, 0.25);
|
||||||
|
--bs-box-shadow-inset: inset 0 1px 4px rgba(74, 0, 61, 0.2);
|
||||||
|
|
||||||
|
/* --- THE GRADIENT: THE SOUL OF THE THEME --- */
|
||||||
|
--bs-gradient: linear-gradient(75deg, var(--bs-primary), var(--bs-secondary));
|
||||||
|
|
||||||
|
/* --- Don't forget the RGB values for Bootstrap components! --- */
|
||||||
|
--bs-primary-rgb: 255, 0, 122;
|
||||||
|
--bs-secondary-rgb: 207, 255, 80;
|
||||||
|
--bs-body-color-rgb: 74, 0, 61;
|
||||||
|
--bs-body-bg-rgb: 255, 245, 253;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* =================================================================================================
|
||||||
|
* 🌙🦇 CYBER GOTH THEME (DARK) 🦇🌙
|
||||||
|
*
|
||||||
|
* The lights are out, the neon is ON.
|
||||||
|
* A dark, moody theme with vibrant, glowing accents.
|
||||||
|
* =================================================================================================
|
||||||
|
*/
|
||||||
|
[data-bs-theme=dark] {
|
||||||
|
color-scheme: dark;
|
||||||
|
|
||||||
|
/* --- BACKGROUNDS & TEXT --- */
|
||||||
|
--bs-body-bg: #1D001A; /* Deep, dark space purple */
|
||||||
|
--bs-body-color: #FFE9FA; /* Light pink text for high contrast */
|
||||||
|
--bs-heading-color: var(--bs-cyan); /* Glowing cyan headings */
|
||||||
|
|
||||||
|
--bs-tertiary-bg: #2E0028; /* A slightly lighter container background */
|
||||||
|
--bs-secondary-bg: #3A0033;
|
||||||
|
--bs-secondary-color: rgba(255, 233, 250, 0.75);
|
||||||
|
--bs-tertiary-color: rgba(255, 233, 250, 0.5);
|
||||||
|
|
||||||
|
/* --- LINKS & CODE --- */
|
||||||
|
/* Using the Toxic Slime for links gives it that cyber look */
|
||||||
|
--bs-link-color: var(--bs-green);
|
||||||
|
--bs-link-hover-color: var(--bs-cyan);
|
||||||
|
--bs-code-color: var(--bs-pink);
|
||||||
|
|
||||||
|
/* --- BORDERS & SHADOWS: NEON GLOWS --- */
|
||||||
|
--bs-border-color: #5C004F;
|
||||||
|
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||||
|
|
||||||
|
/* Redefine shadows to be neon glows */
|
||||||
|
--bs-box-shadow: 0 0 15px rgba(var(--bs-primary-rgb), 0.4);
|
||||||
|
--bs-box-shadow-lg: 0 0 30px rgba(var(--bs-primary-rgb), 0.5);
|
||||||
|
|
||||||
|
/* --- EMPHASIS & SUBTLE BACKGROUNDS --- */
|
||||||
|
/* These are for alerts, badges, etc. They'll be dark with glowing text. */
|
||||||
|
--bs-primary-text-emphasis: #FF8AD1;
|
||||||
|
--bs-secondary-text-emphasis: #E2FF8A;
|
||||||
|
--bs-success-text-emphasis: #8AFFEB;
|
||||||
|
--bs-info-text-emphasis: #7ADCF5;
|
||||||
|
--bs-warning-text-emphasis: #FAF8A8;
|
||||||
|
--bs-danger-text-emphasis: #FF8A8A;
|
||||||
|
|
||||||
|
--bs-primary-bg-subtle: #3D002B;
|
||||||
|
--bs-secondary-bg-subtle: #415215;
|
||||||
|
--bs-success-bg-subtle: #00332B;
|
||||||
|
--bs-info-bg-subtle: #00313D;
|
||||||
|
--bs-warning-bg-subtle: #3E3D1C;
|
||||||
|
--bs-danger-bg-subtle: #520E0E;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === EMOJI LEVELS === */
|
||||||
|
.emoji-normal .emoji-normal { display: inline; }
|
||||||
|
.emoji-normal .emoji-enhanced,
|
||||||
|
.emoji-normal .emoji-bonkers { display: none; }
|
||||||
|
|
||||||
|
.emoji-enhanced .emoji-enhanced { display: inline; }
|
||||||
|
.emoji-enhanced .emoji-normal,
|
||||||
|
.emoji-enhanced .emoji-bonkers { display: none; }
|
||||||
|
|
||||||
|
.emoji-bonkers .emoji-bonkers { display: inline; }
|
||||||
|
.emoji-bonkers .emoji-normal,
|
||||||
|
.emoji-bonkers .emoji-enhanced { display: none; }
|
||||||
|
/*
|
||||||
|
* =================================================================================================
|
||||||
|
* 🌈 RAINBOW PRIDE ELEMENTS 🌈
|
||||||
|
*
|
||||||
|
* Fabulous rainbow-themed elements to celebrate diversity and pride!
|
||||||
|
* =================================================================================================
|
||||||
|
*/
|
||||||
|
.bg-rainbow {
|
||||||
|
background: linear-gradient(
|
||||||
|
to right,
|
||||||
|
#FF5757, /* Red */
|
||||||
|
#FFBD59, /* Orange */
|
||||||
|
#F9F871, /* Yellow */
|
||||||
|
#CFFF50, /* Green */
|
||||||
|
#00F5D4, /* Teal */
|
||||||
|
#00A9E0, /* Blue */
|
||||||
|
#A328D6 /* Purple */
|
||||||
|
);
|
||||||
|
color: white;
|
||||||
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||||
|
font-weight: bold;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fun-fact {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a subtle rainbow border to the fun facts card */
|
||||||
|
.card:has(.fun-fact) {
|
||||||
|
border-width: 2px;
|
||||||
|
border-style: solid;
|
||||||
|
border-image: linear-gradient(
|
||||||
|
to right,
|
||||||
|
#FF5757, /* Red */
|
||||||
|
#FFBD59, /* Orange */
|
||||||
|
#F9F871, /* Yellow */
|
||||||
|
#CFFF50, /* Green */
|
||||||
|
#00F5D4, /* Teal */
|
||||||
|
#00A9E0, /* Blue */
|
||||||
|
#A328D6 /* Purple */
|
||||||
|
) 1;
|
||||||
|
box-shadow: 0 4px 15px rgba(163, 40, 214, 0.2);
|
||||||
|
}
|
||||||
|
|
30
assets/styles/emoji-footprint.css
Normal file
30
assets/styles/emoji-footprint.css
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
/* Emoji Footprint Animation */
|
||||||
|
.emoji-footprint {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
pointer-events: none;
|
||||||
|
animation: emojiFade 1s ease-out forwards;
|
||||||
|
transform: translate(-50%, -50%) scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
z-index: 9999;
|
||||||
|
text-shadow:
|
||||||
|
0 0 4px #ff00bf,
|
||||||
|
0 0 8px #ff80df,
|
||||||
|
0 0 12px #ffccff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes emojiFade {
|
||||||
|
0% {
|
||||||
|
transform: translate(-50%, -50%) scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translate(-50%, -50%) scale(1.5);
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translate(-50%, -50%) scale(2);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
565
assets/styles/modes.css
Normal file
565
assets/styles/modes.css
Normal file
|
@ -0,0 +1,565 @@
|
||||||
|
/* 🌈✨ BONKERS MODE ANIMATIONS ✨🌈 */
|
||||||
|
@keyframes rainbowGradient {
|
||||||
|
0% { background-position: 0% 50%; }
|
||||||
|
50% { background-position: 100% 50%; }
|
||||||
|
100% { background-position: 0% 50%; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes discoFlash {
|
||||||
|
0%, 100% {
|
||||||
|
background-color: var(--bs-pink);
|
||||||
|
box-shadow: 0 0 20px var(--bs-pink), 0 0 40px var(--bs-pink);
|
||||||
|
}
|
||||||
|
16.66% {
|
||||||
|
background-color: var(--bs-purple);
|
||||||
|
box-shadow: 0 0 20px var(--bs-purple), 0 0 40px var(--bs-purple);
|
||||||
|
}
|
||||||
|
33.33% {
|
||||||
|
background-color: var(--bs-cyan);
|
||||||
|
box-shadow: 0 0 20px var(--bs-cyan), 0 0 40px var(--bs-cyan);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
background-color: var(--bs-yellow);
|
||||||
|
box-shadow: 0 0 20px var(--bs-yellow), 0 0 40px var(--bs-yellow);
|
||||||
|
}
|
||||||
|
66.66% {
|
||||||
|
background-color: var(--bs-green);
|
||||||
|
box-shadow: 0 0 20px var(--bs-green), 0 0 40px var(--bs-green);
|
||||||
|
}
|
||||||
|
83.33% {
|
||||||
|
background-color: var(--bs-orange);
|
||||||
|
box-shadow: 0 0 20px var(--bs-orange), 0 0 40px var(--bs-orange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes wiggle {
|
||||||
|
0%, 100% { transform: rotate(0deg); }
|
||||||
|
25% { transform: rotate(-2deg); }
|
||||||
|
75% { transform: rotate(2deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% { transform: scale(1); }
|
||||||
|
50% { transform: scale(1.05); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
from { transform: rotate(0deg); }
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rainbowText {
|
||||||
|
0% { color: var(--bs-red); }
|
||||||
|
14.28% { color: var(--bs-orange); }
|
||||||
|
28.57% { color: var(--bs-yellow); }
|
||||||
|
42.85% { color: var(--bs-green); }
|
||||||
|
57.14% { color: var(--bs-cyan); }
|
||||||
|
71.42% { color: var(--bs-purple); }
|
||||||
|
85.71% { color: var(--bs-pink); }
|
||||||
|
100% { color: var(--bs-red); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shine {
|
||||||
|
0% { left: -100%; }
|
||||||
|
50% { left: 100%; }
|
||||||
|
100% { left: 100%; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slayFloat {
|
||||||
|
0% {
|
||||||
|
transform: translateY(0) scale(0.5);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
transform: translateY(-20px) scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
transform: translateY(-60px) scale(1.2);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(-100px) scale(1.5);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 🎭 BONKERS MODE CLASSES 🎭 */
|
||||||
|
.bonkers-mode {
|
||||||
|
transition: all 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .btn {
|
||||||
|
animation: discoFlash 0.3s infinite, wiggle 0.2s infinite;
|
||||||
|
background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan), var(--bs-yellow), var(--bs-green), var(--bs-orange), var(--bs-red));
|
||||||
|
background-size: 400% 400%;
|
||||||
|
animation: discoFlash 0.3s infinite, wiggle 0.2s infinite, rainbowGradient 1s ease infinite;
|
||||||
|
border: 4px solid var(--bs-white);
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .btn:hover {
|
||||||
|
animation: discoFlash 0.2s infinite, wiggle 0.1s infinite, rainbowGradient 0.5s ease infinite;
|
||||||
|
box-shadow: 0 0 30px var(--bs-pink), 0 0 60px var(--bs-purple);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .btn::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -50%;
|
||||||
|
left: -50%;
|
||||||
|
width: 200%;
|
||||||
|
height: 200%;
|
||||||
|
background: linear-gradient(45deg, transparent, rgba(255,255,255,0.5), transparent);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
animation: spin 0.5s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar {
|
||||||
|
background: linear-gradient(90deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan), var(--bs-yellow), var(--bs-green), var(--bs-orange), var(--bs-red));
|
||||||
|
background-size: 200% 200%;
|
||||||
|
animation: rainbowGradient 2s ease infinite;
|
||||||
|
box-shadow: 0 0 50px rgba(255, 105, 180, 0.9);
|
||||||
|
height: auto !important;
|
||||||
|
min-height: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar-brand {
|
||||||
|
animation: rainbowText 0.8s infinite, wiggle 0.4s infinite;
|
||||||
|
font-size: 1.8em;
|
||||||
|
text-shadow: 3px 3px 6px rgba(0,0,0,0.5);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar-brand::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -50%;
|
||||||
|
left: -50%;
|
||||||
|
width: 200%;
|
||||||
|
height: 200%;
|
||||||
|
background: linear-gradient(45deg, transparent, rgba(255,255,255,0.3), transparent);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
animation: spin 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar-nav .nav-link {
|
||||||
|
animation: rainbowText 1.2s infinite, wiggle 0.3s infinite;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||||
|
border: 2px solid transparent;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
margin: 0 4px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar-nav .nav-link::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
|
||||||
|
animation: shine 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar-nav .nav-link:hover {
|
||||||
|
background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple));
|
||||||
|
border-color: var(--bs-white);
|
||||||
|
box-shadow: 0 0 20px var(--bs-pink);
|
||||||
|
animation: discoFlash 0.5s infinite, wiggle 0.2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar-nav .nav-link.active {
|
||||||
|
background: linear-gradient(45deg, var(--bs-yellow), var(--bs-orange));
|
||||||
|
border-color: var(--bs-white);
|
||||||
|
box-shadow: 0 0 25px var(--bs-yellow);
|
||||||
|
animation: discoFlash 0.8s infinite, wiggle 0.3s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar-text {
|
||||||
|
animation: rainbowText 1.5s infinite, wiggle 0.5s infinite;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||||
|
border: 2px solid var(--bs-white);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
background: linear-gradient(45deg, var(--bs-cyan), var(--bs-blue));
|
||||||
|
box-shadow: 0 0 15px var(--bs-cyan);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar-toggler {
|
||||||
|
border: 3px solid var(--bs-white);
|
||||||
|
background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple));
|
||||||
|
animation: discoFlash 0.6s infinite, wiggle 0.4s infinite;
|
||||||
|
box-shadow: 0 0 20px var(--bs-pink);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar-toggler:focus {
|
||||||
|
box-shadow: 0 0 30px var(--bs-pink), 0 0 0 0.2rem rgba(255, 105, 180, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar-toggler-icon {
|
||||||
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(255, 255, 255, 1)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .dropdown-menu {
|
||||||
|
background: linear-gradient(135deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan));
|
||||||
|
border: 3px solid var(--bs-white);
|
||||||
|
box-shadow: 0 0 30px rgba(255,105,180,0.8);
|
||||||
|
animation: rainbowGradient 2s ease infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .dropdown-item {
|
||||||
|
animation: rainbowText 1.8s infinite, wiggle 0.6s infinite;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.3);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .dropdown-item:hover {
|
||||||
|
background: linear-gradient(45deg, var(--bs-yellow), var(--bs-orange));
|
||||||
|
color: var(--bs-white);
|
||||||
|
box-shadow: 0 0 15px var(--bs-yellow);
|
||||||
|
animation: discoFlash 0.5s infinite, wiggle 0.3s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .navbar-collapse {
|
||||||
|
background: linear-gradient(135deg, rgba(255,105,180,0.1), rgba(138,43,226,0.1));
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
border: 2px solid var(--bs-pink);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode h1, .bonkers-mode h2, .bonkers-mode h3 {
|
||||||
|
animation: rainbowText 1.5s infinite;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .table {
|
||||||
|
background: linear-gradient(135deg, rgba(255,105,180,0.2), rgba(138,43,226,0.2), rgba(0,255,255,0.2));
|
||||||
|
animation: rainbowGradient 3s ease infinite;
|
||||||
|
border: 3px solid var(--bs-pink);
|
||||||
|
box-shadow: 0 0 30px rgba(255,105,180,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .table th {
|
||||||
|
background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple));
|
||||||
|
color: var(--bs-white);
|
||||||
|
animation: discoFlash 0.8s infinite;
|
||||||
|
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .form-control {
|
||||||
|
border: 3px solid var(--bs-pink);
|
||||||
|
box-shadow: 0 0 15px var(--bs-pink);
|
||||||
|
animation: pulse 0.6s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .alert {
|
||||||
|
animation: discoFlash 0.6s infinite, wiggle 0.3s infinite;
|
||||||
|
border: 4px solid var(--bs-white);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .card {
|
||||||
|
background: linear-gradient(45deg, rgba(255,105,180,0.2), rgba(138,43,226,0.2));
|
||||||
|
border: 3px solid var(--bs-purple);
|
||||||
|
box-shadow: 0 0 35px rgba(138,43,226,0.6);
|
||||||
|
animation: pulse 1s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .modal-content {
|
||||||
|
background: linear-gradient(135deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan));
|
||||||
|
border: 4px solid var(--bs-white);
|
||||||
|
box-shadow: 0 0 50px rgba(255,105,180,0.8);
|
||||||
|
animation: rainbowGradient 2s ease infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .modal-header {
|
||||||
|
background: linear-gradient(90deg, var(--bs-yellow), var(--bs-orange));
|
||||||
|
animation: discoFlash 0.8s infinite;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .number-input-wrapper {
|
||||||
|
animation: wiggle 0.4s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bonkers-mode .number-input-wrapper .btn {
|
||||||
|
animation: discoFlash 0.3s infinite, wiggle 0.2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enhanced mode styles (for future use) */
|
||||||
|
[data-website-mode="enhanced"] .btn {
|
||||||
|
background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan), var(--bs-yellow), var(--bs-green), var(--bs-orange), var(--bs-red));
|
||||||
|
background-size: 400% 400%;
|
||||||
|
animation: rainbowGradient 1s ease infinite;
|
||||||
|
border: 4px solid var(--bs-white);
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .btn:hover {
|
||||||
|
animation: rainbowGradient 0.5s ease infinite;
|
||||||
|
box-shadow: 0 0 30px var(--bs-pink), 0 0 60px var(--bs-purple);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .btn::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -50%;
|
||||||
|
left: -50%;
|
||||||
|
width: 200%;
|
||||||
|
height: 200%;
|
||||||
|
background: linear-gradient(45deg, transparent, rgba(255,255,255,0.5), transparent);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
animation: spin 0.5s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar {
|
||||||
|
background: linear-gradient(90deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan), var(--bs-yellow), var(--bs-green), var(--bs-orange), var(--bs-red));
|
||||||
|
background-size: 200% 200%;
|
||||||
|
animation: rainbowGradient 2s ease infinite;
|
||||||
|
box-shadow: 0 0 50px rgba(255, 105, 180, 0.9);
|
||||||
|
height: auto !important;
|
||||||
|
min-height: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar-brand {
|
||||||
|
animation: rainbowText 0.8s infinite;
|
||||||
|
font-size: 1.8em;
|
||||||
|
text-shadow: 3px 3px 6px rgba(0,0,0,0.5);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar-brand::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -50%;
|
||||||
|
left: -50%;
|
||||||
|
width: 200%;
|
||||||
|
height: 200%;
|
||||||
|
background: linear-gradient(45deg, transparent, rgba(255,255,255,0.3), transparent);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
animation: spin 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar-nav .nav-link {
|
||||||
|
animation: rainbowText 1.2s infinite;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||||
|
border: 2px solid transparent;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
margin: 0 4px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar-nav .nav-link::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
|
||||||
|
animation: shine 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar-nav .nav-link:hover {
|
||||||
|
background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple));
|
||||||
|
border-color: var(--bs-white);
|
||||||
|
box-shadow: 0 0 20px var(--bs-pink);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar-nav .nav-link.active {
|
||||||
|
background: linear-gradient(45deg, var(--bs-yellow), var(--bs-orange));
|
||||||
|
border-color: var(--bs-white);
|
||||||
|
box-shadow: 0 0 25px var(--bs-yellow);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar-text {
|
||||||
|
animation: rainbowText 1.5s infinite;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||||
|
border: 2px solid var(--bs-white);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 6px 12px;
|
||||||
|
background: linear-gradient(45deg, var(--bs-cyan), var(--bs-blue));
|
||||||
|
box-shadow: 0 0 15px var(--bs-cyan);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar-toggler {
|
||||||
|
border: 3px solid var(--bs-white);
|
||||||
|
background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple));
|
||||||
|
animation: rainbowGradient 0.6s ease infinite;
|
||||||
|
box-shadow: 0 0 20px var(--bs-pink);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar-toggler:focus {
|
||||||
|
box-shadow: 0 0 30px var(--bs-pink), 0 0 0 0.2rem rgba(255, 105, 180, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar-toggler-icon {
|
||||||
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(255, 255, 255, 1)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .dropdown-menu {
|
||||||
|
background: linear-gradient(135deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan));
|
||||||
|
border: 3px solid var(--bs-white);
|
||||||
|
box-shadow: 0 0 30px rgba(255,105,180,0.8);
|
||||||
|
animation: rainbowGradient 2s ease infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .dropdown-item {
|
||||||
|
animation: rainbowText 1.8s infinite;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.3);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .dropdown-item:hover {
|
||||||
|
background: linear-gradient(45deg, var(--bs-yellow), var(--bs-orange));
|
||||||
|
color: var(--bs-white);
|
||||||
|
box-shadow: 0 0 15px var(--bs-yellow);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .navbar-collapse {
|
||||||
|
background: linear-gradient(135deg, rgba(255,105,180,0.1), rgba(138,43,226,0.1));
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
border: 2px solid var(--bs-pink);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] h1, [data-website-mode="enhanced"] h2, [data-website-mode="enhanced"] h3 {
|
||||||
|
animation: rainbowText 1.5s infinite;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .table {
|
||||||
|
background: linear-gradient(135deg, rgba(255,105,180,0.2), rgba(138,43,226,0.2), rgba(0,255,255,0.2));
|
||||||
|
animation: rainbowGradient 3s ease infinite;
|
||||||
|
border: 3px solid var(--bs-pink);
|
||||||
|
box-shadow: 0 0 30px rgba(255,105,180,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .table th {
|
||||||
|
background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple));
|
||||||
|
color: var(--bs-white);
|
||||||
|
animation: rainbowGradient 0.8s ease infinite;
|
||||||
|
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .form-control {
|
||||||
|
border: 3px solid var(--bs-pink);
|
||||||
|
box-shadow: 0 0 15px var(--bs-pink);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .alert {
|
||||||
|
animation: rainbowGradient 0.6s ease infinite;
|
||||||
|
border: 4px solid var(--bs-white);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .card {
|
||||||
|
background: linear-gradient(45deg, rgba(255,105,180,0.2), rgba(138,43,226,0.2));
|
||||||
|
border: 3px solid var(--bs-purple);
|
||||||
|
box-shadow: 0 0 35px rgba(138,43,226,0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .modal-content {
|
||||||
|
background: linear-gradient(135deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan));
|
||||||
|
border: 4px solid var(--bs-white);
|
||||||
|
box-shadow: 0 0 50px rgba(255,105,180,0.8);
|
||||||
|
animation: rainbowGradient 2s ease infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .modal-header {
|
||||||
|
background: linear-gradient(90deg, var(--bs-yellow), var(--bs-orange));
|
||||||
|
animation: rainbowGradient 0.8s ease infinite;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .number-input-wrapper {
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-website-mode="enhanced"] .number-input-wrapper .btn {
|
||||||
|
animation: rainbowGradient 0.3s ease infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Emoji Footprint Animation */
|
||||||
|
.emoji-footprint {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
pointer-events: none;
|
||||||
|
animation: emojiFade 1s ease-out forwards;
|
||||||
|
transform: translate(-50%, -50%) scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
z-index: 9999;
|
||||||
|
text-shadow:
|
||||||
|
0 0 4px #ff00bf,
|
||||||
|
0 0 8px #ff80df,
|
||||||
|
0 0 12px #ffccff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes emojiFade {
|
||||||
|
0% {
|
||||||
|
transform: translate(-50%, -50%) scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translate(-50%, -50%) scale(1.5);
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translate(-50%, -50%) scale(2);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 💅 SLAY TEXT EFFECTS 💅 */
|
||||||
|
.slay-text {
|
||||||
|
position: fixed;
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 10000;
|
||||||
|
animation: slayFloat 3s ease-out forwards;
|
||||||
|
text-shadow:
|
||||||
|
0 0 10px #ff00bf,
|
||||||
|
0 0 20px #ff80df,
|
||||||
|
0 0 30px #ffccff,
|
||||||
|
2px 2px 4px rgba(0,0,0,0.5);
|
||||||
|
background: linear-gradient(45deg, var(--bs-pink), var(--bs-purple), var(--bs-cyan), var(--bs-yellow));
|
||||||
|
background-size: 400% 400%;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
animation: slayFloat 3s ease-out forwards, rainbowGradient 1s ease infinite;
|
||||||
|
}
|
|
@ -1,17 +1,16 @@
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||||
|
use Symfony\Config\TwigConfig;
|
||||||
|
|
||||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
return static function (
|
||||||
$containerConfigurator->extension('twig', [
|
ContainerConfigurator $containerConfigurator,
|
||||||
'file_name_pattern' => '*.twig',
|
TwigConfig $twig,
|
||||||
'globals' => [
|
): void {
|
||||||
'favicon' => '@App\Service\Favicon',
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
if ($containerConfigurator->env() === 'test') {
|
if ($containerConfigurator->env() === 'test') {
|
||||||
$containerConfigurator->extension('twig', [
|
$twig->strictVariables(true);
|
||||||
'strict_variables' => true,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
$twig->formThemes(['bootstrap_5_layout.html.twig']);
|
||||||
|
$twig->fileNamePattern('*.twig');
|
||||||
|
$twig->global('favicon', '@App\Service\Favicon');
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{{ form_start(form) }}
|
{{ form_start(form, {'attr': {'class': 'mb-3'}}) }}
|
||||||
{{ form_widget(form) }}
|
{{ form_widget(form, {'attr': {'class': 'form-control'}}) }}
|
||||||
<button class="btn">{{ button_label|default('Save') }}</button>
|
<button class="btn btn-primary mt-2">{{ button_label|default('Save') }}</button>
|
||||||
{{ form_end(form) }}
|
{{ form_end(form) }}
|
||||||
|
|
|
@ -11,19 +11,53 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header class="mb-4">
|
||||||
<p>Hello {{ app.request.cookies.get('username', 'nobody') }} - <a href="{{ path('username') }}">change name</a></p>
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||||
<nav>
|
<div class="container-fluid">
|
||||||
<a href="{{ path('app_food_order_index') }}">Orders</a> /
|
<span class="navbar-brand">Futtern</span>
|
||||||
<a href="{{ path('app_food_vendor_index') }}">Vendors</a> /
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<a
|
<span class="navbar-toggler-icon"></span>
|
||||||
href="https://git.hannover.ccc.de/lubiana/futtern/issues/new"
|
</button>
|
||||||
target="_blank"
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
>Create Issue</a> /
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||||
<a href="/api">API</a>
|
<li class="nav-item"><a class="nav-link" href="{{ path('app_food_order_index') }}">Orders</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="{{ path('app_food_vendor_index') }}">Vendors</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/api">API</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="https://git.hannover.ccc.de/lubiana/futtern/issues/new" target="_blank">Create Issue</a></li>
|
||||||
|
</ul>
|
||||||
|
<div class="btn-group ms-auto" role="group" aria-label="Mode selection">
|
||||||
|
<input type="radio" class="btn-check" name="mode" id="normal" autocomplete="off" checked>
|
||||||
|
<label class="btn btn-outline-primary" for="normal">
|
||||||
|
Normal
|
||||||
|
<span class="emoji-normal">😌</span>
|
||||||
|
<span class="emoji-enhanced">😌🍑</span>
|
||||||
|
<span class="emoji-bonkers">😌🍑🍆💦👅💋😈🏳️🌈✨</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input type="radio" class="btn-check" name="mode" id="enhanced" autocomplete="off">
|
||||||
|
<label class="btn btn-outline-primary" for="enhanced">
|
||||||
|
Enhanced
|
||||||
|
<span class="emoji-normal">✨</span>
|
||||||
|
<span class="emoji-enhanced">✨🍑🍆</span>
|
||||||
|
<span class="emoji-bonkers">✨🍑🍆💦👅💋😈🏳️🌈</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input type="radio" class="btn-check" name="mode" id="bonkers" autocomplete="off">
|
||||||
|
<label class="btn btn-outline-primary" for="bonkers">
|
||||||
|
Bonkers
|
||||||
|
<span class="emoji-normal">💦</span>
|
||||||
|
<span class="emoji-enhanced">💦🍑🍆</span>
|
||||||
|
<span class="emoji-bonkers">💦🍑🍆👅💋😈🏳️🌈✨🥵😳🤤😍🥴💕💗💘💝💞💟💌💏💑</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<span class="navbar-text">
|
||||||
|
Hello {{ app.request.cookies.get('username', 'nobody') }} - <a class="text-light" href="{{ path('username') }}">change name</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main class="container pb-5">
|
||||||
{% block body %}{% endblock %}
|
{% block body %}{% endblock %}
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
{% block title %}Edit FoodOrder{% endblock %}
|
{% block title %}Edit FoodOrder{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>Edit FoodOrder</h1>
|
<h1 class="mb-4">Edit FoodOrder</h1>
|
||||||
|
|
||||||
{{ include('_form.html.twig', {'button_label': 'Update'}) }}
|
<div class="mb-4">
|
||||||
|
{{ include('_form.html.twig', {'button_label': 'Update'}) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<a href="{{ path('app_food_order_index') }}">back to list</a>
|
<a class="btn btn-secondary" href="{{ path('app_food_order_index') }}">back to list</a>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -3,17 +3,18 @@
|
||||||
{% block title %}FoodOrder index{% endblock %}
|
{% block title %}FoodOrder index{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>FoodOrder index</h1>
|
<h1 class="mb-4">FoodOrder index</h1>
|
||||||
<div>
|
<div class="mb-3">
|
||||||
<button
|
<button
|
||||||
|
class="btn btn-primary"
|
||||||
hx-get="{{ path('app_food_order_new') }}"
|
hx-get="{{ path('app_food_order_new') }}"
|
||||||
hx-trigger="click"
|
hx-trigger="click"
|
||||||
hx-target="closest div"
|
hx-target="closest div"
|
||||||
>Create new</button>
|
>Create new</button>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<table class="table">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th>CreatedBy</th>
|
<th>CreatedBy</th>
|
||||||
<th>Vendor</th>
|
<th>Vendor</th>
|
||||||
|
@ -28,7 +29,7 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if food_orders|length < 10 %}
|
{% if food_orders|length < 10 %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="5">
|
<td colspan="5" class="text-center text-muted">
|
||||||
check the <a href="{{ path('app_food_order_archive') }}">archive</a>
|
check the <a href="{{ path('app_food_order_archive') }}">archive</a>
|
||||||
for older orders
|
for older orders
|
||||||
</td>
|
</td>
|
||||||
|
@ -36,10 +37,12 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% if prev_page > 0 %}
|
<div class="d-flex gap-2">
|
||||||
<a href="{{ path('app_food_order_archive', {'page': prev_page}) }}">previous page</a> |
|
{% if prev_page > 0 %}
|
||||||
{% endif %}
|
<a class="btn btn-outline-secondary btn-sm" href="{{ path('app_food_order_archive', {'page': prev_page}) }}">previous page</a>
|
||||||
{% if next_page > current_page %}
|
{% endif %}
|
||||||
<a href="{{ path('app_food_order_archive', {'page': next_page}) }}">next page</a>
|
{% if next_page > current_page %}
|
||||||
{% endif %}
|
<a class="btn btn-outline-secondary btn-sm" href="{{ path('app_food_order_archive', {'page': next_page}) }}">next page</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
{{ include('_form.html.twig') }}
|
<div class="mb-4">
|
||||||
|
{{ include('_form.html.twig') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
{% block title %}FoodOrder{% endblock %}
|
{% block title %}FoodOrder{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>FoodOrder</h1>
|
<h1 class="mb-4">FoodOrder</h1>
|
||||||
|
|
||||||
<table class="table">
|
<table class="table table-bordered table-striped w-auto">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Vendor</th>
|
<th>Vendor</th>
|
||||||
|
@ -29,16 +29,18 @@
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<a class="button" href="{{ path('app_food_order_index') }}">back to list</a>
|
<div class="mb-3 d-flex gap-2">
|
||||||
{% if(food_order.isClosed) %}
|
<a class="btn btn-secondary" href="{{ path('app_food_order_index') }}">back to list</a>
|
||||||
<a class="button" href="{{ path('app_food_order_open', {'id': food_order.id}) }}">reopen</a>
|
{% if(food_order.isClosed) %}
|
||||||
{% else %}
|
<a class="btn btn-warning" href="{{ path('app_food_order_open', {'id': food_order.id}) }}">reopen</a>
|
||||||
<a class="button" href="{{ path('app_food_order_close', {'id': food_order.id}) }}">close</a>
|
{% else %}
|
||||||
{% endif %}
|
<a class="btn btn-success" href="{{ path('app_food_order_close', {'id': food_order.id}) }}">close</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2>Items</h2>
|
<h2 class="mt-5">Items</h2>
|
||||||
<table class="table">
|
<table class="table table-hover">
|
||||||
<thead>
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Index</th>
|
<th>Index</th>
|
||||||
<th>username</th>
|
<th>username</th>
|
||||||
|
@ -57,15 +59,15 @@
|
||||||
<td>
|
<td>
|
||||||
{% if(food_order.isClosed) %}
|
{% if(food_order.isClosed) %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ path('app_order_item_edit', {'id': item.id}) }}">edit</a>
|
<a class="btn btn-sm btn-outline-primary me-1" href="{{ path('app_order_item_edit', {'id': item.id}) }}">edit</a>
|
||||||
<a href="{{ path('app_order_item_copy', {'id': item.id}) }}">copy</a>
|
<a class="btn btn-sm btn-outline-secondary me-1" href="{{ path('app_order_item_copy', {'id': item.id}) }}">copy</a>
|
||||||
<a href="{{ path('app_order_item_delete', {'id': item.id}) }}">remove</a>
|
<a class="btn btn-sm btn-outline-danger" href="{{ path('app_order_item_delete', {'id': item.id}) }}">remove</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<a class="button" href="{{ path('app_order_item_new', {'foodOrder': food_order.id}) }}">New Item</a>
|
<a class="btn btn-primary mt-2" href="{{ path('app_order_item_new', {'foodOrder': food_order.id}) }}">New Item</a>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
<td>{{ food_order.createdAt ? food_order.createdAt|date('Y-m-d H:i:s', 'Europe/Berlin') : '' }}</td>
|
<td>{{ food_order.createdAt ? food_order.createdAt|date('Y-m-d H:i:s', 'Europe/Berlin') : '' }}</td>
|
||||||
<td>{{ food_order.closedAt ? food_order.closedAt|date('Y-m-d H:i:s', 'Europe/Berlin') : '' }}</td>
|
<td>{{ food_order.closedAt ? food_order.closedAt|date('Y-m-d H:i:s', 'Europe/Berlin') : '' }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ path('app_food_order_show', {'id': food_order.id}) }}">show</a>
|
<a class="btn btn-sm btn-outline-info" href="{{ path('app_food_order_show', {'id': food_order.id}) }}">show</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
|
@ -1,4 +1,4 @@
|
||||||
{{ form_start(form) }}
|
{{ form_start(form, {'attr': {'class': 'mb-3'}}) }}
|
||||||
{{ form_widget(form) }}
|
{{ form_widget(form, {'attr': {'class': 'form-control'}}) }}
|
||||||
<button class="btn">{{ button_label|default('Save') }}</button>
|
<button class="btn btn-primary mt-2">{{ button_label|default('Save') }}</button>
|
||||||
{{ form_end(form) }}
|
{{ form_end(form) }}
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
{% block title %}Edit FoodVendor{% endblock %}
|
{% block title %}Edit FoodVendor{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>Edit FoodVendor</h1>
|
<h1 class="mb-4">Edit FoodVendor</h1>
|
||||||
|
|
||||||
{{ include('food_vendor/_form.html.twig', {'button_label': 'Update'}) }}
|
<div class="mb-4">
|
||||||
|
{{ include('food_vendor/_form.html.twig', {'button_label': 'Update'}) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<a href="{{ path('app_food_vendor_index') }}">back to list</a>
|
<a class="btn btn-secondary" href="{{ path('app_food_vendor_index') }}">back to list</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
{% block title %}FoodVendor index{% endblock %}
|
{% block title %}FoodVendor index{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>FoodVendor index</h1>
|
<h1 class="mb-4">FoodVendor index</h1>
|
||||||
|
|
||||||
<table class="table">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>actions</th>
|
<th>actions</th>
|
||||||
|
@ -17,17 +17,17 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ food_vendor.name }}</td>
|
<td>{{ food_vendor.name }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ path('app_food_vendor_show', {'id': food_vendor.id}) }}">show</a>
|
<a class="btn btn-sm btn-outline-info me-1" href="{{ path('app_food_vendor_show', {'id': food_vendor.id}) }}">show</a>
|
||||||
<a href="{{ path('app_food_vendor_edit', {'id': food_vendor.id}) }}">edit</a>
|
<a class="btn btn-sm btn-outline-primary" href="{{ path('app_food_vendor_edit', {'id': food_vendor.id}) }}">edit</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% else %}
|
{% else %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3">no records found</td>
|
<td colspan="3" class="text-center text-muted">no records found</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<a href="{{ path('app_food_vendor_new') }}">Create new</a>
|
<a class="btn btn-primary" href="{{ path('app_food_vendor_new') }}">Create new</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
{% block title %}New FoodVendor{% endblock %}
|
{% block title %}New FoodVendor{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>Create new FoodVendor</h1>
|
<h1 class="mb-4">Create new FoodVendor</h1>
|
||||||
|
|
||||||
{{ include('food_vendor/_form.html.twig') }}
|
<div class="mb-4">
|
||||||
|
{{ include('food_vendor/_form.html.twig') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<a href="{{ path('app_food_vendor_index') }}">back to list</a>
|
<a class="btn btn-secondary" href="{{ path('app_food_vendor_index') }}">back to list</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
{% block title %}FoodVendor{% endblock %}
|
{% block title %}FoodVendor{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>FoodVendor</h1>
|
<h1 class="mb-4">FoodVendor</h1>
|
||||||
|
|
||||||
<table class="table">
|
<table class="table table-bordered w-auto">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
|
@ -18,23 +18,22 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<section>
|
<section class="mb-4">
|
||||||
<h2>known menuitems</h2>
|
<h2>known menuitems</h2>
|
||||||
<ul>
|
<ul class="list-group list-group-flush">
|
||||||
{% for item in food_vendor.menuItems %}
|
{% for item in food_vendor.menuItems %}
|
||||||
<li>
|
<li class="list-group-item">
|
||||||
<a href="{{ path('app_menu_item_show', {'id': item.id}) }}">{{ item.name }}</a>
|
<a href="{{ path('app_menu_item_show', {'id': item.id}) }}">{{ item.name }}</a>
|
||||||
{% if(item.aliasOf) %}
|
{% if(item.aliasOf) %}
|
||||||
(alias of: {{ item.aliasOf.name }})
|
<span class="text-muted">(alias of: {{ item.aliasOf.name }})</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<div class="d-flex gap-2">
|
||||||
<a href="{{ path('app_food_vendor_index') }}">back to list</a>
|
<a class="btn btn-secondary" href="{{ path('app_food_vendor_index') }}">back to list</a>
|
||||||
|
<a class="btn btn-primary" href="{{ path('app_food_vendor_edit', {'id': food_vendor.id}) }}">edit</a>
|
||||||
<a href="{{ path('app_food_vendor_edit', {'id': food_vendor.id}) }}">edit</a>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<form method="post" action="{{ path('app_menu_item_delete', {'id': menu_item.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
|
<form method="post" action="{{ path('app_menu_item_delete', {'id': menu_item.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
|
||||||
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ menu_item.id) }}">
|
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ menu_item.id) }}">
|
||||||
<button class="btn">Delete</button>
|
<button class="btn btn-danger btn-sm">Delete</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{{ form_start(form) }}
|
{{ form_start(form, {'attr': {'class': 'mb-3'}}) }}
|
||||||
{{ form_widget(form) }}
|
{{ form_widget(form, {'attr': {'class': 'form-control'}}) }}
|
||||||
<button class="btn">{{ button_label|default('Save') }}</button>
|
<button class="btn btn-primary mt-2">{{ button_label|default('Save') }}</button>
|
||||||
{{ form_end(form) }}
|
{{ form_end(form) }}
|
||||||
|
|
|
@ -3,9 +3,13 @@
|
||||||
{% block title %}Edit MenuItem{% endblock %}
|
{% block title %}Edit MenuItem{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>Edit MenuItem</h1>
|
<h1 class="mb-4">Edit MenuItem</h1>
|
||||||
|
|
||||||
{{ include('menu_item/_form.html.twig', {'button_label': 'Update'}) }}
|
<div class="mb-4">
|
||||||
|
{{ include('menu_item/_form.html.twig', {'button_label': 'Update'}) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{ include('menu_item/_delete_form.html.twig') }}
|
<div class="d-flex gap-2">
|
||||||
|
{{ include('menu_item/_delete_form.html.twig') }}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
{% block title %}MenuItem index{% endblock %}
|
{% block title %}MenuItem index{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>MenuItem index</h1>
|
<h1 class="mb-4">MenuItem index</h1>
|
||||||
|
|
||||||
<table class="table">
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Id</th>
|
<th>Id</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
|
@ -19,17 +19,17 @@
|
||||||
<td>{{ menu_item.id }}</td>
|
<td>{{ menu_item.id }}</td>
|
||||||
<td>{{ menu_item.name }}</td>
|
<td>{{ menu_item.name }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ path('app_menu_item_show', {'id': menu_item.id}) }}">show</a>
|
<a class="btn btn-sm btn-outline-info me-1" href="{{ path('app_menu_item_show', {'id': menu_item.id}) }}">show</a>
|
||||||
<a href="{{ path('app_menu_item_edit', {'id': menu_item.id}) }}">edit</a>
|
<a class="btn btn-sm btn-outline-primary" href="{{ path('app_menu_item_edit', {'id': menu_item.id}) }}">edit</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% else %}
|
{% else %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3">no records found</td>
|
<td colspan="3" class="text-center text-muted">no records found</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<a href="{{ path('app_menu_item_new') }}">Create new</a>
|
<a class="btn btn-primary" href="{{ path('app_menu_item_new') }}">Create new</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
{% block title %}New MenuItem{% endblock %}
|
{% block title %}New MenuItem{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>Create new MenuItem</h1>
|
<h1 class="mb-4">Create new MenuItem</h1>
|
||||||
|
|
||||||
{{ include('menu_item/_form.html.twig') }}
|
<div class="mb-4">
|
||||||
|
{{ include('menu_item/_form.html.twig') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<a href="{{ path('app_menu_item_index') }}">back to list</a>
|
<a class="btn btn-secondary" href="{{ path('app_menu_item_index') }}">back to list</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
{% block title %}MenuItem{% endblock %}
|
{% block title %}MenuItem{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>MenuItem</h1>
|
<h1 class="mb-4">MenuItem</h1>
|
||||||
|
|
||||||
<table class="table">
|
<table class="table table-bordered w-auto">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Id</th>
|
<th>Id</th>
|
||||||
|
@ -25,9 +25,9 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>Aliases</th>
|
<th>Aliases</th>
|
||||||
<td>
|
<td>
|
||||||
<ul>
|
<ul class="list-group list-group-flush">
|
||||||
{% for alias in menu_item.aliases %}
|
{% for alias in menu_item.aliases %}
|
||||||
<li>{{ alias.name }}</li>
|
<li class="list-group-item">{{ alias.name }}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
|
@ -36,9 +36,9 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<a href="{{ path('app_food_vendor_show', { 'id': menu_item.foodVendor.id}) }}">back to list</a>
|
<div class="d-flex gap-2">
|
||||||
|
<a class="btn btn-secondary" href="{{ path('app_food_vendor_show', { 'id': menu_item.foodVendor.id}) }}">back to list</a>
|
||||||
<a href="{{ path('app_menu_item_edit', {'id': menu_item.id}) }}">edit</a>
|
<a class="btn btn-primary" href="{{ path('app_menu_item_edit', {'id': menu_item.id}) }}">edit</a>
|
||||||
|
{{ include('menu_item/_delete_form.html.twig') }}
|
||||||
{{ include('menu_item/_delete_form.html.twig') }}
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{{ form_start(form) }}
|
{{ form_start(form, {'attr': {'class': 'mb-3'}}) }}
|
||||||
{{ form_widget(form) }}
|
{{ form_widget(form, {'attr': {'class': 'form-control'}}) }}
|
||||||
<button class="btn">{{ button_label|default('Save') }}</button>
|
<button class="btn btn-primary mt-2">{{ button_label|default('Save') }}</button>
|
||||||
{{ form_end(form) }}
|
{{ form_end(form) }}
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
{% block title %}Edit OrderItem{% endblock %}
|
{% block title %}Edit OrderItem{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>Edit OrderItem</h1>
|
<h1 class="mb-4">Edit OrderItem</h1>
|
||||||
|
|
||||||
{{ include('order_item/_form.html.twig', {'button_label': 'Update'}) }}
|
<div class="mb-4">
|
||||||
|
{{ include('order_item/_form.html.twig', {'button_label': 'Update'}) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<a href="{{ path('app_food_order_show', {'id': order_item.foodOrder.id}) }}">back to list</a>
|
<a class="btn btn-secondary" href="{{ path('app_food_order_show', {'id': order_item.foodOrder.id}) }}">back to list</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -3,30 +3,32 @@
|
||||||
{% block title %}New OrderItem{% endblock %}
|
{% block title %}New OrderItem{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>Create new OrderItem</h1>
|
<h1 class="mb-4">Create new OrderItem</h1>
|
||||||
|
|
||||||
{{ include('order_item/_form.html.twig') }}
|
<div class="mb-4">
|
||||||
|
{{ include('order_item/_form.html.twig') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
{% if food_order.foodVendor.menuLink != '' %}
|
{% if food_order.foodVendor.menuLink != '' %}
|
||||||
<a href="{{ food_order.foodVendor.menuLink }}" target="_blank">
|
<a class="btn btn-outline-secondary mb-3" href="{{ food_order.foodVendor.menuLink }}" target="_blank">
|
||||||
External link to Menu
|
External link to Menu
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div>
|
<div class="mb-2">
|
||||||
<b>click a button to select a given menuitem</b>
|
<b>click a button to select a given menuitem</b>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="mb-3 d-flex flex-wrap gap-2">
|
||||||
{% for menuItem in menuItems %}
|
{% for menuItem in menuItems %}
|
||||||
<a href="#" data-menu-item>{{ menuItem.name }}</a>
|
<a class="btn btn-outline-info btn-sm" href="#" data-menu-item>{{ menuItem.name }}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<a class="button" href="{{ path('app_food_order_show', { 'id': food_order.id}) }}">back to list</a>
|
<a class="btn btn-secondary" href="{{ path('app_food_order_show', { 'id': food_order.id}) }}">back to list</a>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.querySelectorAll('[data-menu-item]').forEach(function(element) {
|
document.querySelectorAll('[data-menu-item]').forEach(function(element) {
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
{% block title %}Tell me your name{% endblock %}
|
{% block title %}Tell me your name{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1>Tell me your name</h1>
|
<h1 class="mb-4">Tell me your name</h1>
|
||||||
<p>By submitting the form, you agree that your username will be stored as a cookie.</p>
|
<p class="mb-3">By submitting the form, you agree that your username will be stored as a cookie.</p>
|
||||||
{{ include('_form.html.twig') }}
|
<div class="mb-4">
|
||||||
|
{{ include('_form.html.twig') }}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -100,15 +100,15 @@ describe(FoodOrderController::class, function (): void {
|
||||||
$crawler = $this->client->request('GET', "{$this->path}{$order->getId()}");
|
$crawler = $this->client->request('GET', "{$this->path}{$order->getId()}");
|
||||||
$this->assertResponseIsSuccessful();
|
$this->assertResponseIsSuccessful();
|
||||||
$tdContent = $crawler->filter(
|
$tdContent = $crawler->filter(
|
||||||
'table.table:nth-child(6) > tbody:nth-child(2) > tr:nth-child(1) > td:nth-child(3)'
|
'table.table-hover tbody tr:nth-child(1) td:nth-child(3)'
|
||||||
)->text();
|
)->text();
|
||||||
$this->assertEquals('A', $tdContent);
|
$this->assertEquals('A', $tdContent);
|
||||||
$tdContent = $crawler->filter(
|
$tdContent = $crawler->filter(
|
||||||
'table.table:nth-child(6) > tbody:nth-child(2) > tr:nth-child(2) > td:nth-child(3)'
|
'table.table-hover tbody tr:nth-child(2) td:nth-child(3)'
|
||||||
)->text();
|
)->text();
|
||||||
$this->assertEquals('B', $tdContent);
|
$this->assertEquals('B', $tdContent);
|
||||||
$tdContent = $crawler->filter(
|
$tdContent = $crawler->filter(
|
||||||
'table.table:nth-child(6) > tbody:nth-child(2) > tr:nth-child(3) > td:nth-child(3)'
|
'table.table-hover tbody tr:nth-child(3) td:nth-child(3)'
|
||||||
)->text();
|
)->text();
|
||||||
$this->assertEquals('C', $tdContent);
|
$this->assertEquals('C', $tdContent);
|
||||||
});
|
});
|
||||||
|
|
|
@ -119,7 +119,7 @@ describe(FoodVendorController::class, function (): void {
|
||||||
)->text();
|
)->text();
|
||||||
$this->assertSame('My Title', $nameNode);
|
$this->assertSame('My Title', $nameNode);
|
||||||
|
|
||||||
$itemNodes = $crawler->filter('li');
|
$itemNodes = $crawler->filter('ul.list-group li.list-group-item');
|
||||||
|
|
||||||
$this->assertCount(4, $itemNodes);
|
$this->assertCount(4, $itemNodes);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue