"use client" import { InviteCard } from "@/components/cards/InviteCard"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; import { Command, CommandItem } from "@/components/ui/command"; import { Input } from "@/components/ui/input"; import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover"; import { toast } from "@/components/ui/use-toast"; import { bulkDeleteInvites, createInvite } from "@/lib/actions"; import { ChannelInvite } from "@/lib/db"; import { ChevronsUpDown } from "lucide-react"; import { useMemo, useState } from "react"; import { Channel, Server, User } from "revolt-api"; export default function ServerInviteList({ server, invites: invitesInput, channels, users }: { server: Server, invites: ChannelInvite[], channels?: Channel[], users?: User[], }) { const [invites, setInvites] = useState(invitesInput); const [selectVanityOnly, setSelectVanityOnly] = useState(false); const [selectChannel, setSelectChannel] = useState(false); const [selectUser, setSelectUser] = useState(false); const [vanityFilter, setVanityFilter] = useState(null); const [channelFilter, setChannelFilter] = useState(""); const [userFilter, setUserFilter] = useState(""); const [inviteDraft, setInviteDraft] = useState(""); const [inviteChannelDraft, setInviteChannelDraft] = useState(""); const filteredInvites = useMemo(() => { return invites ?.filter(invite => vanityFilter === true ? invite.vanity : vanityFilter === false ? !invite.vanity : true) ?.filter(invite => channelFilter ? invite.channel == channelFilter : true) ?.filter(invite => userFilter ? invite.creator == userFilter : true) ?.reverse(); }, [vanityFilter, channelFilter, userFilter, invites]); return (
{[ { value: null, label: "All" }, { value: true, label: "Vanity" }, { value: false, label: "Not vanity" }, ].map((option) => ( { setSelectVanityOnly(false); setVanityFilter(option.value); }} >{option.label} ))} { setSelectChannel(false); setChannelFilter(""); }} >All channels {channels?.map((channel) => ( { setSelectChannel(false); setChannelFilter(channel._id); }} >{'#' + (channel as any).name} ))} { setSelectUser(false); setUserFilter(""); }} >All users {users?.map((user) => ( { setSelectUser(false); setUserFilter(user._id); }} >{user.username}#{user.discriminator} ))} Bulk delete invites This will delete all invites that match your filter options.
{filteredInvites.length} invite{filteredInvites.length == 1 ? '' : 's'} will be deleted.
{ try { await bulkDeleteInvites(filteredInvites.map(i => i._id)); setInvites(invites.filter(invite => !filteredInvites.find(i => i._id == invite._id))); toast({ title: "Selected invites have been deleted" }); } catch(e) { toast({ title: "Failed to delete invites", description: String(e), variant: "destructive", }); } }} >Bulk delete Cancel
Create vanity invite

Invites are case sensitive.

setInviteDraft(e.currentTarget.value)} placeholder="fortnite" />
{ try { const newInvite: ChannelInvite = { _id: inviteDraft, channel: inviteChannelDraft, creator: server.owner, server: server._id, type: "Server", vanity: true, }; await createInvite(newInvite); setInvites([...invites, newInvite]); setInviteDraft(""); toast({ title: "Vanity invite created", description: rvlt.gg/{inviteDraft} }); } catch(e) { toast({ title: "Failed to create invite", description: String(e), variant: "destructive", }); } }} >Create Cancel
{filteredInvites.map(invite => ( c._id == invite.channel)} channelList={channels} user={users?.find(c => c._id == invite.creator)} key={invite._id} />))}
) } export function ChannelDropdown({ channels, value, setValue }: { channels: Channel[], value: string, setValue: (value: string) => any, }) { const [expanded, setExpanded] = useState(false); return ( {channels?.map((channel) => ( { setExpanded(false); setValue(channel._id); }} >{'#' + (channel as any).name} ))} ); }