import React, { useState, useCallback, useEffect } from "react";
import {
SocketProvider,
useChannel,
useAuth,
useConnection,
Channel,
} from "../index";
import { Message } from "../../types/protocol/messages";
// =============================================================================
// Example 1: Basic Socket Provider Usage
// =============================================================================
function BasicExample() {
return (
🔌 QPub Socket Integration
);
}
function ConnectionStatus() {
const {
status,
connectionId,
connectionDetails,
connect,
isConnected,
disconnect,
reset,
} = useConnection();
const getStatusColor = (status: string) => {
switch (status) {
case "connected":
return "green";
case "connecting":
return "orange";
case "failed":
return "red";
default:
return "gray";
}
};
return (
🔗 Connection
Status: {status}
{connectionId && (
Connection ID: {connectionId}
{connectionDetails && (
<>
Alias: {connectionDetails.alias}
Client ID: {connectionDetails.client_id}
Server ID: {connectionDetails.server_id}
>
)}
)}
);
}
function AuthSection() {
const {
isAuthenticated,
isAuthenticating,
token,
error,
authenticate,
clearToken,
} = useAuth();
return (
🔐 Authentication
{isAuthenticated ? (
<>
✅ Authenticated
Token: {token?.substring(0, 20)}...
>
) : (
<>
❌ Not authenticated
>
)}
{error && (
Error: {error.message}
)}
);
}
function ChatRoom() {
const [messageText, setMessageText] = useState("");
const [messages, setMessages] = useState([]);
const { status, error, publish, subscribe, unsubscribe, isSubscribed } =
useChannel("chat-room");
// Handle incoming messages
const handleMessage = useCallback((message: Message) => {
console.log("Message received:", message);
setMessages((prev) => [...prev, message]);
}, []);
// Subscribe when channel is ready
useEffect(() => {
if (status === "initialized") {
subscribe(handleMessage);
}
}, [status, subscribe, handleMessage]);
const sendMessage = async () => {
if (!messageText.trim()) return;
try {
await publish({
text: messageText,
timestamp: Date.now(),
user: "demo-user",
});
setMessageText("");
} catch (err) {
console.error("Failed to send:", err);
}
};
return (
💬 Chat Room
Channel status: {status}
Subscribed: {isSubscribed() ? "✅" : "❌"}
{messages.map((msg, idx) => (
{msg.data?.user}: {msg.data?.text}
{" "}
(
{msg.timestamp
? new Date(msg.timestamp).toLocaleTimeString()
: "No timestamp"}
)
))}
setMessageText(e.target.value)}
onKeyPress={(e) => e.key === "Enter" && sendMessage()}
placeholder="Type message..."
style={{ flex: 1 }}
/>
{error && (
Error: {error.message}
)}
);
}
// =============================================================================
// Example 2: Channel Component Pattern
// =============================================================================
function ChannelComponentExample() {
return (
📺 Channel Component Pattern
{({ status, publish, isSubscribed, error }) => (
🔔 Notifications
Status: {status}
Subscribed: {isSubscribed() ? "✅" : "❌"}
{error && (
Error: {error.message}
)}
)}
{({ status, subscribe, unsubscribe, isSubscribed }) => (
⚙️ System Events
Status: {status}
)}
);
}
// =============================================================================
// Example 3: Multiple Channels
// =============================================================================
function MultiChannelExample() {
const notifications = useChannel("notifications");
const chat = useChannel("chat");
const events = useChannel("system-events");
useEffect(() => {
// Subscribe to different channels with different handlers
if (notifications.status === "initialized") {
notifications.subscribe((msg: Message) => {
console.log("Notification:", msg);
// Show toast notification
});
}
if (chat.status === "initialized") {
chat.subscribe((msg: Message) => {
console.log("Chat message:", msg);
// Add to chat messages
});
}
if (events.status === "initialized") {
events.subscribe((event: Message) => {
console.log("System event:", event);
// Log system events
});
}
}, [
notifications.status,
chat.status,
events.status,
notifications.subscribe,
chat.subscribe,
events.subscribe,
]);
return (
📡 Multiple Channels
Notifications: {notifications.isSubscribed() ? "✓" : "✗"}
Chat: {chat.isSubscribed() ? "✓" : "✗"}
Events: {events.isSubscribed() ? "✓" : "✗"}
);
}
// =============================================================================
// Example 4: Error Handling
// =============================================================================
function ErrorHandlingExample() {
return (
🚨 Error Handling
(
Provider Error: {error?.message}
)}
>
);
}
function ErrorProneComponent() {
const { error } = useChannel("test-channel");
if (error) {
return (
Channel Error: {error.message}
);
}
return ✅ No errors
;
}
class ErrorBoundary extends React.Component<
{ children: React.ReactNode },
{ hasError: boolean; error: Error | null }
> {
constructor(props: { children: React.ReactNode }) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error: Error) {
return { hasError: true, error };
}
render() {
if (this.state.hasError) {
return (
Something went wrong:
{this.state.error?.message}
);
}
return this.props.children;
}
}
// =============================================================================
// Main App Component
// =============================================================================
export default function App() {
const [activeExample, setActiveExample] = useState("basic");
const examples = {
basic: BasicExample,
channel: ChannelComponentExample,
multi: MultiChannelExample,
error: ErrorHandlingExample,
};
const ExampleComponent = examples[activeExample as keyof typeof examples];
return (
QPub React Integration Examples
);
}