Skip to content

Commit 763fa0c

Browse files
committed
better hero and menu CTA / move c4p away from the menu / polish UI/UX
1 parent f722f2f commit 763fa0c

6 files changed

Lines changed: 415 additions & 118 deletions

File tree

index.html

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@
2626
});
2727

2828
gtag('js', new Date());
29-
gtag('config', 'G-K4QDNZB9C7');
29+
30+
// Basic anonymous config - always runs
31+
gtag('config', 'G-K4QDNZB9C7', {
32+
'anonymize_ip': true,
33+
'allow_google_signals': false,
34+
'allow_ad_personalization_signals': false
35+
});
3036
</script>
3137

3238

@@ -89,8 +95,7 @@
8995
<a href="#" onclick="window.scrollTo({top: 0, behavior: 'smooth'}); return false;">Home</a>
9096
<a href="#agenda">Agenda</a>
9197
<a href="#speakers">Speakers</a>
92-
<a href="https://sessionize.com/sjcelebration-c4p/" target="_blank" rel="noopener">Call for Papers <span class="material-icons">open_in_new</span></a>
93-
<a href="https://soujava.dev/30y-celebration-week" target="_blank" rel="noopener" class="nav-register">Register</a>
98+
<a href="https://soujava.dev/live-celebrationweek" target="_blank" rel="noopener" class="nav-register">Join Now</a>
9499
</div>
95100
<button class="nav-toggle" aria-label="Toggle navigation">
96101
<span></span>
@@ -123,14 +128,10 @@ <h1>#CelebrationWeek for 30y of Java</h1>
123128
</div>
124129

125130
<div class="cta-buttons">
126-
<a href="https://soujava.dev/30y-celebration-week"
127-
class="btn btn-primary"
128-
target="_blank"
129-
rel="noopener">
130-
Register for Free
131-
</a>
132-
<a href="#agenda" class="btn btn-outline">View Agenda</a>
131+
<a id="primaryCtaButton" href="#" class="btn btn-primary" style="display: none;"></a>
132+
<a id="secondaryCtaButton" href="#" class="btn btn-outline" style="display: none;"></a>
133133
</div>
134+
<p class="live-cta-subtext">Access the live streams, agenda, and recordings. Open to all.</p>
134135
</div>
135136

136137
<!-- Speaker Carousel -->
@@ -207,7 +208,7 @@ <h2 class="section-title">Agenda</h2>
207208
<div class="container">
208209
<div class="section-content">
209210
<h2 class="section-title">Featured Speakers</h2>
210-
<p class="section-description">Meet our incredible lineup of Java Champions, experts, and community leaders from around the world.</p>
211+
<p class="section-description">Meet our incredible lineup of Java Champions, experts, and community leaders from around the world. Our program was curated from a public <a href="https://sessionize.com/sjcelebration-c4p/" target="_blank" rel="noopener" class="inline-link">Call for Papers <span class="material-icons inline-link-icon">open_in_new</span></a>, showcasing talent from the global Java community.</p>
211212
</div>
212213

213214
<div id="speakers-container" class="speakers-grid">
@@ -219,50 +220,39 @@ <h2 class="section-title">Featured Speakers</h2>
219220
</div>
220221
</section>
221222

222-
<!-- CTA Section -->
223-
<section class="section cta-section">
224-
<div class="container">
225-
<div class="section-content">
226-
<h2 class="section-title">Ready to join us?</h2>
227-
<p class="section-description">Don't miss this opportunity to connect with the Java community and celebrate 30 years of innovation.</p>
228-
<div class="cta-button-wrapper">
229-
<a href="https://soujava.dev/30y-celebration-week"
230-
class="btn btn-primary"
231-
target="_blank"
232-
rel="noopener">
233-
Register for Free
234-
</a>
235-
</div>
236-
</div>
237-
</div>
238-
</section>
223+
239224
</main>
240225

241226
<!-- Footer -->
242227
<footer class="footer">
243228
<div class="container">
244-
<div class="footer-sponsors">
245-
<div class="sponsors-section">
229+
<div class="footer-content">
230+
<!-- Organizer Tier -->
231+
<div class="footer-tier footer-organizer">
246232
<p class="sponsor-label">Brought to you by</p>
247-
<div class="sponsor-logos">
248-
<a href="https://soujava.org.br" target="_blank" rel="noopener">
249-
<img src="./logos/soujava.png" alt="SouJava" class="sponsor-logo">
250-
</a>
251-
</div>
233+
<a href="https://soujava.org.br" target="_blank" rel="noopener" class="logo-link">
234+
<img src="./logos/soujava.png" alt="SouJava" class="organizer-logo">
235+
</a>
252236
</div>
253237

254-
<div class="sponsors-section">
238+
<!-- Supporter Tier -->
239+
<div class="footer-tier footer-supporters">
255240
<p class="sponsor-label">Proudly supported by</p>
256-
<div class="sponsor-logos">
257-
<a href="https://aletyx.com" target="_blank" rel="noopener">
258-
<img src="./logos/aletyx.png" alt="Aletyx" class="sponsor-logo">
241+
<div class="supporter-logos">
242+
<a href="https://aletyx.com" target="_blank" rel="noopener" class="logo-link">
243+
<img src="./logos/aletyx.png" alt="Aletyx" class="supporter-logo">
244+
</a>
245+
<a href="https://jakarta.ee" target="_blank" rel="noopener" class="logo-link">
246+
<img src="./logos/jakartaee.png" alt="Jakarta EE" class="supporter-logo">
259247
</a>
260248
</div>
261249
</div>
262250
</div>
263251

264252
<div class="footer-bottom">
265-
<p>&copy; 2025 SouJava. All rights reserved.</p>
253+
<p>&copy; 2025 SouJava. All rights reserved. |
254+
<a href="#" onclick="CookieConsent.showPreferences(); return false;" style="color: var(--text-secondary); text-decoration: underline;">Cookie Settings</a>
255+
</p>
266256
</div>
267257
</div>
268258
</footer>

js/cookie-consent.js

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@ const CookieConsent = {
2727
banner.innerHTML = `
2828
<div class="consent-content">
2929
<div class="consent-text">
30-
<p><strong>We use cookies to improve your experience</strong></p>
31-
<p>We use analytics cookies to understand how you use our site.
30+
<p>We collect anonymous visitor statistics to improve our event. With your consent, we can also track which sessions and speakers interest you most.
3231
<a href="https://policies.google.com/technologies/cookies" target="_blank" rel="noopener">Learn more</a></p>
33-
<p class="consent-legal">By clicking "Accept", you consent to our use of analytics cookies.</p>
32+
<p class="consent-legal">Basic anonymous metrics are always collected. Enhanced tracking requires consent.</p>
3433
</div>
3534
<div class="consent-buttons">
3635
<button class="consent-button consent-reject" onclick="CookieConsent.reject()">Reject</button>
@@ -78,9 +77,6 @@ const CookieConsent = {
7877
line-height: 1.4;
7978
}
8079
81-
.consent-text p:first-child {
82-
display: none;
83-
}
8480
8581
.consent-text a {
8682
color: #5cb6fa;
@@ -91,7 +87,7 @@ const CookieConsent = {
9187
.consent-legal {
9288
font-size: 0.75rem;
9389
opacity: 0.8;
94-
display: none;
90+
margin-top: 0.25rem;
9591
}
9692
9793
.consent-buttons {
@@ -189,23 +185,35 @@ const CookieConsent = {
189185
},
190186

191187
enableAnalytics() {
192-
// Initialize analytics only after consent
193-
if (window.EventAnalytics && typeof window.EventAnalytics.init === 'function') {
194-
window.EventAnalytics.init();
188+
// Re-initialize enhanced tracking after consent
189+
if (window.EventAnalytics && typeof window.EventAnalytics.initEnhancedTracking === 'function') {
190+
window.EventAnalytics.initEnhancedTracking();
195191
}
196192

197-
// Fire page view if it hasn't been sent
193+
// Update consent mode to allow cookies
198194
if (typeof gtag !== 'undefined') {
199-
gtag('event', 'page_view', {
200-
page_location: window.location.href,
201-
page_title: document.title
195+
gtag('consent', 'update', {
196+
'analytics_storage': 'granted'
202197
});
203198
}
204199
},
205200

206201
// Check if user has consented (for use in other scripts)
207202
canTrack() {
208203
return this.hasConsent;
204+
},
205+
206+
// Allow users to change their consent
207+
resetConsent() {
208+
localStorage.removeItem(this.consentKey);
209+
this.hasConsent = false;
210+
location.reload();
211+
},
212+
213+
// Show preferences (can be called from anywhere)
214+
showPreferences() {
215+
localStorage.removeItem(this.consentKey);
216+
this.showBanner();
209217
}
210218
};
211219

js/event-analytics.js

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
/**
22
* Event Analytics for Java 30Y Celebration
3-
* Focused tracking for tech conference KPIs
3+
* Two-tier approach: Anonymous metrics + Enhanced tracking with consent
44
*/
55

66
const EventAnalytics = {
7+
// Track basic anonymous metrics (no consent needed)
8+
trackAnonymousEvent(eventName, parameters = {}) {
9+
if (typeof gtag === 'undefined') return;
10+
11+
// Only send non-personal, anonymous events
12+
const anonymousParams = {
13+
...parameters,
14+
'anonymize_ip': true,
15+
'allow_google_signals': false,
16+
'allow_ad_personalization_signals': false
17+
};
18+
19+
gtag('event', eventName, anonymousParams);
20+
},
721
// Track which sessions people are actually interested in
822
trackSessionInterest(session) {
923
if (typeof gtag === 'undefined' || !CookieConsent.canTrack()) return;
@@ -162,11 +176,37 @@ const EventAnalytics = {
162176

163177
// Initialize all tracking
164178
init() {
165-
// Only initialize if we have consent
166-
if (!CookieConsent.canTrack()) {
167-
return;
179+
// ALWAYS track basic anonymous metrics
180+
this.initBasicTracking();
181+
182+
// Only initialize enhanced tracking if we have consent
183+
if (CookieConsent.canTrack()) {
184+
this.initEnhancedTracking();
168185
}
186+
},
187+
188+
// Basic anonymous tracking - always runs
189+
initBasicTracking() {
190+
// Track basic page navigation
191+
this.trackAnonymousEvent('page_view', {
192+
page_location: window.location.pathname,
193+
page_title: document.title
194+
});
169195

196+
// Track registration clicks anonymously
197+
document.querySelectorAll('a[href*="soujava.dev/30y-celebration-week"]').forEach(link => {
198+
link.addEventListener('click', () => {
199+
this.trackAnonymousEvent('registration_intent', {
200+
click_location: link.closest('header') ? 'header' :
201+
link.closest('nav') ? 'nav' :
202+
link.closest('.cta-section') ? 'cta' : 'other'
203+
});
204+
});
205+
});
206+
},
207+
208+
// Enhanced tracking - only with consent
209+
initEnhancedTracking() {
170210
// Scroll tracking
171211
this.initScrollTracking();
172212

@@ -183,8 +223,11 @@ const EventAnalytics = {
183223
}
184224
};
185225

186-
// Don't auto-initialize - wait for consent
187-
// The cookie consent script will call this when appropriate
226+
// Initialize immediately for basic tracking
227+
// Enhanced features will activate if/when consent is given
228+
document.addEventListener('DOMContentLoaded', () => {
229+
EventAnalytics.init();
230+
});
188231

189232
// Export for use in main.js
190233
window.EventAnalytics = EventAnalytics;

logos/jakartaee.png

21.6 KB
Loading

main.js

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,25 @@
44
* FIXES: Proper session scheduling, timezone handling, and data validation
55
*/
66

7+
// =======================================================
8+
// DAILY HERO BUTTON CONFIGURATION - FINAL VERSION
9+
// =======================================================
10+
const HERO_CTA_CONFIG = {
11+
// Primary button links to the LIVE or UPCOMING stream
12+
primary: {
13+
text: "Join the Live Stream",
14+
link: "https://soujava.dev/celebration-day-2" // This link is still updated daily
15+
},
16+
// Secondary button links to the MOST RECENT recording
17+
secondary: {
18+
text: "Latest Recordings",
19+
link: "https://soujava.dev/celebration-day-1" // This link is also updated daily
20+
},
21+
// Set to false if you only want to show one button
22+
showSecondaryButton: true
23+
};
24+
// =======================================================
25+
726
// Application State
827
const AppState = {
928
eventData: null,
@@ -818,9 +837,18 @@ class ScheduleRenderer {
818837

819838
AppState.eventData.schedule.forEach((day, dayIndex) => {
820839
const dayAnchor = Utils.createDayAnchor(day.date);
840+
// Calculate the day number (June 16 = day 1)
841+
const dayNumber = new Date(day.date + 'T00:00:00').getDate() - 15;
842+
const streamLink = `https://soujava.dev/celebration-day-${dayNumber}`;
843+
821844
scheduleHTML += `
822845
<div class="day-group" data-day="${day.date}" id="${dayAnchor}">
823-
<h3 class="day-header">${Utils.formatDateHeader(day.date)}</h3>
846+
<div class="day-header-container">
847+
<h3 class="day-header">${Utils.formatDateHeader(day.date)}</h3>
848+
<a href="${streamLink}" target="_blank" rel="noopener" class="day-stream-link">
849+
Watch Day ${dayNumber} Stream <span class="material-icons">open_in_new</span>
850+
</a>
851+
</div>
824852
`;
825853

826854
day.sessions.forEach(session => {
@@ -1100,12 +1128,8 @@ class ScheduleRenderer {
11001128
Analytics.trackSessionDetailsView('Session Not Found', []);
11011129
}
11021130
} else {
1103-
// When collapsing, remove the hash entirely (don't assume where user came from)
1131+
// When collapsing, remove the hash from the URL without causing a page jump.
11041132
if (window.history && window.history.replaceState) {
1105-
// First clear the hash to remove :target styling
1106-
window.location.hash = '';
1107-
1108-
// Then clean up the URL
11091133
const baseUrl = window.location.pathname + window.location.search;
11101134
window.history.replaceState(null, '', baseUrl);
11111135
}
@@ -1907,6 +1931,32 @@ window.addEventListener('unhandledrejection', function(e) {
19071931
}
19081932
});
19091933

1934+
// Apply Hero CTA Configuration
1935+
function applyHeroCtaConfig() {
1936+
const primaryBtn = document.getElementById('primaryCtaButton');
1937+
const secondaryBtn = document.getElementById('secondaryCtaButton');
1938+
1939+
// Configure Primary Button
1940+
if (primaryBtn && HERO_CTA_CONFIG.primary && HERO_CTA_CONFIG.primary.text) {
1941+
primaryBtn.textContent = HERO_CTA_CONFIG.primary.text;
1942+
primaryBtn.href = HERO_CTA_CONFIG.primary.link;
1943+
primaryBtn.target = "_blank";
1944+
primaryBtn.rel = "noopener";
1945+
primaryBtn.style.display = 'inline-flex';
1946+
}
1947+
1948+
// Configure Secondary Button
1949+
if (secondaryBtn && HERO_CTA_CONFIG.showSecondaryButton && HERO_CTA_CONFIG.secondary && HERO_CTA_CONFIG.secondary.text) {
1950+
secondaryBtn.textContent = HERO_CTA_CONFIG.secondary.text;
1951+
secondaryBtn.href = HERO_CTA_CONFIG.secondary.link;
1952+
secondaryBtn.target = "_blank";
1953+
secondaryBtn.rel = "noopener";
1954+
secondaryBtn.style.display = 'inline-flex';
1955+
} else if (secondaryBtn) {
1956+
secondaryBtn.style.display = 'none'; // Ensure it's hidden if not configured
1957+
}
1958+
}
1959+
19101960
// Initialize Application
19111961
let app;
19121962
let modalHandler;
@@ -1915,6 +1965,9 @@ function initApp() {
19151965
app = new App();
19161966
modalHandler = app.modalHandler; // Make modal handler globally available
19171967
app.init();
1968+
1969+
// Apply hero CTA configuration
1970+
applyHeroCtaConfig();
19181971
}
19191972

19201973
// Start the application when DOM is ready

0 commit comments

Comments
 (0)