diff --git a/client/src/data.js b/client/src/data.js index b9c6e38..53a4edc 100644 --- a/client/src/data.js +++ b/client/src/data.js @@ -1,5 +1,77 @@ // Static data for rmzi.world - no backend needed +export const projects = [ + { + id: 'p1', + title: '36247', + subtitle: 'Memphis Rap streaming service — 2,091 tracks, no tracking', + url: 'https://36247.rmzi.world', + }, + { + id: 'p2', + title: 'Crate', + subtitle: 'Free-to-use music streaming platform', + url: 'https://crate.rmzi.world', + }, +]; + +export const press = [ + { + id: 'pr1', + title: 'Are Hackathons Worth It? Five Participants Weigh In', + source: 'WNYC', + date: '2013-09-18', + url: 'https://www.wnycstudios.org/podcasts/notetoself/segments/are-hackathons-worth-it-five-participants-weigh', + }, + { + id: 'pr2', + title: 'And the Winner of the First Ever Fashion Hackathon Is...', + source: 'Fashionista', + date: '2013-02-13', + url: 'https://fashionista.com/2013/02/and-the-winner-of-the-first-ever-fashion-hackathon-is', + }, + { + id: 'pr3', + title: 'Fashion Hackathon Comes to NYFW', + source: 'WWD', + date: '2013-02-13', + url: 'https://wwd.com/fashion-news/fashion-scoops/feature/fashion-hackathon-comes-to-nyfw-6621485-450231/', + }, + { + id: 'pr4', + title: 'Tech is the New Black: Decoded Fashion at Mercedes Benz Fashion Week', + source: 'AlleyWatch', + date: '2013-02-13', + url: 'https://www.alleywatch.com/2013/02/tech-is-the-new-black-decoded-fashion-at-mercedes-benz-fashion-week/', + }, + { + id: 'pr5', + title: 'Music Hack Day NYC — Spotify V. Rdio', + source: 'Music Machinery', + date: '2013-10-21', + url: 'https://musicmachinery.com/2013/10/21/music-hack-day-nyc/', + }, + { + id: 'pr6', + title: 'Bodywerk Memphis: DJ Superteam Making Waves', + source: 'We Are Memphis', + url: 'https://wearememphis.com/play/music/musician-profiles/bodywerk-memphis-dj-superteam/', + }, + { + id: 'pr7', + title: 'Ep. 23: Bodywerk', + source: 'The Shellcast: Only In Memphis', + date: '2022-03-10', + url: 'https://podcasts.apple.com/us/podcast/ep-23-bodywerk/id1558176971?i=1000553643095', + }, + { + id: 'pr8', + title: 'HabibiBeats Radio', + source: 'WYXR 91.7 FM', + url: 'https://wyxr.org/past-shows/', + }, +]; + export const works = [ { id: 0, diff --git a/client/src/pages/Work.jsx b/client/src/pages/Work.jsx index 1b40300..71c7cd8 100644 --- a/client/src/pages/Work.jsx +++ b/client/src/pages/Work.jsx @@ -1,6 +1,6 @@ import { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; -import { works } from '../data'; +import { works, projects, press } from '../data'; import { useStore } from '../store'; // Track mix/embed opens @@ -13,6 +13,42 @@ const trackMixOpen = (mixTitle) => { } }; +const trackOutboundClick = (url, label) => { + if (typeof window.gtag === 'function') { + window.gtag('event', 'outbound', { + event_category: 'engagement', + event_label: label, + transport_type: 'beacon', + }); + } +}; + +const sectionLabelStyle = { + fontSize: '0.65rem', + fontWeight: '600', + textTransform: 'uppercase', + letterSpacing: '0.1em', + opacity: 0.4, + color: '#1a1a1a', + padding: '20px 20px 4px', + margin: 0, +}; + +const linkItemStyle = { + width: '100%', + padding: '16px 20px', + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + background: 'transparent', + border: 'none', + color: '#1a1a1a', + cursor: 'pointer', + textAlign: 'left', + borderRadius: '8px', + textDecoration: 'none', +}; + export default function Work() { const [expandedId, setExpandedId] = useState(null); const { setEmbedOpen } = useStore(); @@ -61,15 +97,67 @@ export default function Work() { margin: '0 auto', }} > - {works.map((work, index) => ( - Projects

+ {projects.map((project, index) => ( + + trackOutboundClick(project.url, project.title)} + whileHover={{ backgroundColor: 'rgba(0,0,0,0.03)' }} + style={linkItemStyle} + > +
+

+ {project.title} +

+ + {project.subtitle} + +
+ + ↗ + +
+
+ ))} + + {/* Mixes Section */} +

Mixes

+ {works.map((work, index) => ( + @@ -77,7 +165,7 @@ export default function Work() { toggleItem(work.id, work.title)} whileHover={{ backgroundColor: 'rgba(0,0,0,0.03)' }} - style={{ + style={{ width: '100%', padding: '16px 20px', display: 'flex', @@ -86,34 +174,34 @@ export default function Work() { background: 'transparent', border: 'none', color: '#1a1a1a', - cursor: 'pointer', + cursor: 'pointer', textAlign: 'left', borderRadius: '8px', - }} - > + }} + >
-

- {work.title} + {work.title}

- - {work.date} + {work.date}
- + - {expandedId === work.id && ( - + >
-

{work.subtitle}

- + {work.youtubeId && (
)}
- - )} + + )} - - ))} + + ))} + + {/* Press Section */} +
+

Press

+ {press.map((item, index) => ( + + trackOutboundClick(item.url, item.title)} + whileHover={{ backgroundColor: 'rgba(0,0,0,0.03)' }} + style={linkItemStyle} + > +
+

+ {item.title} +

+ + {item.source}{item.date ? ` · ${item.date}` : ''} + +
+ + ↗ + +
+
+ ))} +
);