Implement fetch-on-demand QR logic for WhatsApp
This commit is contained in:
@@ -11,6 +11,7 @@ export default function SettingsPage() {
|
|||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
|
const [fetchingQr, setFetchingQr] = useState(false);
|
||||||
const dict = useDictionary();
|
const dict = useDictionary();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -28,13 +29,9 @@ export default function SettingsPage() {
|
|||||||
try {
|
try {
|
||||||
const res = await fetch("/api/users/profile");
|
const res = await fetch("/api/users/profile");
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data.error) {
|
if (data.error) setError(data.error);
|
||||||
setError(data.error);
|
else if (!data) setError("Kullanıcı profili bulunamadı.");
|
||||||
} else if (!data) {
|
else setProfile(data);
|
||||||
setError("Kullanıcı profili bulunamadı.");
|
|
||||||
} else {
|
|
||||||
setProfile(data);
|
|
||||||
}
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
setError(e.message);
|
setError(e.message);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -52,6 +49,19 @@ export default function SettingsPage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleConnectWa = async () => {
|
||||||
|
setFetchingQr(true);
|
||||||
|
try {
|
||||||
|
const res = await fetch("/api/whatsapp/qr");
|
||||||
|
const data = await res.json();
|
||||||
|
setWaStatus(data);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
} finally {
|
||||||
|
setFetchingQr(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleSave = async (e: React.FormEvent) => {
|
const handleSave = async (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setSaving(true);
|
setSaving(true);
|
||||||
@@ -61,9 +71,8 @@ export default function SettingsPage() {
|
|||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify(profile)
|
body: JSON.stringify(profile)
|
||||||
});
|
});
|
||||||
if (res.ok) {
|
if (res.ok) alert("Ayarlar kaydedildi!");
|
||||||
alert("Ayarlar kaydedildi!");
|
else {
|
||||||
} else {
|
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
alert("Hata: " + data.error);
|
alert("Hata: " + data.error);
|
||||||
}
|
}
|
||||||
@@ -110,9 +119,6 @@ export default function SettingsPage() {
|
|||||||
onChange={e => setProfile({...profile, telegramId: e.target.value})}
|
onChange={e => setProfile({...profile, telegramId: e.target.value})}
|
||||||
placeholder="Örn: 5009005027"
|
placeholder="Örn: 5009005027"
|
||||||
/>
|
/>
|
||||||
<p style={{ fontSize: 12, color: "var(--text-secondary)", marginTop: 6 }}>
|
|
||||||
Botu başlatın ve ID'nizi buraya yazın.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -146,7 +152,7 @@ export default function SettingsPage() {
|
|||||||
{waStatus?.status === 'connected' ? (
|
{waStatus?.status === 'connected' ? (
|
||||||
<div style={{ color: "#10b981", fontWeight: 600, display: "flex", alignItems: "center", gap: 8 }}>
|
<div style={{ color: "#10b981", fontWeight: 600, display: "flex", alignItems: "center", gap: 8 }}>
|
||||||
<div style={{ width: 8, height: 8, borderRadius: "50%", background: "#10b981" }} />
|
<div style={{ width: 8, height: 8, borderRadius: "50%", background: "#10b981" }} />
|
||||||
Bağlı
|
Bağlı ✅
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
@@ -154,11 +160,20 @@ export default function SettingsPage() {
|
|||||||
<div style={{ width: 8, height: 8, borderRadius: "50%", background: "#ef4444" }} />
|
<div style={{ width: 8, height: 8, borderRadius: "50%", background: "#ef4444" }} />
|
||||||
Bağlı Değil
|
Bağlı Değil
|
||||||
</div>
|
</div>
|
||||||
{waStatus?.qr && (
|
{waStatus?.qr ? (
|
||||||
<div style={{ background: "#fff", padding: 10, borderRadius: 8, width: "fit-content" }}>
|
<div style={{ background: "#fff", padding: 10, borderRadius: 8, width: "fit-content" }}>
|
||||||
<img src={waStatus.qr} alt="QR Code" style={{ width: 150, height: 150 }} />
|
<img src={waStatus.qr} alt="QR Code" style={{ width: 150, height: 150 }} />
|
||||||
<p style={{ fontSize: 11, color: "#000", textAlign: "center", marginTop: 5 }}>WhatsApp'tan okutun</p>
|
<p style={{ fontSize: 11, color: "#000", textAlign: "center", marginTop: 5 }}>WhatsApp'tan okutun</p>
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-secondary btn-sm"
|
||||||
|
onClick={handleConnectWa}
|
||||||
|
disabled={fetchingQr}
|
||||||
|
>
|
||||||
|
{fetchingQr ? "QR Oluşturuluyor..." : "Bağlantı Kur (QR)"}
|
||||||
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
19
app/api/whatsapp/qr/route.ts
Normal file
19
app/api/whatsapp/qr/route.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { auth } from "@/auth";
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
const session = await auth();
|
||||||
|
if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||||
|
|
||||||
|
const userId = session.user.id;
|
||||||
|
const workerUrl = process.env.WHATSAPP_WORKER_URL;
|
||||||
|
const secret = process.env.WHATSAPP_SECRET;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${workerUrl}/get-qr?userId=${userId}&secret=${secret}`);
|
||||||
|
const data = await res.json();
|
||||||
|
return NextResponse.json(data);
|
||||||
|
} catch (error: any) {
|
||||||
|
return NextResponse.json({ status: 'error', error: error.message });
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user