| |
| |
|
|
| const defaultData = { |
| releases: [ |
| { |
| id: 1, |
| title: "Neural Network", |
| artist: "Cybernetic", |
| genre: "Neurofunk", |
| year: "2024", |
| image: "http://static.photos/technology/640x360/1", |
| link: "#" |
| }, |
| { |
| id: 2, |
| title: "Dark Matter", |
| artist: "Synapse", |
| genre: "Techstep", |
| year: "2024", |
| image: "http://static.photos/abstract/640x360/2", |
| link: "#" |
| }, |
| { |
| id: 3, |
| title: "System Shock", |
| artist: "Binary Soul", |
| genre: "Breakbeat", |
| year: "2023", |
| image: "http://static.photos/industry/640x360/3", |
| link: "#" |
| }, |
| { |
| id: 4, |
| title: "Core Dump", |
| artist: "Null Pointer", |
| genre: "DnB", |
| year: "2024", |
| image: "http://static.photos/technology/640x360/4", |
| link: "#" |
| } |
| ], |
| artists: [ |
| { |
| id: 1, |
| name: "Cybernetic", |
| genre: "Neurofunk", |
| bio: "Піонер української нейрофанк сцени. Виробляє потужні басові лінії з 2019 року.", |
| image: "http://static.photos/people/640x360/10", |
| soundcloud: "#", |
| instagram: "#" |
| }, |
| { |
| id: 2, |
| name: "Synapse", |
| genre: "Techstep", |
| bio: "Майстер темних атмосфер та агресивних ритмів.", |
| image: "http://static.photos/people/640x360/11", |
| soundcloud: "#", |
| instagram: "#" |
| }, |
| { |
| id: 3, |
| name: "Binary Soul", |
| genre: "Breakbeat", |
| bio: "Експериментатор, що поєднує класичний брейкбіт з сучасним звучанням.", |
| image: "http://static.photos/people/640x360/12", |
| soundcloud: "#", |
| instagram: "#" |
| } |
| ], |
| events: [ |
| { |
| id: 1, |
| title: "CORE64 Label Night", |
| date: "2024-02-15", |
| time: "22:00", |
| venue: "Київ, Atlas", |
| description: "Великий лейбл-ніч з усіма артистами CORE64.", |
| image: "http://static.photos/nightlife/640x360/20" |
| }, |
| { |
| id: 2, |
| title: "Neurofunk Madness", |
| date: "2024-03-01", |
| time: "23:00", |
| venue: "Львів, !FESTrepublic", |
| description: "Вечірка присвячена найважчому нейрофанку.", |
| image: "http://static.photos/nightlife/640x360/21" |
| } |
| ], |
| settings: { |
| title: "CORE64 Records", |
| about: "CORE64 Records — незалежний музичний лейбл, заснований у 2024 році. Ми спеціалізуємося на найважчих жанрах електронної музики: Neurofunk, Techstep, Darkstep та Breakbeat.", |
| mission: "Наша місія — підтримувати андерграунд сцену та виводити Drum & Bass на новий рівень. Кожен реліз — це унікальна історія, закодована в звуках синтезаторів та ритмах барабанів.", |
| email: "demo@core64.records", |
| password: "core64admin" |
| } |
| }; |
|
|
| |
| function initData() { |
| if (!localStorage.getItem('core64_data')) { |
| localStorage.setItem('core64_data', JSON.stringify(defaultData)); |
| } |
| return JSON.parse(localStorage.getItem('core64_data')); |
| } |
|
|
| |
| function getData() { |
| return JSON.parse(localStorage.getItem('core64_data')) || defaultData; |
| } |
|
|
| |
| function saveData(data) { |
| localStorage.setItem('core64_data', JSON.stringify(data)); |
| } |
|
|
| |
| function renderReleases() { |
| const data = getData(); |
| const grid = document.getElementById('releases-grid'); |
| if (!grid) return; |
| |
| grid.innerHTML = data.releases.map(release => ` |
| <div class="release-card border border-cyan-500/20 rounded-lg overflow-hidden group cursor-pointer"> |
| <div class="relative aspect-square overflow-hidden bg-gray-900"> |
| <img src="${release.image}" alt="${release.title}" class="w-full h-full object-cover vinyl-spin"> |
| <div class="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-4"> |
| <button class="p-3 bg-cyan-400 rounded-full text-black hover:scale-110 transition-transform"> |
| <i data-lucide="play" class="w-6 h-6 fill-current"></i> |
| </button> |
| </div> |
| <div class="absolute top-2 right-2 genre-tag px-3 py-1 text-xs rounded uppercase tracking-wider"> |
| ${release.genre} |
| </div> |
| </div> |
| <div class="p-4"> |
| <h3 class="text-xl font-bold text-white mb-1 group-hover:text-cyan-400 transition-colors">${release.title}</h3> |
| <p class="text-gray-400 text-sm mb-2">${release.artist}</p> |
| <div class="flex justify-between items-center text-xs text-gray-500 uppercase tracking-wider"> |
| <span>${release.year}</span> |
| <span class="text-cyan-400">CORE64</span> |
| </div> |
| </div> |
| </div> |
| `).join(''); |
| |
| |
| const statEl = document.getElementById('stat-releases'); |
| if (statEl) statEl.textContent = data.releases.length; |
| |
| if (window.lucide) lucide.createIcons(); |
| } |
|
|
| |
| function renderArtists() { |
| const data = getData(); |
| const grid = document.getElementById('artists-grid'); |
| if (!grid) return; |
| |
| grid.innerHTML = data.artists.map(artist => ` |
| <div class="card rounded-lg overflow-hidden group"> |
| <div class="relative aspect-[4/3] overflow-hidden"> |
| <img src="${artist.image}" alt="${artist.name}" class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"> |
| <div class="absolute inset-0 bg-gradient-to-t from-black via-transparent to-transparent"></div> |
| <div class="absolute bottom-0 left-0 right-0 p-6"> |
| <span class="inline-block px-3 py-1 bg-pink-500/20 border border-pink-500/50 text-pink-400 text-xs rounded uppercase tracking-wider mb-2"> |
| ${artist.genre} |
| </span> |
| <h3 class="text-2xl font-bold text-white">${artist.name}</h3> |
| </div> |
| </div> |
| <div class="p-6"> |
| <p class="text-gray-400 text-sm mb-4 line-clamp-2">${artist.bio}</p> |
| <div class="flex gap-3"> |
| <a href="${artist.soundcloud}" class="p-2 bg-gray-800 rounded hover:bg-cyan-400 hover:text-black transition-colors"> |
| <i data-lucide="music" class="w-4 h-4"></i> |
| </a> |
| <a href="${artist.instagram}" class="p-2 bg-gray-800 rounded hover:bg-pink-400 hover:text-black transition-colors"> |
| <i data-lucide="instagram" class="w-4 h-4"></i> |
| </a> |
| </div> |
| </div> |
| </div> |
| `).join(''); |
| |
| |
| const statEl = document.getElementById('stat-artists'); |
| if (statEl) statEl.textContent = data.artists.length; |
| |
| if (window.lucide) lucide.createIcons(); |
| } |
|
|
| |
| function renderEvents() { |
| const data = getData(); |
| const list = document.getElementById('events-list'); |
| if (!list) return; |
| |
| const sortedEvents = [...data.events].sort((a, b) => new Date(a.date) - new Date(b.date)); |
| |
| list.innerHTML = sortedEvents.map(event => { |
| const eventDate = new Date(event.date); |
| const day = eventDate.getDate(); |
| const month = eventDate.toLocaleDateString('uk-UA', { month: 'short' }); |
| |
| return ` |
| <div class="flex flex-col md:flex-row gap-6 p-6 border border-green-500/20 rounded-lg hover:border-green-500/50 transition-colors bg-black/30"> |
| <div class="flex-shrink-0 w-full md:w-48 h-32 overflow-hidden rounded border border-green-500/30"> |
| <img src="${event.image}" alt="${event.title}" class="w-full h-full object-cover"> |
| </div> |
| <div class="flex-1"> |
| <div class="flex flex-col md:flex-row md:items-center justify-between mb-2"> |
| <h3 class="text-2xl font-bold text-white">${event.title}</h3> |
| <div class="flex items-center gap-2 text-green-400 mt-2 md:mt-0"> |
| <i data-lucide="calendar" class="w-4 h-4"></i> |
| <span class="uppercase tracking-wider text-sm">${day} ${month} • ${event.time}</span> |
| </div> |
| </div> |
| <div class="flex items-center gap-2 text-gray-400 mb-3"> |
| <i data-lucide="map-pin" class="w-4 h-4"></i> |
| <span>${event.venue}</span> |
| </div> |
| <p class="text-gray-300">${event.description}</p> |
| </div> |
| <div class="flex-shrink-0 flex items-center"> |
| <button class="px-6 py-3 border border-green-400 text-green-400 hover:bg-green-400 hover:text-black transition-all uppercase tracking-wider text-sm font-bold"> |
| Квитки |
| </button> |
| </div> |
| </div> |
| `; |
| }).join(''); |
| |
| if (window.lucide) lucide.createIcons(); |
| } |
|
|
| |
| function toggleMobileMenu() { |
| const menu = document.getElementById('mobile-menu'); |
| menu.classList.toggle('hidden'); |
| } |
|
|
| |
| function scrollToSection(id) { |
| const element = document.getElementById(id); |
| if (element) { |
| element.scrollIntoView({ behavior: 'smooth' }); |
| |
| const mobileMenu = document.getElementById('mobile-menu'); |
| if (mobileMenu) mobileMenu.classList.add('hidden'); |
| } |
| } |
|
|
| |
| function initContactForm() { |
| const form = document.getElementById('contact-form'); |
| if (form) { |
| form.addEventListener('submit', (e) => { |
| e.preventDefault(); |
| alert('Дякуємо за повідомлення! Ми зв\'яжемося з вами найближчим часом.'); |
| form.reset(); |
| }); |
| } |
| } |
|
|
| |
| document.addEventListener('DOMContentLoaded', () => { |
| initData(); |
| renderReleases(); |
| renderArtists(); |
| renderEvents(); |
| initContactForm(); |
| |
| |
| const data = getData(); |
| const aboutEl = document.getElementById('about-text'); |
| if (aboutEl && data.settings.about) { |
| aboutEl.textContent = data.settings.about; |
| } |
| |
| |
| const missionEl = document.getElementById('about-mission'); |
| if (missionEl && data.settings.mission) { |
| missionEl.textContent = data.settings.mission; |
| } |
| }); |