mirror of
https://github.com/Luchexx/wacrm.git
synced 2026-11-02 17:29:45 +00:00
Merge pull request #35 from ArnasDon/fix/dashboard-deep-link-to-conversation
fix(dashboard): open the clicked conversation when deep-linking from dashboard
This commit is contained in:
commit
5943c59193
@ -261,7 +261,7 @@ export default function DashboardPage() {
|
|||||||
recentConversations.map((conv) => (
|
recentConversations.map((conv) => (
|
||||||
<button
|
<button
|
||||||
key={conv.id}
|
key={conv.id}
|
||||||
onClick={() => router.push("/inbox")}
|
onClick={() => router.push(`/inbox?c=${conv.id}`)}
|
||||||
className="flex w-full items-center gap-3 px-5 py-3 text-left transition-colors hover:bg-slate-800/50"
|
className="flex w-full items-center gap-3 px-5 py-3 text-left transition-colors hover:bg-slate-800/50"
|
||||||
>
|
>
|
||||||
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-emerald-500/10 text-sm font-medium text-emerald-500">
|
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-emerald-500/10 text-sm font-medium text-emerald-500">
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState, useCallback, useEffect } from "react";
|
import { useState, useCallback, useEffect, useRef } from "react";
|
||||||
|
import { useRouter, useSearchParams } from "next/navigation";
|
||||||
import { createClient } from "@/lib/supabase/client";
|
import { createClient } from "@/lib/supabase/client";
|
||||||
import type { Conversation, Message, Contact, ConversationStatus } from "@/types";
|
import type { Conversation, Message, Contact, ConversationStatus } from "@/types";
|
||||||
import { useRealtime } from "@/hooks/use-realtime";
|
import { useRealtime } from "@/hooks/use-realtime";
|
||||||
@ -11,6 +12,15 @@ import { toast } from "sonner";
|
|||||||
import { WifiOff } from "lucide-react";
|
import { WifiOff } from "lucide-react";
|
||||||
|
|
||||||
export default function InboxPage() {
|
export default function InboxPage() {
|
||||||
|
const router = useRouter();
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
/**
|
||||||
|
* `?c=<id>` deep-link support. Used when landing here from the
|
||||||
|
* dashboard's recent-conversations list so the right thread opens
|
||||||
|
* automatically instead of showing the empty center panel.
|
||||||
|
*/
|
||||||
|
const deepLinkConvId = searchParams.get("c");
|
||||||
|
|
||||||
const [conversations, setConversations] = useState<Conversation[]>([]);
|
const [conversations, setConversations] = useState<Conversation[]>([]);
|
||||||
const [activeConversation, setActiveConversation] =
|
const [activeConversation, setActiveConversation] =
|
||||||
useState<Conversation | null>(null);
|
useState<Conversation | null>(null);
|
||||||
@ -20,6 +30,12 @@ export default function InboxPage() {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Fire the deep-link auto-select exactly once per URL — subsequent
|
||||||
|
// list refreshes (realtime, manual refetch) must not snap the user
|
||||||
|
// back to the deep-linked conversation if they've already clicked
|
||||||
|
// elsewhere.
|
||||||
|
const autoSelectedForDeepLinkRef = useRef<string | null>(null);
|
||||||
|
|
||||||
// Check WhatsApp connection status on mount
|
// Check WhatsApp connection status on mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkConnection = async () => {
|
const checkConnection = async () => {
|
||||||
@ -135,8 +151,26 @@ export default function InboxPage() {
|
|||||||
const handleConversationsLoaded = useCallback(
|
const handleConversationsLoaded = useCallback(
|
||||||
(loaded: Conversation[]) => {
|
(loaded: Conversation[]) => {
|
||||||
setConversations(loaded);
|
setConversations(loaded);
|
||||||
|
// Resolve a pending deep-link here rather than in an effect — this
|
||||||
|
// is an event handler, so the setState calls below are allowed by
|
||||||
|
// react-hooks/set-state-in-effect. Runs once per ?c=<id> URL value
|
||||||
|
// via the ref, so realtime refreshes of the list can't snap the
|
||||||
|
// user back to the deep-linked thread after they've navigated.
|
||||||
|
if (
|
||||||
|
deepLinkConvId &&
|
||||||
|
autoSelectedForDeepLinkRef.current !== deepLinkConvId &&
|
||||||
|
loaded.length > 0
|
||||||
|
) {
|
||||||
|
autoSelectedForDeepLinkRef.current = deepLinkConvId;
|
||||||
|
const match = loaded.find((c) => c.id === deepLinkConvId);
|
||||||
|
if (match) {
|
||||||
|
setActiveConversation(match);
|
||||||
|
setActiveContact(match.contact ?? null);
|
||||||
|
setMessages([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[]
|
[deepLinkConvId]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSelectConversation = useCallback(
|
const handleSelectConversation = useCallback(
|
||||||
@ -149,10 +183,15 @@ export default function InboxPage() {
|
|||||||
setActiveConversation(conv);
|
setActiveConversation(conv);
|
||||||
setActiveContact(conv.contact ?? null);
|
setActiveContact(conv.contact ?? null);
|
||||||
setMessages([]);
|
setMessages([]);
|
||||||
|
// Reflect the selection in the URL so a refresh lands the user
|
||||||
|
// back in the same thread, and so copy-paste links work. Use
|
||||||
|
// replace() to avoid polluting browser history with every click.
|
||||||
|
router.replace(`/inbox?c=${conv.id}`, { scroll: false });
|
||||||
},
|
},
|
||||||
[activeConversation?.id]
|
[activeConversation?.id, router]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const handleMessagesLoaded = useCallback((loaded: Message[]) => {
|
const handleMessagesLoaded = useCallback((loaded: Message[]) => {
|
||||||
setMessages(loaded);
|
setMessages(loaded);
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user