-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
143 lines (120 loc) · 5.21 KB
/
Copy pathscript.js
File metadata and controls
143 lines (120 loc) · 5.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Theme Toggle Logic
function toggleTheme() {
const isDark = document.documentElement.classList.toggle('dark');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
updateThemeIcon(isDark);
drawBackground(); // Update canvas colors if needed
}
function updateThemeIcon(isDark) {
const icon = document.getElementById('themeIcon');
if (icon) {
if (isDark) {
icon.classList.remove('fa-moon');
icon.classList.add('fa-sun');
} else {
icon.classList.remove('fa-sun');
icon.classList.add('fa-moon');
}
}
}
// Background Animation (Simplified version for contact page)
function drawBackground() {
const canvas = document.getElementById('bgCanvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
// Set proper size
const resize = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};
window.addEventListener('resize', resize);
resize();
// Basic particle animation
const particles = [];
const isDark = document.documentElement.classList.contains('dark');
const color = isDark ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.05)';
for (let i = 0; i < 50; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: Math.random() * 2 + 1,
speedY: Math.random() * 0.5 + 0.1
});
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = color;
particles.forEach(p => {
ctx.beginPath();
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
ctx.fill();
p.y -= p.speedY;
if (p.y < 0) {
p.y = canvas.height;
p.x = Math.random() * canvas.width;
}
});
requestAnimationFrame(animate);
}
animate();
}
// Initialize on load
document.addEventListener('DOMContentLoaded', () => {
const isDark = document.documentElement.classList.contains('dark');
updateThemeIcon(isDark);
drawBackground();
// Form Handling - Asynchronous Apps Script Web App "Silent" Logic
const contactForm = document.getElementById('contactForm');
if (contactForm) {
contactForm.addEventListener('submit', async (e) => {
e.preventDefault();
const btn = document.getElementById('submitBtn');
const btnText = document.getElementById('btnText');
const statusDiv = document.getElementById('formStatus');
// Disable button & show loading state
btn.disabled = true;
btnText.innerHTML = 'Sending...';
statusDiv.classList.add('hidden');
// Collect Data and handle JSON mapping as Apps Script handles it robustly
const formData = new FormData(contactForm);
// The Apps Script JSON Endpoint
const SCRIPT_URL = "https://script.google.com/macros/s/AKfycbzgccTbmSWWE0p49Hkc_Duy34z9u32W3kvDPOrMlN0m_2ypCrlfD_18Qpcxmu_FO5uW/exec";
try {
// Convert FormData to a standard JSON object mapping our name attributes
const dataPayload = Object.fromEntries(formData);
// The Silent Logic: Using mode 'no-cors' allows us to send a POST request
// bypassing CORS restrictions from a static site. We can't read the response,
// but we know it gets sent.
await fetch(SCRIPT_URL, {
method: 'POST',
mode: 'no-cors',
body: JSON.stringify(dataPayload)
});
// On success (or at least dispatch completion)
contactForm.reset();
showStatus(statusDiv, 'success', 'Your message has been sent successfully. We will get back to you soon!');
} catch (error) {
console.error("Error submitting form:", error);
// For no-cors, exceptions are rare unless there is a complete network interruption,
// making it effectively "Silent".
showStatus(statusDiv, 'error', 'An error occurred while sending your message. Please verify your connection.');
} finally {
// Reset button
btn.disabled = false;
btnText.textContent = 'Send Message';
}
});
}
});
function showStatus(element, type, message) {
element.textContent = '';
// Clear previous classes
element.className = 'mt-6 p-4 rounded-xl text-sm font-medium animate-fade-in block border';
if (type === 'success') {
element.classList.add('bg-emerald-500/10', 'text-emerald-700', 'dark:text-emerald-400', 'border-emerald-500/20');
element.innerHTML = '<i class="fa-solid fa-check-circle mr-2"></i> ' + message;
} else {
element.classList.add('bg-destructive/10', 'text-destructive', 'border-destructive/20');
element.innerHTML = '<i class="fa-solid fa-triangle-exclamation mr-2"></i> ' + message;
}
}