Created
August 2, 2025 01:51
-
-
Save oshkoshbagoshh/a31e268972cf9d7848b6dac6be77ef4b to your computer and use it in GitHub Desktop.
zzDynamoPHP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| // TODO: - set constants, create backend initiatization / startup stcript | |
| //TODO - test database connection, | |
| //TODO: - handle user auth and authorization (some routes locked off base on role) | |
| // TODO - PHP sessions | |
| // TODO - Front end common / initialization. | |
| // TODO: common files / partials / comonents | |
| // todo: data handlers for AJAX | |
| // TODO: getters, setters, CRUD | |
| // TODO: worry about front end styling later.... | |
| ?> | |
| <!doctype html> | |
| <html lang="en"> | |
| <head> | |
| <title>TFN Music Platform</title> | |
| <!-- Required meta tags --> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | |
| <!-- Tailwind CSS CDN --> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <!-- Alpine.js CDN --> | |
| <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> | |
| <!-- FontAwesome for icons --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| /* smooth scrolling */ | |
| html { scroll-behavior: smooth; } | |
| /* horizontal carousel */ | |
| .scroll-container { | |
| scroll-snap-type: x mandatory; | |
| } | |
| .scroll-item { | |
| scroll-snap-align: center; | |
| } | |
| /* PHP dynamic content highlight */ | |
| .php-dynamic { | |
| border: 2px dashed #8b5cf6; | |
| position: relative; | |
| } | |
| .php-dynamic::after { | |
| content: "PHP"; | |
| position: absolute; | |
| top: -10px; | |
| right: -10px; | |
| background: #8b5cf6; | |
| color: white; | |
| font-size: 10px; | |
| padding: 2px 6px; | |
| border-radius: 4px; | |
| z-index: 10; | |
| } | |
| /* Custom utility class for aspect ratio */ | |
| .pb-3\/4 { | |
| padding-bottom: 75%; | |
| position: relative; | |
| } | |
| /* Skeleton loading animation */ | |
| @keyframes pulse { | |
| 0%, 100% { | |
| opacity: 0.6; | |
| } | |
| 50% { | |
| opacity: 0.3; | |
| } | |
| } | |
| .skeleton { | |
| animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; | |
| } | |
| </style> | |
| </head> | |
| <body id="top" class="bg-gray-50"> | |
| <!-- Navbar --> | |
| <nav class="bg-white shadow" x-data="{ open: false }"> | |
| <div class="container mx-auto px-4"> | |
| <div class="flex justify-between items-center h-16"> | |
| <div class="flex items-center"> | |
| <a href="#" class="font-bold text-xl text-indigo-600 php-dynamic">TFN Music</a> | |
| </div> | |
| <!-- Mobile menu button --> | |
| <div class="md:hidden"> | |
| <button @click="open = !open" class="text-gray-500 hover:text-gray-600 focus:outline-none"> | |
| <i class="fas fa-bars" x-show="!open"></i> | |
| <i class="fas fa-times" x-show="open"></i> | |
| </button> | |
| </div> | |
| <!-- Desktop menu --> | |
| <div class="hidden md:flex space-x-4 php-dynamic"> | |
| <a href="#albums" class="text-gray-700 hover:text-indigo-600">Albums</a> | |
| <a href="#featured-tracks" class="text-gray-700 hover:text-indigo-600">Tracks</a> | |
| <a href="#artist-of-week" class="text-gray-700 hover:text-indigo-600">Artist</a> | |
| <a href="#filters" class="text-gray-700 hover:text-indigo-600">Filters</a> | |
| </div> | |
| </div> | |
| <!-- Mobile menu --> | |
| <div class="md:hidden" x-show="open" x-transition> | |
| <div class="px-2 pt-2 pb-3 space-y-1 php-dynamic"> | |
| <a href="#albums" class="block px-3 py-2 rounded text-gray-700 hover:bg-indigo-100 hover:text-indigo-600">Albums</a> | |
| <a href="#featured-tracks" class="block px-3 py-2 rounded text-gray-700 hover:bg-indigo-100 hover:text-indigo-600">Tracks</a> | |
| <a href="#artist-of-week" class="block px-3 py-2 rounded text-gray-700 hover:bg-indigo-100 hover:text-indigo-600">Artist</a> | |
| <a href="#filters" class="block px-3 py-2 rounded text-gray-700 hover:bg-indigo-100 hover:text-indigo-600">Filters</a> | |
| </div> | |
| </div> | |
| </div> | |
| </nav> | |
| <!-- Main content --> | |
| <main class="container mx-auto px-4 py-8"> | |
| <!-- Albums grid --> | |
| <section id="albums" class="mb-12"> | |
| <h2 class="text-2xl font-bold mb-6 flex items-center"> | |
| <span class="mr-2"><i class="fas fa-compact-disc text-indigo-600"></i></span> | |
| Albums | |
| </h2> | |
| <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6 php-dynamic"> | |
| <!-- Album Card Template - Will be repeated with PHP --> | |
| <div class="bg-white rounded-lg shadow overflow-hidden"> | |
| <div class="relative pb-3/4"> | |
| <!-- SVG Placeholder instead of image --> | |
| <svg class="absolute inset-0 h-full w-full skeleton" xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 300 225" preserveAspectRatio="xMidYMid slice"> | |
| <rect width="100%" height="100%" fill="#cbd5e1"></rect> | |
| <path d="M145,80 L155,80 L155,145 L145,145 Z" fill="#94a3b8"></path> | |
| <circle cx="150" cy="70" r="10" fill="#94a3b8"></circle> | |
| <path d="M130,170 L170,170 M120,180 L180,180 M110,190 L190,190" stroke="#94a3b8" stroke-width="5"></path> | |
| </svg> | |
| </div> | |
| <div class="p-4"> | |
| <p class="font-semibold">Album Title</p> | |
| <p class="text-sm text-gray-600">Artist Name</p> | |
| </div> | |
| </div> | |
| <!-- Additional Album Skeletons --> | |
| <div class="bg-white rounded-lg shadow overflow-hidden"> | |
| <div class="relative pb-3/4"> | |
| <svg class="absolute inset-0 h-full w-full skeleton" xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 300 225" preserveAspectRatio="xMidYMid slice"> | |
| <rect width="100%" height="100%" fill="#cbd5e1"></rect> | |
| <path d="M145,80 L155,80 L155,145 L145,145 Z" fill="#94a3b8"></path> | |
| <circle cx="150" cy="70" r="10" fill="#94a3b8"></circle> | |
| <path d="M130,170 L170,170 M120,180 L180,180 M110,190 L190,190" stroke="#94a3b8" stroke-width="5"></path> | |
| </svg> | |
| </div> | |
| <div class="p-4"> | |
| <div class="h-4 bg-gray-200 rounded skeleton w-3/4 mb-2"></div> | |
| <div class="h-3 bg-gray-200 rounded skeleton w-1/2"></div> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-lg shadow overflow-hidden hidden sm:block"> | |
| <div class="relative pb-3/4"> | |
| <svg class="absolute inset-0 h-full w-full skeleton" xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 300 225" preserveAspectRatio="xMidYMid slice"> | |
| <rect width="100%" height="100%" fill="#cbd5e1"></rect> | |
| <path d="M145,80 L155,80 L155,145 L145,145 Z" fill="#94a3b8"></path> | |
| <circle cx="150" cy="70" r="10" fill="#94a3b8"></circle> | |
| <path d="M130,170 L170,170 M120,180 L180,180 M110,190 L190,190" stroke="#94a3b8" stroke-width="5"></path> | |
| </svg> | |
| </div> | |
| <div class="p-4"> | |
| <div class="h-4 bg-gray-200 rounded skeleton w-3/4 mb-2"></div> | |
| <div class="h-3 bg-gray-200 rounded skeleton w-1/2"></div> | |
| </div> | |
| </div> | |
| <div class="bg-white rounded-lg shadow overflow-hidden hidden md:block"> | |
| <div class="relative pb-3/4"> | |
| <svg class="absolute inset-0 h-full w-full skeleton" xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 300 225" preserveAspectRatio="xMidYMid slice"> | |
| <rect width="100%" height="100%" fill="#cbd5e1"></rect> | |
| <path d="M145,80 L155,80 L155,145 L145,145 Z" fill="#94a3b8"></path> | |
| <circle cx="150" cy="70" r="10" fill="#94a3b8"></circle> | |
| <path d="M130,170 L170,170 M120,180 L180,180 M110,190 L190,190" stroke="#94a3b8" stroke-width="5"></path> | |
| </svg> | |
| </div> | |
| <div class="p-4"> | |
| <div class="h-4 bg-gray-200 rounded skeleton w-3/4 mb-2"></div> | |
| <div class="h-3 bg-gray-200 rounded skeleton w-1/2"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Featured tracks carousel --> | |
| <section id="featured-tracks" class="mb-12"> | |
| <h2 class="text-2xl font-bold mb-6 flex items-center"> | |
| <span class="mr-2"><i class="fas fa-music text-indigo-600"></i></span> | |
| Featured Tracks | |
| </h2> | |
| <div class="scroll-container flex overflow-x-auto gap-4 pb-4 php-dynamic"> | |
| <!-- Track Card Template - Will be repeated with PHP --> | |
| <div class="scroll-item flex-none w-48 md:w-56 bg-white rounded-lg shadow"> | |
| <div class="relative pb-3/4"> | |
| <svg class="absolute inset-0 h-full w-full skeleton" xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 300 225" preserveAspectRatio="xMidYMid slice"> | |
| <rect width="100%" height="100%" fill="#cbd5e1"></rect> | |
| <circle cx="150" cy="100" r="30" fill="#94a3b8"></circle> | |
| <path d="M150,70 L150,130" stroke="#94a3b8" stroke-width="5"></path> | |
| <path d="M130,100 L130,150 Q130,170 150,170 Q170,170 170,150 L170,100" stroke="#94a3b8" stroke-width="5" fill="none"></path> | |
| </svg> | |
| </div> | |
| <div class="p-4"> | |
| <p class="font-semibold">Track Title</p> | |
| <p class="text-sm text-gray-600">Artist</p> | |
| </div> | |
| </div> | |
| <!-- Additional Track Skeletons --> | |
| <div class="scroll-item flex-none w-48 md:w-56 bg-white rounded-lg shadow"> | |
| <div class="relative pb-3/4"> | |
| <svg class="absolute inset-0 h-full w-full skeleton" xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 300 225" preserveAspectRatio="xMidYMid slice"> | |
| <rect width="100%" height="100%" fill="#cbd5e1"></rect> | |
| <circle cx="150" cy="100" r="30" fill="#94a3b8"></circle> | |
| <path d="M150,70 L150,130" stroke="#94a3b8" stroke-width="5"></path> | |
| <path d="M130,100 L130,150 Q130,170 150,170 Q170,170 170,150 L170,100" stroke="#94a3b8" stroke-width="5" fill="none"></path> | |
| </svg> | |
| </div> | |
| <div class="p-4"> | |
| <div class="h-4 bg-gray-200 rounded skeleton w-3/4 mb-2"></div> | |
| <div class="h-3 bg-gray-200 rounded skeleton w-1/2"></div> | |
| </div> | |
| </div> | |
| <div class="scroll-item flex-none w-48 md:w-56 bg-white rounded-lg shadow"> | |
| <div class="relative pb-3/4"> | |
| <svg class="absolute inset-0 h-full w-full skeleton" xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 300 225" preserveAspectRatio="xMidYMid slice"> | |
| <rect width="100%" height="100%" fill="#cbd5e1"></rect> | |
| <circle cx="150" cy="100" r="30" fill="#94a3b8"></circle> | |
| <path d="M150,70 L150,130" stroke="#94a3b8" stroke-width="5"></path> | |
| <path d="M130,100 L130,150 Q130,170 150,170 Q170,170 170,150 L170,100" stroke="#94a3b8" stroke-width="5" fill="none"></path> | |
| </svg> | |
| </div> | |
| <div class="p-4"> | |
| <div class="h-4 bg-gray-200 rounded skeleton w-3/4 mb-2"></div> | |
| <div class="h-3 bg-gray-200 rounded skeleton w-1/2"></div> | |
| </div> | |
| </div> | |
| <div class="scroll-item flex-none w-48 md:w-56 bg-white rounded-lg shadow"> | |
| <div class="relative pb-3/4"> | |
| <svg class="absolute inset-0 h-full w-full skeleton" xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 300 225" preserveAspectRatio="xMidYMid slice"> | |
| <rect width="100%" height="100%" fill="#cbd5e1"></rect> | |
| <circle cx="150" cy="100" r="30" fill="#94a3b8"></circle> | |
| <path d="M150,70 L150,130" stroke="#94a3b8" stroke-width="5"></path> | |
| <path d="M130,100 L130,150 Q130,170 150,170 Q170,170 170,150 L170,100" stroke="#94a3b8" stroke-width="5" fill="none"></path> | |
| </svg> | |
| </div> | |
| <div class="p-4"> | |
| <div class="h-4 bg-gray-200 rounded skeleton w-3/4 mb-2"></div> | |
| <div class="h-3 bg-gray-200 rounded skeleton w-1/2"></div> | |
| </div> | |
| </div> | |
| <div class="scroll-item flex-none w-48 md:w-56 bg-white rounded-lg shadow"> | |
| <div class="relative pb-3/4"> | |
| <svg class="absolute inset-0 h-full w-full skeleton" xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 300 225" preserveAspectRatio="xMidYMid slice"> | |
| <rect width="100%" height="100%" fill="#cbd5e1"></rect> | |
| <circle cx="150" cy="100" r="30" fill="#94a3b8"></circle> | |
| <path d="M150,70 L150,130" stroke="#94a3b8" stroke-width="5"></path> | |
| <path d="M130,100 L130,150 Q130,170 150,170 Q170,170 170,150 L170,100" stroke="#94a3b8" stroke-width="5" fill="none"></path> | |
| </svg> | |
| </div> | |
| <div class="p-4"> | |
| <div class="h-4 bg-gray-200 rounded skeleton w-3/4 mb-2"></div> | |
| <div class="h-3 bg-gray-200 rounded skeleton w-1/2"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Artist of the Week --> | |
| <section id="artist-of-week" class="mb-12 php-dynamic"> | |
| <h2 class="text-2xl font-bold mb-6 flex items-center"> | |
| <span class="mr-2"><i class="fas fa-star text-indigo-600"></i></span> | |
| TFN Artist of the Week | |
| </h2> | |
| <div class="bg-white p-6 rounded-lg shadow"> | |
| <div class="flex flex-col sm:flex-row items-start"> | |
| <div class="flex-shrink-0 mb-4 sm:mb-0 sm:mr-4"> | |
| <!-- Artist Avatar Placeholder --> | |
| <svg class="w-16 h-16 rounded-full skeleton" xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 64 64" preserveAspectRatio="xMidYMid slice"> | |
| <rect width="100%" height="100%" fill="#cbd5e1" rx="32" ry="32"></rect> | |
| <circle cx="32" cy="26" r="8" fill="#94a3b8"></circle> | |
| <path d="M20,48 C20,40 26,38 32,38 C38,38 44,40 44,48" fill="#94a3b8"></path> | |
| </svg> | |
| </div> | |
| <div class="flex-grow"> | |
| <div class="mb-2"> | |
| <p class="font-bold text-lg">Artist Name</p> | |
| <p class="text-sm text-gray-600">@artist</p> | |
| </div> | |
| <p class="text-gray-700 mb-4"> | |
| A brief bio or highlight of the featured artist. This artist has been making waves in the industry with their unique sound and captivating performances. | |
| </p> | |
| <div class="flex space-x-2"> | |
| <button class="flex items-center text-sm text-indigo-600 hover:text-indigo-800"> | |
| <i class="fas fa-user-plus mr-1"></i> Follow | |
| </button> | |
| <button class="flex items-center text-sm text-indigo-600 hover:text-indigo-800"> | |
| <i class="fas fa-share-alt mr-1"></i> Share | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Aside filters --> | |
| <aside class="container mx-auto px-4 py-6" id="filters"> | |
| <div class="bg-white p-6 rounded-lg shadow" x-data="{ openFilter: null }"> | |
| <p class="font-bold text-lg mb-4 flex items-center"> | |
| <span class="mr-2"><i class="fas fa-filter text-indigo-600"></i></span> | |
| Filters | |
| </p> | |
| <ul class="space-y-1 php-dynamic"> | |
| <!-- Genre Filter - Will be populated by PHP --> | |
| <li> | |
| <button @click="openFilter = openFilter === 'genre' ? null : 'genre'" | |
| class="w-full flex justify-between items-center p-3 rounded hover:bg-indigo-50 focus:outline-none"> | |
| <span class="flex items-center"> | |
| <i class="fas fa-music text-indigo-600 mr-2"></i> | |
| Genre | |
| </span> | |
| <i class="fas" :class="openFilter === 'genre' ? 'fa-chevron-up' : 'fa-chevron-down'"></i> | |
| </button> | |
| <div x-show="openFilter === 'genre'" x-transition class="pl-8 py-2 space-y-1"> | |
| <label class="flex items-center space-x-2 cursor-pointer"> | |
| <input type="checkbox" class="form-checkbox text-indigo-600"> | |
| <span>Rock</span> | |
| </label> | |
| <label class="flex items-center space-x-2 cursor-pointer"> | |
| <input type="checkbox" class="form-checkbox text-indigo-600"> | |
| <span>Pop</span> | |
| </label> | |
| <label class="flex items-center space-x-2 cursor-pointer"> | |
| <input type="checkbox" class="form-checkbox text-indigo-600"> | |
| <span>Jazz</span> | |
| </label> | |
| </div> | |
| </li> | |
| <!-- Mood Filter - Will be populated by PHP --> | |
| <li> | |
| <button @click="openFilter = openFilter === 'mood' ? null : 'mood'" | |
| class="w-full flex justify-between items-center p-3 rounded hover:bg-indigo-50 focus:outline-none"> | |
| <span class="flex items-center"> | |
| <i class="fas fa-smile text-indigo-600 mr-2"></i> | |
| Mood | |
| </span> | |
| <i class="fas" :class="openFilter === 'mood' ? 'fa-chevron-up' : 'fa-chevron-down'"></i> | |
| </button> | |
| <div x-show="openFilter === 'mood'" x-transition class="pl-8 py-2 space-y-1"> | |
| <label class="flex items-center space-x-2 cursor-pointer"> | |
| <input type="checkbox" class="form-checkbox text-indigo-600"> | |
| <span>Happy</span> | |
| </label> | |
| <label class="flex items-center space-x-2 cursor-pointer"> | |
| <input type="checkbox" class="form-checkbox text-indigo-600"> | |
| <span>Chill</span> | |
| </label> | |
| <label class="flex items-center space-x-2 cursor-pointer"> | |
| <input type="checkbox" class="form-checkbox text-indigo-600"> | |
| <span>Energetic</span> | |
| </label> | |
| </div> | |
| </li> | |
| <!-- Instrument Filter - Will be populated by PHP --> | |
| <li> | |
| <button @click="openFilter = openFilter === 'instrument' ? null : 'instrument'" | |
| class="w-full flex justify-between items-center p-3 rounded hover:bg-indigo-50 focus:outline-none"> | |
| <span class="flex items-center"> | |
| <i class="fas fa-guitar text-indigo-600 mr-2"></i> | |
| Instrument | |
| </span> | |
| <i class="fas" :class="openFilter === 'instrument' ? 'fa-chevron-up' : 'fa-chevron-down'"></i> | |
| </button> | |
| <div x-show="openFilter === 'instrument'" x-transition class="pl-8 py-2 space-y-1"> | |
| <label class="flex items-center space-x-2 cursor-pointer"> | |
| <input type="checkbox" class="form-checkbox text-indigo-600"> | |
| <span>Guitar</span> | |
| </label> | |
| <label class="flex items-center space-x-2 cursor-pointer"> | |
| <input type="checkbox" class="form-checkbox text-indigo-600"> | |
| <span>Piano</span> | |
| </label> | |
| <label class="flex items-center space-x-2 cursor-pointer"> | |
| <input type="checkbox" class="form-checkbox text-indigo-600"> | |
| <span>Drums</span> | |
| </label> | |
| </div> | |
| </li> | |
| </ul> | |
| </div> | |
| </aside> | |
| <!-- Flash messages / alerts --> | |
| <section class="container mx-auto px-4 py-6 php-dynamic" x-data="{ showMessage: true }"> | |
| <div x-show="showMessage" x-transition class="bg-blue-50 border-l-4 border-blue-500 text-blue-700 p-4 rounded shadow-md"> | |
| <div class="flex justify-between items-start"> | |
| <div class="flex items-center"> | |
| <i class="fas fa-info-circle mr-2"></i> | |
| <div> | |
| <p class="font-bold">Info</p> | |
| <p>This is an informational flash message.</p> | |
| </div> | |
| </div> | |
| <button @click="showMessage = false" class="text-blue-700 hover:text-blue-900"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Footer --> | |
| <footer class="bg-gray-800 text-white py-8"> | |
| <div class="container mx-auto px-4 text-center"> | |
| <p class="mb-4 php-dynamic">© 2025 TFN Music Platform</p> | |
| <a href="#top" class="inline-flex items-center px-4 py-2 bg-gray-700 hover:bg-gray-600 rounded transition duration-200"> | |
| <i class="fas fa-arrow-up mr-2"></i> | |
| Back to top | |
| </a> | |
| <div class="mt-6 flex justify-center space-x-6 php-dynamic"> | |
| <a href="#" class="text-gray-400 hover:text-white"> | |
| <i class="fab fa-facebook-f"></i> | |
| </a> | |
| <a href="#" class="text-gray-400 hover:text-white"> | |
| <i class="fab fa-twitter"></i> | |
| </a> | |
| <a href="#" class="text-gray-400 hover:text-white"> | |
| <i class="fab fa-instagram"></i> | |
| </a> | |
| <a href="#" class="text-gray-400 hover:text-white"> | |
| <i class="fab fa-youtube"></i> | |
| </a> | |
| </div> | |
| </div> | |
| </footer> | |
| <!-- Alpine.js Initialization --> | |
| <script> | |
| // Any additional Alpine.js initialization can go here | |
| document.addEventListener('alpine:init', () => { | |
| // You can define custom Alpine.js data and functions here | |
| }); | |
| </script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment