Development (#93)

diff --git a/src/actions/roleMenu.ts b/src/actions/roleMenu.ts
index 9c9430d..8b623a4 100644
--- a/src/actions/roleMenu.ts
+++ b/src/actions/roleMenu.ts
@@ -32,7 +32,7 @@
 
 interface ObjectSchema {
     name: string;
-    description: string;
+    description: string | null;
     min: number;
     max: number;
     options: {
@@ -72,6 +72,7 @@
     if (!interaction.member) return;
     if (!interaction.guild) return;
     const config = await client.database.guilds.read(interaction.guild.id);
+    const options = config.roleMenu.options.filter((option) => option.options.length > 0);
     if (!config.roleMenu.enabled) {
         return await interaction.reply({
             embeds: [
@@ -86,7 +87,7 @@
             ephemeral: true
         });
     }
-    if (config.roleMenu.options.length === 0)
+    if (options.length === 0) {
         return await interaction.reply({
             embeds: [
                 new EmojiEmbed()
@@ -99,6 +100,7 @@
             ],
             ephemeral: true
         });
+    }
     const m = await interaction.reply({ embeds: LoadingEmbed, ephemeral: true, fetchReply: true });
     if (config.roleMenu.allowWebUI) {
         // TODO: Make rolemenu web ui
@@ -180,8 +182,6 @@
             await component.deferUpdate();
         }
     }
-
-    const options = config.roleMenu.options;
     const selectedRoles: string[][] = [];
     const maxPage = options.length;
     const completedPages: boolean[] = options.map((option) => option.min === 0);
diff --git a/src/commands/nucleus/premium.ts b/src/commands/nucleus/premium.ts
index 5894850..a3f1368 100644
--- a/src/commands/nucleus/premium.ts
+++ b/src/commands/nucleus/premium.ts
@@ -56,11 +56,8 @@
                     })
                 )
         );
-        const cancel = new ActionRowBuilder<ButtonBuilder>().addComponents(
-            new ButtonBuilder().setCustomId("cancel").setLabel("Close").setStyle(ButtonStyle.Danger)
-        );
 
-        const components: ActionRowBuilder<StringSelectMenuBuilder | ButtonBuilder>[] = [cancel];
+        const components: ActionRowBuilder<StringSelectMenuBuilder>[] = [];
         if (options.length > 0) components.unshift(removeRow);
         await interaction.editReply({
             embeds: [
@@ -77,24 +74,20 @@
             components: components
         });
 
-        let i: StringSelectMenuInteraction | ButtonInteraction;
+        let i: StringSelectMenuInteraction;
         try {
-            const filter = (i: StringSelectMenuInteraction | ButtonInteraction) => i.user.id === interaction.user.id;
-            i = await msg.awaitMessageComponent<ComponentType.StringSelect | ComponentType.Button>({
+            const filter = (i: StringSelectMenuInteraction) => i.user.id === interaction.user.id;
+            i = await msg.awaitMessageComponent<ComponentType.StringSelect>({
                 time: 300000,
                 filter
             });
         } catch (e) {
             await interaction.deleteReply();
             closed = true;
-            break;
+            continue;
         }
         await i.deferUpdate();
-        if (i.isButton()) {
-            closed = true;
-        } else {
-            await client.database.premium.removePremium(interaction.user.id, i.values[0]!);
-        }
+        await client.database.premium.removePremium(interaction.user.id, i.values[0]!);
     } while (!closed);
     await interaction.deleteReply();
 };
diff --git a/src/commands/settings/rolemenu.ts b/src/commands/settings/rolemenu.ts
index 9779126..dbdcb4c 100644
--- a/src/commands/settings/rolemenu.ts
+++ b/src/commands/settings/rolemenu.ts
@@ -29,11 +29,12 @@
 
 const isEqual = _.isEqual;
 
-const command = (builder: SlashCommandSubcommandBuilder) => builder.setName("rolemenu").setDescription("rolemenu");
+const command = (builder: SlashCommandSubcommandBuilder) =>
+    builder.setName("rolemenu").setDescription("Allows you to change settings for the servers rolemenu");
 
 interface ObjectSchema {
     name: string;
-    description: string;
+    description: string | null;
     min: number;
     max: number;
     options: {
@@ -105,7 +106,7 @@
     i: ButtonInteraction,
     interaction: StringSelectMenuInteraction | ButtonInteraction,
     m: Message,
-    data: { name?: string; description?: string }
+    data: { name?: string; description?: string | null }
 ) => {
     let { name, description } = data;
     const modal = new ModalBuilder()
@@ -162,7 +163,7 @@
     if (!out) return [name, description];
     if (out.isButton()) return [name, description];
     name = out.fields.fields.find((f) => f.customId === "name")?.value ?? name;
-    description = out.fields.fields.find((f) => f.customId === "description")?.value ?? "";
+    description = out.fields.fields.find((f) => f.customId === "description")?.value ?? null;
     return [name, description];
 };
 
@@ -205,7 +206,7 @@
             "Edit Roles",
             {
                 name: data.name,
-                description: data.description,
+                description: data.description ?? null,
                 min: 1,
                 max: 1,
                 options: noRoles ? [{ name: "Role 1", description: null, role: "No role set" }] : data.options
@@ -217,7 +218,7 @@
             .setTitle(`${data.name}`)
             .setStatus("Success")
             .setDescription(
-                `**Description:**\n> ${data.description}\n\n` +
+                `**Description:**\n> ${data.description ?? "*No description set*"}\n\n` +
                     `**Min:** ${data.min}` +
                     (data.min === 0 ? " (Members will be given a skip button)" : "") +
                     "\n" +
@@ -393,31 +394,47 @@
     let page = 0;
     let closed = false;
     const config = await client.database.guilds.read(interaction.guild.id);
-    let currentObject: ObjectSchema[] = _.cloneDeep(config.roleMenu.options);
+    const currentObject: typeof config.roleMenu = _.cloneDeep(config.roleMenu);
     let modified = false;
     do {
         const embed = new EmojiEmbed().setTitle("Role Menu").setEmoji("GUILD.GREEN").setStatus("Success");
-        const noRoleMenus = currentObject.length === 0;
+        const noRoleMenus = currentObject.options.length === 0;
         let current: ObjectSchema;
 
         const pageSelect = new StringSelectMenuBuilder()
             .setCustomId("page")
             .setPlaceholder("Select a Role Menu page to manage");
-        const actionSelect = new StringSelectMenuBuilder()
-            .setCustomId("action")
-            .setPlaceholder("Perform an action")
-            .addOptions(
-                new StringSelectMenuOptionBuilder()
-                    .setLabel("Edit")
-                    .setDescription("Edit this page")
-                    .setValue("edit")
-                    .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
-                new StringSelectMenuOptionBuilder()
-                    .setLabel("Delete")
-                    .setDescription("Delete this page")
-                    .setValue("delete")
-                    .setEmoji(getEmojiByName("TICKETS.ISSUE", "id") as APIMessageComponentEmoji)
+        let actionSelect;
+        if (page === 0) {
+            actionSelect = new ActionRowBuilder<ButtonBuilder>().addComponents(
+                new ButtonBuilder()
+                    .setCustomId("switch")
+                    .setLabel(currentObject.enabled ? "Enabled" : "Disabled")
+                    .setStyle(currentObject.enabled ? ButtonStyle.Success : ButtonStyle.Danger)
+                    .setEmoji(
+                        getEmojiByName(
+                            currentObject.enabled ? "CONTROL.TICK" : "CONTROL.CROSS",
+                            "id"
+                        ) as APIMessageComponentEmoji
+                    )
             );
+        } else {
+            actionSelect = new StringSelectMenuBuilder()
+                .setCustomId("action")
+                .setPlaceholder("Perform an action")
+                .addOptions(
+                    new StringSelectMenuOptionBuilder()
+                        .setLabel("Edit")
+                        .setDescription("Edit this page")
+                        .setValue("edit")
+                        .setEmoji(getEmojiByName("ICONS.EDIT", "id") as APIMessageComponentEmoji),
+                    new StringSelectMenuOptionBuilder()
+                        .setLabel("Delete")
+                        .setDescription("Delete this page")
+                        .setValue("delete")
+                        .setEmoji(getEmojiByName("TICKETS.ISSUE", "id") as APIMessageComponentEmoji)
+                );
+        }
         const buttonRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
             new ButtonBuilder()
                 .setCustomId("back")
@@ -428,19 +445,19 @@
                 .setCustomId("next")
                 .setEmoji(getEmojiByName("CONTROL.RIGHT", "id") as APIMessageComponentEmoji)
                 .setStyle(ButtonStyle.Primary)
-                .setDisabled(page === Object.keys(currentObject).length - 1 || noRoleMenus),
+                .setDisabled(page === Object.keys(currentObject.options).length || noRoleMenus),
             new ButtonBuilder()
                 .setCustomId("add")
                 .setLabel("New Page")
                 .setEmoji(getEmojiByName("TICKETS.SUGGESTION", "id") as APIMessageComponentEmoji)
                 .setStyle(ButtonStyle.Secondary)
-                .setDisabled(Object.keys(currentObject).length >= 24),
+                .setDisabled(Object.keys(currentObject.options).length >= 24),
             new ButtonBuilder()
                 .setCustomId("reorder")
                 .setLabel("Reorder Pages")
                 .setEmoji(getEmojiByName("ICONS.REORDER", "id") as APIMessageComponentEmoji)
                 .setStyle(ButtonStyle.Secondary)
-                .setDisabled(Object.keys(currentObject).length <= 1),
+                .setDisabled(Object.keys(currentObject.options).length <= 1),
             new ButtonBuilder()
                 .setCustomId("save")
                 .setLabel("Save")
@@ -454,22 +471,69 @@
                     createPageIndicator(1, 1, undefined, true)
             );
             pageSelect.setDisabled(true);
-            actionSelect.setDisabled(true);
+            if (page > 0) (actionSelect as StringSelectMenuBuilder).setDisabled(true);
             pageSelect.addOptions(new StringSelectMenuOptionBuilder().setLabel("No role menu pages").setValue("none"));
+        } else if (page === 0) {
+            const cross = getEmojiByName("CONTROL.CROSS");
+            const tick = getEmojiByName("CONTROL.TICK");
+            embed.setDescription(
+                `**Enabled:** ${config.roleMenu.enabled ? `${tick} Yes` : `${cross} No`}\n\n` +
+                    `**Pages:** ${currentObject.options.length}\n` +
+                    (currentObject.options.length > 0
+                        ? currentObject.options
+                              .map((key: ObjectSchema) => {
+                                  return `> **${key.name}:** ${key.description ?? "*No description set*"}`;
+                              })
+                              .join("\n")
+                        : "")
+            );
+            if (currentObject.options.length > 0) {
+                pageSelect.addOptions(
+                    currentObject.options.map((key: ObjectSchema, index) => {
+                        return new StringSelectMenuOptionBuilder()
+                            .setLabel(ellipsis(key.name, 50))
+                            .setDescription(
+                                ellipsis(
+                                    key.description?.length
+                                        ? key.description.length > 0
+                                            ? key.description
+                                            : "No description set"
+                                        : "No description set",
+                                    50
+                                )
+                            )
+                            .setValue(index.toString());
+                    })
+                );
+            } else {
+                pageSelect.setDisabled(true);
+                pageSelect.addOptions(
+                    new StringSelectMenuOptionBuilder().setLabel("No role menu pages").setValue("none")
+                );
+            }
         } else {
-            page = Math.max(Math.min(page, currentObject.length - 1), 0);
-            current = currentObject[page]!;
+            page = Math.max(Math.min(page, currentObject.options.length), 0);
+            current = currentObject.options[page - 1]!;
             embed.setDescription(
                 `**Currently Editing:** ${current.name}\n\n` +
-                    `**Description:**\n> ${current.description || "*No description set*"}\n` +
+                    `**Description:**\n> ${current.description ?? "*No description set*"}\n` +
                     `\n\n${createPageIndicator(Object.keys(config.roleMenu.options).length, page)}`
             );
 
             pageSelect.addOptions(
-                currentObject.map((key: ObjectSchema, index) => {
+                currentObject.options.map((key: ObjectSchema, index) => {
                     return new StringSelectMenuOptionBuilder()
                         .setLabel(ellipsis(key.name, 50))
-                        .setDescription(ellipsis(key.description || "No description set", 50))
+                        .setDescription(
+                            ellipsis(
+                                key.description?.length
+                                    ? key.description.length > 0
+                                        ? key.description
+                                        : "No description set"
+                                    : "No description set",
+                                50
+                            )
+                        )
                         .setValue(index.toString());
                 })
             );
@@ -478,9 +542,13 @@
         await interaction.editReply({
             embeds: [embed],
             components: [
-                new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(actionSelect),
+                page === 0
+                    ? (actionSelect as ActionRowBuilder<ButtonBuilder>)
+                    : new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
+                          actionSelect as StringSelectMenuBuilder
+                      ),
                 new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(pageSelect),
-                buttonRow
+                buttonRow as ActionRowBuilder<ButtonBuilder>
             ]
         });
         let i: StringSelectMenuInteraction | ButtonInteraction;
@@ -512,23 +580,32 @@
                         break;
                     }
                     if (newPage) {
-                        currentObject.push(newPage);
-                        page = currentObject.length - 1;
+                        currentObject.options.push(newPage);
+                        page = currentObject.options.length;
+                        modified = true;
                     }
                     break;
                 }
                 case "reorder": {
-                    const reordered = await reorderRoleMenuPages(interaction, m, currentObject);
+                    const reordered = await reorderRoleMenuPages(interaction, m, currentObject.options);
                     if (!reordered) break;
-                    currentObject = reordered;
+                    currentObject.options = reordered;
+                    modified = true;
                     break;
                 }
                 case "save": {
-                    await client.database.guilds.write(interaction.guild.id, { "roleMenu.options": currentObject });
+                    await client.database.guilds.write(interaction.guild.id, {
+                        "roleMenu.options": currentObject.options
+                    });
                     modified = false;
                     await client.memory.forceUpdate(interaction.guild.id);
                     break;
                 }
+                case "switch": {
+                    currentObject.enabled = !currentObject.enabled;
+                    modified = true;
+                    break;
+                }
             }
         } else if (i.isStringSelectMenu()) {
             switch (i.customId) {
@@ -537,14 +614,15 @@
                         case "edit": {
                             const edited = await editRoleMenuPage(i, m, current!);
                             if (!edited) break;
-                            currentObject[page] = edited;
+                            currentObject.options[page] = edited;
                             modified = true;
                             break;
                         }
                         case "delete": {
-                            if (page === 0 && currentObject.keys.length - 1 > 0) page++;
+                            if (page === 0 && currentObject.options.keys.length - 1 > 0) page++;
                             else page--;
-                            currentObject.splice(page, 1);
+                            currentObject.options.splice(page, 1);
+                            modified = true;
                             break;
                         }
                     }
diff --git a/src/config/default.ts b/src/config/default.ts
index f0b931e..69de019 100644
--- a/src/config/default.ts
+++ b/src/config/default.ts
@@ -88,7 +88,7 @@
     },
     moderation: {
         mute: {
-            timeout: false,
+            timeout: true,
             role: null,
             text: null,
             link: null
@@ -121,13 +121,13 @@
     },
     tracks: [],
     roleMenu: {
-        enabled: false,
+        enabled: true,
         allowWebUI: false,
         options: []
     },
     tags: {},
     autoPublish: {
-        enabled: false,
+        enabled: true,
         channels: []
     }
 } as GuildConfig;
diff --git a/src/utils/database.ts b/src/utils/database.ts
index f24416a..a1d5f49 100644
--- a/src/utils/database.ts
+++ b/src/utils/database.ts
@@ -1016,7 +1016,7 @@
         allowWebUI: boolean;
         options: {
             name: string;
-            description: string;
+            description: string | null;
             min: number;
             max: number;
             options: {