195 lines
7.2 KiB
TypeScript
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;
|