2026-02-21 19:04:54 +00:00

195 lines
7.2 KiB
TypeScript

"use client";
import { useEffect, useState, useCallback } from "react";
import axios from "axios";
import { ApiServerBaseUrl } from "@/utils/baseurl.utils";
import { getSocialAuthStatus } from "@/utils/commonFunction.utils";
import { useRouter } from "next/navigation";
const ONE_HOUR = 3600;
const AutomationPage = () => {
const router = useRouter();
const [limit, setLimit] = useState<number>(20);
const [loading, setLoading] = useState(false);
const [lastRun, setLastRun] = useState<string>("");
const [nextRunIn, setNextRunIn] = useState<number>(ONE_HOUR);
/* ------------------------------------------------------------
Validate payment + social login
------------------------------------------------------------ */
useEffect(() => {
async function validate() {
const userEmail = localStorage.getItem("user_email");
if (!userEmail) {
router.push("/social-media-connect");
return;
}
const storedUser = localStorage.getItem("userDetails");
if (!storedUser) {
router.push("/social-media-connect");
return;
}
const user = JSON.parse(storedUser);
const role = user?.role;
// ✅ CUSTOMER → pricing check FIRST
if (role === "customer") {
const session = localStorage.getItem("payment_session");
if (!session) {
router.push("/pricing");
return;
}
}
// ✅ ALL ROLES → social media connect check
const res = await getSocialAuthStatus(userEmail);
if (!res?.connected) {
router.push("/social-media-connect");
return;
}
}
validate();
}, [router]);
/* ------------------------------------------------------------
Auto Reply Function (wrapped in useCallback)
------------------------------------------------------------ */
const triggerAutoReply = useCallback(async () => {
if (!limit || limit <= 0) {
alert("Please enter a valid limit number");
return;
}
try {
setLoading(true);
await axios.post(
`${ApiServerBaseUrl}/social/automation/auto-reply?userId=${localStorage.getItem("user_email")}`,
{ limit }
);
const now = new Date().toLocaleString();
setLastRun(now);
const nextTime = Date.now() + ONE_HOUR * 1000;
localStorage.setItem("nextRunTimestamp", nextTime.toString());
setNextRunIn(ONE_HOUR);
} catch (error: any) {
alert(error.response?.data?.message || "Auto reply failed");
} finally {
setLoading(false);
}
}, [limit]);
/* ------------------------------------------------------------
Load saved next run or trigger if expired
------------------------------------------------------------ */
useEffect(() => {
const savedTime = localStorage.getItem("nextRunTimestamp");
if (savedTime) {
const diff = Math.floor((Number(savedTime) - Date.now()) / 1000);
if (diff > 0) {
setNextRunIn(diff);
} else {
triggerAutoReply();
}
} else {
const nextTime = Date.now() + ONE_HOUR * 1000;
localStorage.setItem("nextRunTimestamp", nextTime.toString());
}
}, [triggerAutoReply]);
/* ------------------------------------------------------------
Countdown timer
------------------------------------------------------------ */
useEffect(() => {
const timer = setInterval(() => {
setNextRunIn((prev) => {
if (prev <= 1) {
triggerAutoReply();
return ONE_HOUR;
}
return prev - 1;
});
}, 1000);
return () => clearInterval(timer);
}, [triggerAutoReply]);
const formatTime = (sec: number) => {
const m = Math.floor(sec / 60);
const s = sec % 60;
return `${m}m ${s < 10 ? "0" + s : s}s`;
};
return (
<div className="relative min-h-[88vh] flex items-center justify-center overflow-hidden bg-[#111111] px-4">
{/* Floating background bubbles */}
<div className="absolute bottom-[-100px] left-[10%] w-[70px] h-[70px] rounded-full bg-pink-500/40 blur-xl animate-floatUp"></div>
<div className="absolute bottom-[-120px] left-[30%] w-[90px] h-[90px] rounded-full bg-blue-500/40 blur-xl animate-floatUpSlow"></div>
<div className="absolute bottom-[-110px] left-[60%] w-[60px] h-[60px] rounded-full bg-green-500/40 blur-xl animate-floatUpFast"></div>
<div className="w-full max-w-md bg-white/10 shadow-2xl rounded-2xl p-8 border border-[#000]/20">
<h2 className="text-3xl font-bold bg-gradient-to-r from-blue-400 to-pink-400 bg-clip-text text-transparent text-center mb-6">
Instagram Auto Reply
</h2>
<div className="mb-5">
<label className="block text-left text-gray-300 font-medium mb-2">
Auto Reply Limit
</label>
<input
type="number"
className="w-full px-4 py-3 border rounded-xl
text-lg focus:ring-2 focus:ring-blue-500
focus:outline-none bg-[#111111] border-[#111111]/60 text-white"
value={limit}
onChange={(e) => setLimit(Number(e.target.value))}
/>
</div>
<button
onClick={triggerAutoReply}
disabled={loading}
title="Click to manually trigger the automation script to scan for new comments and reply."
className="w-full bg-gradient-to-r from-blue-600 to-pink-500
text-white py-3 rounded-xl font-semibold shadow-lg
transition-all hover:opacity-90"
>
{loading ? "Processing..." : "Start Auto Reply"}
</button>
<p className="mt-4 text-[10px] text-gray-500 text-center leading-tight">
* This tool uses the `instagram_manage_comments` permission to fetch your recent posts' comments and apply pre-configured automated responses.
</p>
{lastRun && (
<p className="text-center mt-4 text-gray-300">
Last executed: <b className="text-white">{lastRun}</b>
</p>
)}
<p className="text-center mt-4 text-blue-300 font-semibold text-lg">
Next auto-run in:{" "}
<span className="text-pink-400">{formatTime(nextRunIn)}</span>
</p>
<p className="text-center mt-6 text-xs text-gray-500">
Auto reply runs automatically every 1 hour.
</p>
</div>
</div>
);
};
export default AutomationPage;