Skip to content

Commit 0b95d9e

Browse files
committed
Add unique URL sharing and beautiful footer with social media links
1 parent c15c03a commit 0b95d9e

3 files changed

Lines changed: 258 additions & 14 deletions

File tree

index.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,5 +138,24 @@ <h3>A Message for You</h3>
138138
</div>
139139

140140
<script src="script.js"></script>
141+
142+
<!-- Footer -->
143+
<footer class="footer">
144+
<div class="footer-content">
145+
<div class="footer-credits">
146+
<p>Created with ❤️ by <strong>Sunmughan Swamy</strong></p>
147+
</div>
148+
<div class="footer-social">
149+
<a href="https://www.instagram.com/sunmughan" target="_blank" rel="noopener noreferrer" class="social-btn instagram-btn">
150+
<i class="fab fa-instagram"></i>
151+
<span>Follow on Instagram</span>
152+
</a>
153+
<a href="https://www.linkedin.com/in/sunmughan" target="_blank" rel="noopener noreferrer" class="social-btn linkedin-btn">
154+
<i class="fab fa-linkedin-in"></i>
155+
<span>Follow on LinkedIn</span>
156+
</a>
157+
</div>
158+
</div>
159+
</footer>
141160
</body>
142161
</html>

script.js

Lines changed: 128 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,110 @@ class FriendshipGreetingApp {
55
this.currentAnimation = null;
66
this.uploadedFiles = [];
77
this.effectInterval = null;
8+
this.currentGreetingId = null;
9+
this.quotes = [
10+
"Friendship is born at that moment when one person says to another, 'What! You too?'",
11+
"A real friend is one who walks in when the rest of the world walks out.",
12+
"Friends are the family you choose."
13+
];
814

915
this.init();
1016
}
1117

1218
init() {
1319
this.bindEvents();
1420
this.startDefaultEffect();
21+
this.checkForSharedGreeting();
22+
}
23+
24+
generateGreetingId() {
25+
return 'greeting_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
26+
}
27+
28+
saveGreeting(greetingData) {
29+
const greetingId = this.generateGreetingId();
30+
const greetings = JSON.parse(localStorage.getItem('friendshipGreetings') || '{}');
31+
greetings[greetingId] = {
32+
...greetingData,
33+
createdAt: new Date().toISOString()
34+
};
35+
localStorage.setItem('friendshipGreetings', JSON.stringify(greetings));
36+
return greetingId;
37+
}
38+
39+
loadGreeting(greetingId) {
40+
const greetings = JSON.parse(localStorage.getItem('friendshipGreetings') || '{}');
41+
return greetings[greetingId] || null;
42+
}
43+
44+
checkForSharedGreeting() {
45+
const urlParams = new URLSearchParams(window.location.search);
46+
const greetingId = urlParams.get('greeting');
47+
48+
if (greetingId) {
49+
const greetingData = this.loadGreeting(greetingId);
50+
if (greetingData) {
51+
this.loadGreetingFromData(greetingData);
52+
this.currentGreetingId = greetingId;
53+
// Hide the form and show only the greeting
54+
document.querySelector('.form-container').style.display = 'none';
55+
document.querySelector('.greeting-preview').style.width = '100%';
56+
document.querySelector('.greeting-preview').style.maxWidth = '600px';
57+
document.querySelector('.greeting-preview').style.margin = '0 auto';
58+
59+
// Add a "Create Your Own" button
60+
this.addCreateOwnButton();
61+
}
62+
}
63+
}
64+
65+
loadGreetingFromData(data) {
66+
// Update form fields
67+
document.getElementById('friendName').value = data.friendName || '';
68+
document.getElementById('memories').value = data.memories || '';
69+
document.getElementById('message').value = data.message || '';
70+
71+
// Set effects and styles
72+
this.currentEffect = data.effect || 'hearts';
73+
this.currentStyle = data.style || 'classic';
74+
this.currentAnimation = data.animation || 'bounce';
75+
76+
// Update the greeting display
77+
this.updateFriendName(data.friendName || '');
78+
this.updateMemories(data.memories || '');
79+
this.updateMessage(data.message || '');
80+
this.setEffect(this.currentEffect);
81+
this.setStyle(this.currentStyle);
82+
this.setAnimation(this.currentAnimation);
83+
84+
// Handle uploaded files if any
85+
if (data.uploadedFiles && data.uploadedFiles.length > 0) {
86+
// Note: We can't restore actual files, but we can show placeholders
87+
this.showNotification('Note: Shared greetings show text content only. Original images are not included for privacy.', 'info');
88+
}
89+
}
90+
91+
addCreateOwnButton() {
92+
// Check if button already exists
93+
if (document.getElementById('createOwnBtn')) return;
94+
95+
const actionButtons = document.querySelector('.action-buttons');
96+
const createOwnBtn = document.createElement('button');
97+
createOwnBtn.id = 'createOwnBtn';
98+
createOwnBtn.className = 'action-btn';
99+
createOwnBtn.innerHTML = '<i class="fas fa-plus"></i> Create Your Own';
100+
createOwnBtn.style.background = '#667eea';
101+
createOwnBtn.style.color = 'white';
102+
createOwnBtn.style.border = '2px solid #667eea';
103+
104+
createOwnBtn.addEventListener('click', () => {
105+
// Remove the greeting parameter from URL and reload
106+
const url = new URL(window.location);
107+
url.searchParams.delete('greeting');
108+
window.location.href = url.toString();
109+
});
110+
111+
actionButtons.appendChild(createOwnBtn);
15112
}
16113

17114
bindEvents() {
@@ -290,18 +387,35 @@ class FriendshipGreetingApp {
290387
const message = document.getElementById('message').value;
291388

292389
if (!friendName.trim()) {
293-
this.showNotification('Please enter your friend\'s name!', 'warning');
390+
this.showNotification('Please enter your friend\'s name! 👤', 'error');
294391
return;
295392
}
296393

394+
// Save greeting data
395+
const greetingData = {
396+
friendName: friendName,
397+
memories: memories,
398+
message: message,
399+
effect: this.currentEffect,
400+
style: this.currentStyle,
401+
animation: this.currentAnimation,
402+
uploadedFiles: this.uploadedFiles.map(file => ({ name: file.name, type: file.type }))
403+
};
404+
405+
this.currentGreetingId = this.saveGreeting(greetingData);
406+
407+
this.updateFriendName(friendName);
408+
this.updateMemories(memories);
409+
this.updateMessage(message);
410+
297411
// Add a special creation animation
298412
const greetingCard = document.getElementById('greetingCard');
299413
greetingCard.style.transform = 'scale(0.95)';
300414
greetingCard.style.transition = 'transform 0.3s ease';
301415

302416
setTimeout(() => {
303417
greetingCard.style.transform = 'scale(1)';
304-
this.showNotification('Greeting card created successfully! 🎉', 'success');
418+
this.showNotification('Beautiful greeting created! 🎉 Ready to share!', 'success');
305419
}, 300);
306420

307421
// Add some extra sparkle effect
@@ -352,17 +466,25 @@ class FriendshipGreetingApp {
352466
}
353467

354468
shareGreeting() {
469+
if (!this.currentGreetingId) {
470+
this.showNotification('Please create a greeting first!', 'warning');
471+
return;
472+
}
473+
474+
const shareUrl = `${window.location.origin}${window.location.pathname}?greeting=${this.currentGreetingId}`;
475+
355476
if (navigator.share) {
356477
navigator.share({
357478
title: 'Friendship Day Greeting',
358479
text: 'Check out this beautiful friendship day greeting I created!',
359-
url: window.location.href
480+
url: shareUrl
360481
});
361482
} else {
362483
// Fallback for browsers that don't support Web Share API
363-
const url = window.location.href;
364-
navigator.clipboard.writeText(url).then(() => {
365-
this.showNotification('Link copied to clipboard! Share it with your friends! 📋', 'success');
484+
navigator.clipboard.writeText(shareUrl).then(() => {
485+
this.showNotification('Greeting link copied to clipboard! Share it with your friends! 📋', 'success');
486+
}).catch(() => {
487+
this.showNotification('Failed to copy link. Please try again.', 'error');
366488
});
367489
}
368490
}

styles.css

Lines changed: 111 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,19 @@ body {
113113
position: relative;
114114
border-radius: 8px;
115115
overflow: hidden;
116-
aspect-ratio: 1;
116+
aspect-ratio: auto;
117+
max-height: 120px;
118+
display: flex;
119+
align-items: center;
120+
justify-content: center;
117121
}
118122

119123
.preview-item img,
120124
.preview-item video {
121-
width: 100%;
122-
height: 100%;
123-
object-fit: cover;
125+
max-width: 100%;
126+
max-height: 100%;
127+
object-fit: contain;
128+
border-radius: 8px;
124129
}
125130

126131
.effects-section {
@@ -273,14 +278,19 @@ body {
273278
.media-item {
274279
border-radius: 10px;
275280
overflow: hidden;
276-
aspect-ratio: 1;
281+
aspect-ratio: auto;
282+
max-height: 300px;
283+
display: flex;
284+
align-items: center;
285+
justify-content: center;
277286
}
278287

279288
.media-item img,
280289
.media-item video {
281-
width: 100%;
282-
height: 100%;
283-
object-fit: cover;
290+
max-width: 100%;
291+
max-height: 100%;
292+
object-fit: contain;
293+
border-radius: 10px;
284294
}
285295

286296
.memories-section,
@@ -552,6 +562,84 @@ body {
552562
}
553563
}
554564

565+
/* Footer Styles */
566+
.footer {
567+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
568+
color: white;
569+
padding: 30px 0;
570+
margin-top: 50px;
571+
text-align: center;
572+
box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.1);
573+
}
574+
575+
.footer-content {
576+
max-width: 1200px;
577+
margin: 0 auto;
578+
padding: 0 20px;
579+
}
580+
581+
.footer-credits {
582+
margin-bottom: 20px;
583+
}
584+
585+
.footer-credits p {
586+
margin: 0;
587+
font-size: 16px;
588+
opacity: 0.9;
589+
}
590+
591+
.footer-credits strong {
592+
font-weight: 600;
593+
color: #fff;
594+
}
595+
596+
.footer-social {
597+
display: flex;
598+
justify-content: center;
599+
gap: 15px;
600+
flex-wrap: wrap;
601+
}
602+
603+
.social-btn {
604+
display: inline-flex;
605+
align-items: center;
606+
gap: 8px;
607+
padding: 10px 20px;
608+
border-radius: 25px;
609+
text-decoration: none;
610+
color: white;
611+
font-weight: 500;
612+
transition: all 0.3s ease;
613+
border: 2px solid rgba(255, 255, 255, 0.3);
614+
backdrop-filter: blur(10px);
615+
background: rgba(255, 255, 255, 0.1);
616+
}
617+
618+
.social-btn:hover {
619+
transform: translateY(-2px);
620+
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
621+
border-color: rgba(255, 255, 255, 0.5);
622+
background: rgba(255, 255, 255, 0.2);
623+
}
624+
625+
.instagram-btn:hover {
626+
background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%);
627+
border-color: transparent;
628+
}
629+
630+
.linkedin-btn:hover {
631+
background: #0077b5;
632+
border-color: transparent;
633+
}
634+
635+
.social-btn i {
636+
font-size: 18px;
637+
}
638+
639+
.social-btn span {
640+
font-size: 14px;
641+
}
642+
555643
/* Responsive Design */
556644
@media (max-width: 768px) {
557645
.main-content {
@@ -574,4 +662,19 @@ body {
574662
.effect-options {
575663
grid-template-columns: 1fr 1fr;
576664
}
665+
666+
.footer {
667+
padding: 20px 0;
668+
margin-top: 30px;
669+
}
670+
671+
.footer-social {
672+
flex-direction: column;
673+
align-items: center;
674+
}
675+
676+
.social-btn {
677+
width: 200px;
678+
justify-content: center;
679+
}
577680
}

0 commit comments

Comments
 (0)