source: frontend/src/components/contact-bubble.tsx

Last change on this file was b8093a0, checked in by imbrsk <boris696boris@…>, 3 days ago

Merge iknow-remaster into frontend/

Bring the Next.js frontend into this repository as a monorepo subdirectory,
preserving its full commit history via a subtree merge.

  • Property mode set to 100644
File size: 7.4 KB
Line 
1"use client"
2
3import { useState } from 'react';
4import { useTranslation } from 'react-i18next';
5import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6import { faEnvelope, faTimes, faPaperPlane, faSpinner } from '@fortawesome/free-solid-svg-icons';
7
8export default function ContactBubble() {
9 const { t } = useTranslation();
10 const [isOpen, setIsOpen] = useState(false);
11 const [isSending, setIsSending] = useState(false);
12 const [sent, setSent] = useState(false);
13 const [form, setForm] = useState({ name: '', email: '', subject: '', message: '' });
14
15 const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
16 setForm((prev) => ({ ...prev, [e.target.name]: e.target.value }));
17 };
18
19 const handleSubmit = async (e: React.FormEvent) => {
20 e.preventDefault();
21 setIsSending(true);
22 // Simulate sending
23 await new Promise((r) => setTimeout(r, 1200));
24 setIsSending(false);
25 setSent(true);
26 setTimeout(() => {
27 setSent(false);
28 setIsOpen(false);
29 setForm({ name: '', email: '', subject: '', message: '' });
30 }, 2500);
31 };
32
33 return (
34 <>
35 {/* Floating bubble */}
36 <button
37 onClick={() => setIsOpen(true)}
38 className={`fixed bottom-6 right-6 z-50 flex items-center gap-2 bg-primary hover:bg-blue-700 text-white px-5 py-3 rounded-full shadow-lg transition-all duration-300 hover:scale-105 hover:shadow-xl ${isOpen ? 'scale-0 opacity-0' : 'scale-100 opacity-100'}`}
39 aria-label={t('contact_us', 'Контактирај нè')}
40 >
41 <FontAwesomeIcon icon={faEnvelope} className="w-5 h-5" />
42 <span className="font-medium text-sm">{t('contact_us', 'Контактирај нè')}</span>
43 </button>
44
45 {/* Backdrop */}
46 {isOpen && (
47 <div
48 className="fixed inset-0 z-50 bg-black/40 backdrop-blur-sm transition-opacity duration-300"
49 onClick={() => setIsOpen(false)}
50 />
51 )}
52
53 {/* Modal */}
54 <div
55 className={`fixed z-50 bottom-6 right-6 w-[380px] max-w-[calc(100vw-2rem)] bg-card border border-border rounded-2xl shadow-2xl transition-all duration-300 origin-bottom-right ${isOpen ? 'scale-100 opacity-100' : 'scale-0 opacity-0 pointer-events-none'}`}
56 >
57 {/* Modal header */}
58 <div className="bg-primary text-white rounded-t-2xl px-6 py-4 flex items-center justify-between">
59 <div className="flex items-center gap-3">
60 <FontAwesomeIcon icon={faEnvelope} className="w-5 h-5" />
61 <h2 className="text-lg font-bold">{t('contact_us', 'Контактирај нè')}</h2>
62 </div>
63 <button
64 onClick={() => setIsOpen(false)}
65 className="text-white/80 hover:text-white transition-colors p-1"
66 aria-label={t('close', 'Затвори')}
67 >
68 <FontAwesomeIcon icon={faTimes} className="w-5 h-5" />
69 </button>
70 </div>
71
72 {/* Modal body */}
73 <div className="p-6">
74 {sent ? (
75 <div className="text-center py-8">
76 <div className="w-16 h-16 bg-green-100 text-green-600 rounded-full flex items-center justify-center mx-auto mb-4">
77 <FontAwesomeIcon icon={faPaperPlane} className="w-7 h-7" />
78 </div>
79 <h3 className="text-lg font-bold text-card-foreground mb-1">
80 {t('contact_sent_title', 'Пораката е испратена!')}
81 </h3>
82 <p className="text-sm text-muted-foreground">
83 {t('contact_sent_desc', 'Ќе ви одговориме наскоро.')}
84 </p>
85 </div>
86 ) : (
87 <form onSubmit={handleSubmit} className="space-y-4">
88 {/* Name */}
89 <div>
90 <label className="block text-sm font-medium text-muted-foreground mb-1">
91 {t('contact_name', 'Име и презиме')}
92 </label>
93 <input
94 type="text"
95 name="name"
96 required
97 value={form.name}
98 onChange={handleChange}
99 placeholder={t('contact_name_placeholder', 'Вашето име')}
100 className="w-full border border-border rounded-lg px-3 py-2 text-sm bg-card text-card-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary"
101 />
102 </div>
103
104 {/* Email */}
105 <div>
106 <label className="block text-sm font-medium text-muted-foreground mb-1">
107 {t('contact_email', 'Е-пошта')}
108 </label>
109 <input
110 type="email"
111 name="email"
112 required
113 value={form.email}
114 onChange={handleChange}
115 placeholder={t('contact_email_placeholder', 'example@email.com')}
116 className="w-full border border-border rounded-lg px-3 py-2 text-sm bg-card text-card-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary"
117 />
118 </div>
119
120 {/* Subject */}
121 <div>
122 <label className="block text-sm font-medium text-muted-foreground mb-1">
123 {t('contact_subject', 'Наслов')}
124 </label>
125 <input
126 type="text"
127 name="subject"
128 required
129 value={form.subject}
130 onChange={handleChange}
131 placeholder={t('contact_subject_placeholder', 'Тема на пораката')}
132 className="w-full border border-border rounded-lg px-3 py-2 text-sm bg-card text-card-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary"
133 />
134 </div>
135
136 {/* Message */}
137 <div>
138 <label className="block text-sm font-medium text-muted-foreground mb-1">
139 {t('contact_message', 'Порака')}
140 </label>
141 <textarea
142 name="message"
143 required
144 rows={3}
145 value={form.message}
146 onChange={handleChange}
147 placeholder={t('contact_message_placeholder', 'Напишете ја вашата порака...')}
148 className="w-full border border-border rounded-lg px-3 py-2 text-sm bg-card text-card-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary resize-none"
149 />
150 </div>
151
152 {/* Submit */}
153 <button
154 type="submit"
155 disabled={isSending}
156 className="w-full bg-primary hover:bg-blue-700 text-white font-medium py-2.5 rounded-lg transition-colors duration-200 flex items-center justify-center gap-2 disabled:opacity-60 disabled:cursor-not-allowed"
157 >
158 {isSending ? (
159 <>
160 <FontAwesomeIcon icon={faSpinner} className="w-4 h-4 animate-spin" />
161 {t('contact_sending', 'Испраќа...')}
162 </>
163 ) : (
164 <>
165 <FontAwesomeIcon icon={faPaperPlane} className="w-4 h-4" />
166 {t('contact_send', 'Испрати')}
167 </>
168 )}
169 </button>
170 </form>
171 )}
172 </div>
173 </div>
174 </>
175 );
176}
Note: See TracBrowser for help on using the repository browser.