);
};
```
--------------------------------
### Comments System with Moderation using React and Supabase
Source: https://context7.com/arielxfelipe/arfel/llms.txt
A comprehensive comments system for novels, supporting comments at both novel and chapter levels. Includes moderation features like spoiler tagging and content censoring. Fetches comments and associated user profiles from Supabase. Requires `AuthContext` for user authentication and `useRoles` hook for permission checks.
```tsx
import { useRoles } from "@/hooks/use-roles";
import { supabase } from "@/integrations/supabase/client";
interface Comment {
id: string;
content: string;
created_at: string;
user_id: string;
is_spoiler: boolean;
is_censored: boolean;
profile?: { display_name: string | null; avatar_url: string | null };
}
const NovelComments = ({ novelId }: { novelId: string }) => {
const { user } = useAuth();
const { isModerator, isAdmin } = useRoles();
const [comments, setComments] = useState([]);
// Load comments with user profiles
const loadComments = async () => {
const { data } = await supabase
.from("novel_comments")
.select("*")
.eq("novel_id", novelId)
.order("created_at", { ascending: true });
if (data) {
const userIds = [...new Set(data.map((c) => c.user_id))];
const { data: profiles } = await supabase
.from("profiles")
.select("user_id, display_name, avatar_url")
.in("user_id", userIds);
const profileMap = new Map(profiles?.map((p) => [p.user_id, p]));
setComments(data.map((c) => ({ ...c, profile: profileMap.get(c.user_id) })));
}
};
// Post new comment
const handlePost = async (content: string) => {
if (!user) return;
await supabase.from("novel_comments").insert({
user_id: user.id,
novel_id: novelId,
content: content.trim(),
});
loadComments();
};
// Moderation: toggle spoiler flag
const handleToggleSpoiler = async (commentId: string, current: boolean) => {
await supabase.from("novel_comments")
.update({ is_spoiler: !current })
.eq("id", commentId);
loadComments();
};
// Moderation: censor comment
const handleCensor = async (commentId: string) => {
await supabase.from("novel_comments")
.update({ is_censored: true })
.eq("id", commentId);
loadComments();
};
// Delete comment (owner or moderator)
const handleDelete = async (commentId: string) => {
await supabase.from("novel_comments").delete().eq("id", commentId);
loadComments();
};
const canModerate = isModerator || isAdmin;
// ... render component
};
```
--------------------------------
### Implement Protected React Router Navigation
Source: https://context7.com/arielxfelipe/arfel/llms.txt
Configures application routes using React Router, implementing a ProtectedRoute wrapper to ensure authentication. It handles public, reader-specific, and role-based administrative routes.
```tsx
import { BrowserRouter, Route, Routes, Navigate } from "react-router-dom";
const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
const { user, loading } = useAuth();
if (loading) return null;
if (!user) return ;
return <>{children}>;
};
const AppRoutes = () => (
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
);
```
--------------------------------
### Internationalization and Language Management (React/TypeScript)
Source: https://context7.com/arielxfelipe/arfel/llms.txt
Handles user language preferences (Portuguese, English, Spanish) and provides a translation function `t()` for localized strings. Language settings are persisted in the user's profile.
```tsx
import { useLanguage } from "@/contexts/LanguageContext";
import { t } from "@/lib/i18n";
// Language type definition
type Language = "pt" | "en" | "es";
// Using the language context
const MyComponent = () => {
const { language, setLanguage, loading } = useLanguage();
// Change language (persists to user profile)
const handleLanguageChange = async (newLang: Language) => {
await setLanguage(newLang);
};
return (
{t("nav.home", language)}
{t("hero.subtitle", language)}
);
};
// Translation function usage
const translations: Record> = {
"nav.home": { pt: "Início", en: "Home", es: "Inicio" },
"nav.explore": { pt: "Explorar", en: "Explore", es: "Explorar" },
"chapter.chapter": { pt: "Capítulo", en: "Chapter", es: "Capítulo" },
};
export function t(key: string, language: Language): string {
return translations[key]?.[language] ?? translations[key]?.["en"] ?? key;
}
```
--------------------------------
### Role-Based Access Control Hook (React/TypeScript)
Source: https://context7.com/arielxfelipe/arfel/llms.txt
Provides a hook `useRoles` to manage and check user roles (admin, moderator, uploader, revisor). It fetches roles from the `user_roles` table and offers boolean flags for easy access control.
```tsx
import { useRoles, AppRole } from "@/hooks/use-roles";
// Available roles
type AppRole = "admin" | "moderator" | "uploader" | "revisor" | "user";
// Using the roles hook
const AdminGuard = ({ children }: { children: React.ReactNode }) => {
const { isAdmin, isModerator, isUploader, isRevisor, hasRole, loading, roles } = useRoles();
if (loading) return null;
// Check specific roles
if (!isAdmin && !isModerator) {
return ;
}
// Or use hasRole for custom checks
if (!hasRole("admin")) {
return
Access denied
;
}
return <>{children}>;
};
// Database query for roles
const loadRoles = async (userId: string) => {
const { data } = await supabase
.from("user_roles")
.select("role")
.eq("user_id", userId);
return data?.map((r) => r.role) as AppRole[];
};
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.