diff --git a/TODO b/TODO
index 91eecea..9217e27 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,5 @@
 Role all (?)
 Server rules
 verificationRequired on welcome
-Role User GUI
\ No newline at end of file
+Role User GUI
+clean channels
diff --git a/src/commands/role/_meta.ts b/src/commands/role/_meta.ts
deleted file mode 100644
index f546d51..0000000
--- a/src/commands/role/_meta.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { command } from "../../utils/commandRegistration/slashCommandBuilder.js";
-
-const name = "role";
-const description = "Change roles for users";
-
-const subcommand = await command(name, description, `role`);
-
-export { name, description, subcommand as command };
diff --git a/src/commands/role/user.ts b/src/commands/role/user.ts
deleted file mode 100644
index 4ec7f3e..0000000
--- a/src/commands/role/user.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import type { CommandInteraction, GuildMember, Role, User } from "discord.js";
-import type { SlashCommandSubcommandBuilder } from "discord.js";
-import client from "../../utils/client.js";
-import confirmationMessage from "../../utils/confirmationMessage.js";
-import keyValueList from "../../utils/generateKeyValueList.js";
-import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
-
-const command = (builder: SlashCommandSubcommandBuilder) =>
-    builder
-        .setName("user")
-        .setDescription("Gives or removes a role from someone")
-        .addUserOption((option) =>
-            option.setName("user").setDescription("The member to give or remove the role from").setRequired(true)
-        )
-        .addRoleOption((option) =>
-            option.setName("role").setDescription("The role to give or remove").setRequired(true)
-        )
-        .addStringOption((option) =>
-            option
-                .setName("action")
-                .setDescription("The action to perform")
-                .setRequired(true)
-                .addChoices(
-                    {name: "Add", value: "give"},
-                    {name: "Remove", value: "remove"}
-                )
-        );
-
-const callback = async (interaction: CommandInteraction): Promise<unknown> => {
-    const { renderUser, renderRole } = client.logger;
-    const action = interaction.options.get("action")?.value as string;
-    const role: Role = (await interaction.guild!.roles.fetch(interaction.options.get("role")?.value as string))!;
-    // TODO:[Modals] Replace this with a modal
-    const confirmation = await new confirmationMessage(interaction)
-        .setEmoji("GUILD.ROLES.DELETE")
-        .setTitle("Role")
-        .setDescription(
-            keyValueList({
-                user: renderUser(interaction.options.getUser("user")! as User),
-                role: renderRole(role)
-            }) +
-                `\nAre you sure you want to ${
-                    action === "give" ? "give the role to" : "remove the role from"
-                } ${interaction.options.getUser("user")}?`
-        )
-        .setColor("Danger")
-        .setFailedMessage("No changes were made", "Success", "GUILD.ROLES.CREATE")
-        .send();
-    if (confirmation.cancelled || !confirmation.success) return;
-    try {
-        const member = interaction.options.getMember("user") as GuildMember;
-        if ((interaction.options.get("action")?.value as string) === "give") {
-            member.roles.add(role);
-        } else {
-            member.roles.remove(role);
-        }
-    } catch (e) {
-        return await interaction.editReply({
-            embeds: [
-                new EmojiEmbed()
-                    .setTitle("Role")
-                    .setDescription("Something went wrong and the role could not be added")
-                    .setStatus("Danger")
-                    .setEmoji("CONTROL.BLOCKCROSS")
-            ],
-            components: []
-        });
-    }
-    return await interaction.editReply({
-        embeds: [
-            new EmojiEmbed()
-                .setTitle("Role")
-                .setDescription(`The role has been ${action === "give" ? "given" : "removed"} successfully`)
-                .setStatus("Success")
-                .setEmoji("GUILD.ROLES.CREATE")
-        ],
-        components: []
-    });
-};
-
-const check = (interaction: CommandInteraction, partial: boolean = false) => {
-    const member = interaction.member as GuildMember;
-    // Check if the user has manage_roles permission
-    if (!member.permissions.has("ManageRoles")) return "You do not have the *Manage Roles* permission";
-    if (partial) return true;
-    if (!interaction.guild) return
-    const me = interaction.guild.members.me!;
-    const apply = interaction.options.getMember("user") as GuildMember | null;
-    if (apply === null) return "That member is not in the server";
-    // Check if Nucleus has permission to role
-    if (!me.permissions.has("ManageRoles")) return "I do not have the *Manage Roles* permission";
-    // Allow the owner to role anyone
-    if (member.id === interaction.guild.ownerId) return true;
-    // Allow role
-    return true;
-};
-
-export { command };
-export { callback };
-export { check };
diff --git a/src/commands/user/role.ts b/src/commands/user/role.ts
new file mode 100644
index 0000000..19bd3c7
--- /dev/null
+++ b/src/commands/user/role.ts
@@ -0,0 +1,163 @@
+import { ActionRowBuilder, APIMessageComponentEmoji, ButtonBuilder, ButtonInteraction, ButtonStyle, CommandInteraction, GuildMember, Role, RoleSelectMenuBuilder, RoleSelectMenuInteraction, UserSelectMenuBuilder, UserSelectMenuInteraction } from "discord.js";
+import type { SlashCommandSubcommandBuilder } from "discord.js";
+import client from "../../utils/client.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import { LoadingEmbed } from "../../utils/defaults.js";
+import getEmojiByName from "../../utils/getEmojiByName.js";
+
+const listToAndMore = (list: string[], max: number) => {
+    // PineappleFan, Coded, Mini (and 10 more)
+    if(list.length > max) {
+        return list.slice(0, max).join(", ") + ` (and ${list.length - max} more)`;
+    }
+    return list.join(", ");
+}
+
+const { renderUser } = client.logger;
+
+const canEdit = (role: Role, member: GuildMember, me: GuildMember): [string, boolean] => {
+    if(role.position >= me.roles.highest.position ||
+       role.position >= member.roles.highest.position
+    ) return [`~~<@&${role.id}>~~`, false];
+    return [`<@&${role.id}>`, true];
+};
+
+const command = (builder: SlashCommandSubcommandBuilder) =>
+    builder
+        .setName("role")
+        .setDescription("Gives or removes a role from someone")
+        .addUserOption((option) => option.setName("user").setDescription("The user to give or remove the role from"))
+
+const callback = async (interaction: CommandInteraction): Promise<unknown> => {
+    const m = await interaction.reply({ embeds: LoadingEmbed, fetchReply: true, ephemeral: true });
+
+    let member = interaction.options.getMember("user") as GuildMember | null;
+
+    if(!member) {
+        let memberEmbed = new EmojiEmbed()
+            .setTitle("Role")
+            .setDescription(`Please choose a member to edit the roles of.`)
+            .setEmoji("GUILD.ROLES.CREATE")
+            .setStatus("Success");
+        let memberChooser = new ActionRowBuilder<UserSelectMenuBuilder>().addComponents(
+            new UserSelectMenuBuilder()
+                .setCustomId("memberChooser")
+                .setPlaceholder("Select a member")
+        );
+        await interaction.editReply({embeds: [memberEmbed], components: [memberChooser]});
+
+        const filter = (i: UserSelectMenuInteraction) => i.customId === "memberChooser" && i.user.id === interaction.user.id;
+
+        let i: UserSelectMenuInteraction | null;
+        try {
+            i = await m.awaitMessageComponent<5>({ filter, time: 300000});
+        } catch (e) {
+            return;
+        }
+
+        if(!i) return;
+        memberEmbed.setDescription(`Editing roles for ${renderUser(i.values[0]!)}`);
+        await i.deferUpdate();
+        await interaction.editReply({ embeds: LoadingEmbed, components: [] })
+        member = await interaction.guild?.members.fetch(i.values[0]!)!;
+
+    }
+
+    let closed = false;
+    let rolesToChange: string[] = [];
+    const roleAdd = new ActionRowBuilder<RoleSelectMenuBuilder>()
+        .addComponents(
+            new RoleSelectMenuBuilder()
+                .setCustomId("roleAdd")
+                .setPlaceholder("Select a role to add")
+                .setMaxValues(25)
+        );
+
+    do {
+        const embed = new EmojiEmbed()
+        .setTitle("Role")
+        .setDescription(
+            `${getEmojiByName("ICONS.EDIT")} Editing roles for <@${member.id}>\n\n` +
+            `Adding:\n` +
+            `${listToAndMore(rolesToChange.filter((r) => !member!.roles.cache.has(r)).map((r) => canEdit(interaction.guild?.roles.cache.get(r)!, interaction.member as GuildMember, interaction.guild?.members.me!)[0]) || ["None"], 5)}\n` +
+            `Removing:\n` +
+            `${listToAndMore(rolesToChange.filter((r) => member!.roles.cache.has(r)).map((r) => canEdit(interaction.guild?.roles.cache.get(r)!, interaction.member as GuildMember, interaction.guild?.members.me!)[0]) || ["None"], 5)}\n`
+        )
+        .setEmoji("GUILD.ROLES.CREATE")
+        .setStatus("Success");
+
+        const buttons = new ActionRowBuilder<ButtonBuilder>()
+            .addComponents(
+                new ButtonBuilder()
+                    .setCustomId("roleSave")
+                    .setLabel("Apply")
+                    .setEmoji(getEmojiByName("ICONS.SAVE", "id") as APIMessageComponentEmoji)
+                    .setStyle(ButtonStyle.Success),
+                new ButtonBuilder()
+                    .setCustomId("roleDiscard")
+                    .setLabel("Reset")
+                    .setEmoji(getEmojiByName("CONTROL.CROSS", "id") as APIMessageComponentEmoji)
+                    .setStyle(ButtonStyle.Danger)
+            );
+
+        await interaction.editReply({ embeds: [embed], components: [roleAdd, buttons] });
+
+        let i: RoleSelectMenuInteraction | ButtonInteraction | null;
+        try {
+            i = await m.awaitMessageComponent({ filter: (i) => i.user.id === interaction.user.id, time: 300000 }) as RoleSelectMenuInteraction | ButtonInteraction;
+        } catch (e) {
+            return;
+        }
+
+        if(!i) return;
+        i.deferUpdate();
+        if(i.isButton()) {
+            switch(i.customId) {
+                case "roleSave":
+                    const roles = rolesToChange.map((r) => interaction.guild?.roles.cache.get(r)!);
+                    await interaction.editReply({ embeds: LoadingEmbed, components: [] });
+                    let rolesToAdd: Role[] = [];
+                    let rolesToRemove: Role[] = [];
+                    for(const role of roles) {
+                        if(!canEdit(role, interaction.member as GuildMember, interaction.guild?.members.me!)[1]) continue;
+                        if(member.roles.cache.has(role.id)) {
+                            rolesToRemove.push(role);
+                        } else {
+                            rolesToAdd.push(role);
+                        }
+                    }
+                    await member.roles.add(rolesToAdd);
+                    await member.roles.remove(rolesToRemove);
+                    rolesToChange = [];
+                    break;
+                case "roleDiscard":
+                    rolesToChange = [];
+                    await interaction.editReply({ embeds: LoadingEmbed, components: [] });
+                    break;
+            }
+        } else {
+            rolesToChange = i.values;
+        }
+
+    } while (!closed);
+
+};
+
+const check = (interaction: CommandInteraction, partial: boolean = false) => {
+    const member = interaction.member as GuildMember;
+    // Check if the user has manage_roles permission
+    if (!member.permissions.has("ManageRoles")) return "You do not have the *Manage Roles* permission";
+    if (partial) return true;
+    if (!interaction.guild) return
+    const me = interaction.guild.members.me!;
+    // Check if Nucleus has permission to role
+    if (!me.permissions.has("ManageRoles")) return "I do not have the *Manage Roles* permission";
+    // Allow the owner to role anyone
+    if (member.id === interaction.guild.ownerId) return true;
+    // Allow role
+    return true;
+};
+
+export { command };
+export { callback };
+export { check };
