diff --git a/api.php b/api.php
index 17097fb..00dc218 100644
--- a/api.php
+++ b/api.php
@@ -909,6 +909,35 @@ switch ($action) {
}
ok(['loggedIn' => false]);
+ // ─── Yhteydenotto ──────────────────────────────────────────
+ case 'contact':
+ $name = trim($body['name'] ?? '');
+ $email = trim($body['email'] ?? '');
+ $message = trim($body['message'] ?? '');
+
+ if (!$name || !$email || !$message) err('Täytä kaikki kentät.');
+ if (!filter_var($email, FILTER_VALIDATE_EMAIL)) err('Sähköpostiosoite ei kelpaa.');
+ if (mb_strlen($message) > 5000) err('Viesti on liian pitkä.');
+
+ // Tallenna varmuuskopio
+ $messages = readData('messages.json', []);
+ $messages[] = [
+ 'name' => htmlspecialchars($name, ENT_QUOTES | ENT_HTML5, 'UTF-8'),
+ 'email' => htmlspecialchars($email, ENT_QUOTES | ENT_HTML5, 'UTF-8'),
+ 'message' => htmlspecialchars($message, ENT_QUOTES | ENT_HTML5, 'UTF-8'),
+ 'date' => date('Y-m-d H:i:s'),
+ ];
+ writeData('messages.json', $messages);
+
+ // Lähetä sähköposti
+ $to = 'info@tykkaa.fi';
+ $subject = "tykkää.fi: viesti käyttäjältä $name";
+ $body = "Nimi: $name\nSähköposti: $email\n\nViesti:\n$message";
+ $headers = "From: noreply@tykkaa.fi\r\nReply-To: $email\r\nContent-Type: text/plain; charset=UTF-8";
+ @mail($to, $subject, $body, $headers);
+
+ ok(['sent' => true]);
+
default:
err('Unknown action');
}
diff --git a/index.html b/index.html
index e11781e..b9ca21c 100644
--- a/index.html
+++ b/index.html
@@ -64,7 +64,12 @@
diff --git a/script.js b/script.js
index 7bfb315..9112317 100644
--- a/script.js
+++ b/script.js
@@ -15,7 +15,9 @@ const T = {
about_title: 'Mikä tykkää.fi?',
about_text: 'tykkää.fi on avoin yhteisö, jonne kuka tahansa voi tulla jakamaan asioita joista tykkää. Reseptejä, neulomisohjeita, käsityöideoita tai ihan mitä muuta kivaa — tärkeintä on jakamisen ilo. Lisää oma julkaisusi yläkulman napista!',
contact_title: 'Ota yhteyttä',
- contact_desc: 'Kysyttävää tai ehdotuksia? Lähetä meille sähköpostia!',
+ contact_desc: 'Kysyttävää tai ehdotuksia? Lähetä meille viestiä!',
+ name_ph: 'Nimesi', email_ph: 'Sähköpostisi', msg_ph: 'Viestisi...',
+ send_btn: 'Lähetä viesti', msg_sent: 'Viesti lähetetty! ✓', msg_error: 'Virhe lähetyksessä. Yritä uudelleen.',
footer: 'Avoin yhteisö kaikille',
modal_by: 'Kirjoittanut',
modal_ingredients: 'Ainekset', modal_steps: 'Ohjeet',
@@ -47,7 +49,9 @@ const T = {
about_title: 'What is tykkää.fi?',
about_text: 'tykkää.fi is an open community where anyone can share things they love. Recipes, knitting patterns, craft ideas or anything fun — the joy of sharing is what matters. Add your own post using the button in the top corner!',
contact_title: 'Get in Touch',
- contact_desc: 'Questions or suggestions? Send us an email!',
+ contact_desc: 'Questions or suggestions? Send us a message!',
+ name_ph: 'Your name', email_ph: 'Your email', msg_ph: 'Your message...',
+ send_btn: 'Send Message', msg_sent: 'Message Sent! ✓', msg_error: 'Error sending. Please try again.',
footer: 'Open community for everyone',
modal_by: 'By',
modal_ingredients: 'Ingredients', modal_steps: 'Instructions',
@@ -638,6 +642,29 @@ async function submitPublicPost() {
// ===========================
// CONTACT FORM
// ===========================
+// ===========================
+// CONTACT FORM
+// ===========================
+async function handleSubmit(e) {
+ e.preventDefault();
+ const btn = e.target.querySelector('button[type="submit"]');
+ const name = document.getElementById('contact-name').value.trim();
+ const email = document.getElementById('contact-email').value.trim();
+ const message = document.getElementById('contact-msg').value.trim();
+ btn.disabled = true;
+ try {
+ await apiPost('contact', { name, email, message });
+ btn.textContent = t('msg_sent');
+ btn.style.background = '#5c8a4a';
+ e.target.reset();
+ setTimeout(() => { btn.textContent = t('send_btn'); btn.style.background = ''; btn.disabled = false; }, 4000);
+ } catch {
+ btn.textContent = t('msg_error');
+ btn.style.background = '#c04040';
+ setTimeout(() => { btn.textContent = t('send_btn'); btn.style.background = ''; btn.disabled = false; }, 4000);
+ }
+}
+
// ===========================
// INIT
// ===========================
diff --git a/style.css b/style.css
index 9465b3f..fe15ce4 100644
--- a/style.css
+++ b/style.css
@@ -324,19 +324,31 @@ nav a:hover { color: #fff; }
.contact h2 { font-size: 1.9rem; color: var(--warm-brown); margin-bottom: 8px; }
.contact > .container > p { color: var(--text-light); margin-bottom: 28px; }
-.contact-email {
- font-size: 1.3rem;
- font-family: 'Georgia', serif;
- color: var(--accent);
- text-decoration: none;
- transition: color 0.2s;
+.contact-form {
+ display: flex;
+ flex-direction: column;
+ gap: 14px;
+ max-width: 520px;
+ margin: 0 auto;
}
-.contact-email:hover {
- color: #a0522d;
- text-decoration: underline;
+.contact-form input,
+.contact-form textarea {
+ padding: 12px 18px;
+ border: 2px solid var(--border);
+ border-radius: 10px;
+ font-size: 1rem;
+ font-family: 'Georgia', serif;
+ background: #fff;
+ color: var(--text);
+ outline: none;
+ transition: border-color 0.2s;
+ resize: vertical;
}
+.contact-form input:focus,
+.contact-form textarea:focus { border-color: var(--accent); }
+
/* =====================
FOOTER
===================== */