changes to how deleting tickets works, and UI when creating mod tickets
diff --git a/src/utils/client.ts b/src/utils/client.ts
new file mode 100644
index 0000000..3f4a8a1
--- /dev/null
+++ b/src/utils/client.ts
@@ -0,0 +1,9 @@
+import { HaikuClient } from 'jshaiku';
+import { Intents } from 'discord.js';
+import config from '../config/main.json' assert {type: 'json'};
+
+const client = new HaikuClient({
+    intents: new Intents(32767).bitfield,  // This is a way of specifying all intents w/o having to type them out
+}, config);
+
+export default client;
\ No newline at end of file
diff --git a/src/utils/confirmationMessage.ts b/src/utils/confirmationMessage.ts
index dd97603..7a06d83 100644
--- a/src/utils/confirmationMessage.ts
+++ b/src/utils/confirmationMessage.ts
@@ -14,6 +14,8 @@
     customCallbackString: string = "";
     customCallbackClicked: boolean = false;
     customCallbackResponse: any = null;
+    customBoolean: () => any;
+    customBooleanClicked: boolean = null;
     inverted: boolean;
 
     constructor(interaction: CommandInteraction) {
@@ -23,8 +25,9 @@
         this.emoji = "";
         this.description = "";
         this.color = "";
-        this.inverted = false
-        this.customCallback = () => {}
+        this.inverted = false;
+        this.customCallback = () => {};
+        this.customBoolean = () => {};
     }
 
     setTitle(title: string) { this.title = title; return this }
@@ -33,12 +36,23 @@
     setColor(color: string) { this.color = color; return this }
     setInverted(inverted: boolean) { this.inverted = inverted; return this }
     addCustomCallback(title: string, disabled: boolean, callback: () => any, callbackClicked: string) {
+        if (this.customButtonTitle) return this
         this.customButtonTitle = title;
         this.customButtonDisabled = disabled;
         this.customCallback = callback;
         this.customCallbackString = callbackClicked;
         return this;
     }
+    addCustomBoolean(title: string, disabled: boolean, callback: () => any, callbackClicked: string) {
+        if (this.customButtonTitle) return this
+        this.customButtonTitle = title;
+        this.customButtonDisabled = disabled;
+        this.customBoolean = callback;
+        this.customCallbackString = callbackClicked;
+        this.customBooleanClicked = false;
+        return this;
+    }
+
 
     async send(editOnly?: boolean) {
         while (true) {
@@ -49,7 +63,7 @@
                         .setTitle(this.title)
                         .setDescription(this.description)
                         .setStatus(this.color)
-                        .setFooter({text: this.customCallbackClicked ? this.customCallbackString : ""})
+                        .setFooter({text: (this.customBooleanClicked ?? this.customCallbackClicked) ? this.customCallbackString : ""})
                 ],
                 components: [
                     new MessageActionRow().addComponents([
@@ -66,7 +80,10 @@
                     ].concat(this.customButtonTitle ? [new Discord.MessageButton()
                         .setCustomId("custom")
                         .setLabel(this.customButtonTitle)
-                        .setStyle("PRIMARY")
+                        .setStyle(this.customBooleanClicked !== null ?
+                            ( this.customBooleanClicked ? "SUCCESS" : "PRIMARY" ) :
+                            "PRIMARY"
+                        )
                         .setDisabled(this.customButtonDisabled)
                         .setEmoji(getEmojiByName("CONTROL.TICKET", "id"))
                     ] : []))
@@ -84,19 +101,36 @@
             try {
                 component = await (m as Message).awaitMessageComponent({filter: (m) => m.user.id === this.interaction.user.id, time: 2.5 * 60 * 1000});
             } catch (e) {
-                return { success: false, buttonClicked: this.customCallbackClicked, response: this.customCallbackResponse };
+                return {
+                    success: false,
+                    buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
+                    response: this.customCallbackResponse
+                };
             }
             if (component.customId === "yes") {
                 component.deferUpdate();
-                return { success: true, buttonClicked: this.customCallbackClicked, response: this.customCallbackResponse };
+                if (this.customBooleanClicked === true) this.customCallbackResponse = await this.customBoolean();
+                return {
+                    success: true,
+                    buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
+                    response: this.customCallbackResponse
+                };
             } else if (component.customId === "no") {
                 component.deferUpdate();
-                return { success: false, buttonClicked: this.customCallbackClicked, response: this.customCallbackResponse };
+                return {
+                    success: false,
+                    buttonClicked: this.customBooleanClicked ?? this.customCallbackClicked,
+                    response: this.customCallbackResponse
+                };
             } else if (component.customId === "custom") {
                 component.deferUpdate();
-                this.customCallbackResponse = this.customCallback();
-                this.customCallbackClicked = true;
-                this.customButtonDisabled = true;
+                if (this.customBooleanClicked !== null) {
+                    this.customBooleanClicked = !this.customBooleanClicked;
+                } else {
+                    this.customCallbackResponse = await this.customCallback();
+                    this.customCallbackClicked = true;
+                    this.customButtonDisabled = true;
+                }
                 editOnly = true;
             }
         }
diff --git a/src/utils/database.ts b/src/utils/database.ts
new file mode 100644
index 0000000..53ccb97
--- /dev/null
+++ b/src/utils/database.ts
@@ -0,0 +1,180 @@
+import { Collection, Db, MongoClient } from 'mongodb';
+
+
+export const Entry = data => {
+    data = data ?? {};
+    return {
+        get(target, prop, receiver) {
+            let dataToReturn = data[prop]
+            if (dataToReturn === null ) return Reflect.get(target, prop, receiver);
+            if (typeof dataToReturn === "object" && !Array.isArray(dataToReturn)) dataToReturn = new Proxy(
+                Reflect.get(target, prop, receiver),
+                Entry(dataToReturn),
+            )
+            return dataToReturn ?? Reflect.get(target, prop, receiver);
+        }
+    }
+}
+
+
+export default class Database {
+    mongoClient: MongoClient;
+    database: Db;
+    guilds: Collection<GuildConfig>;
+    defaultData: GuildConfig;
+
+    constructor(url) {
+        this.mongoClient = new MongoClient(url);
+    }
+
+    async connect() {
+        await this.mongoClient.connect()
+        this.database = this.mongoClient.db("Nucleus");
+        this.guilds = this.database.collection<GuildConfig>("guilds");
+        await this.guilds.createIndex({ id: "text" }, { unique: true });
+        this.defaultData = (await import("../config/default.json", { assert: { type: "json" }})).default as unknown as GuildConfig;
+        return this;
+    }
+
+    async read(guild: string) {
+        let entry = await this.guilds.findOne({ id: guild });
+        return new Proxy(this.defaultData, Entry(entry)) as unknown as GuildConfig
+    }
+
+    async write(guild: string, config: GuildConfig) {
+        await this.guilds.updateOne({ id: guild }, { $set: config }, { upsert: true });
+    }
+}
+
+export interface GuildConfig {
+    id: string,
+    version: number,
+    singleEventNotifications: {
+        statsChannelDeleted: boolean
+    }
+    filters: {
+        images: {
+            NSFW: boolean,
+            size: boolean
+        },
+        malware: boolean,
+        wordFilter: {
+            enabled: boolean,
+            words: {
+                strict: string[],
+                loose: string[]
+            },
+            allowed: {
+                users: string[],
+                roles: string[],
+                channels: string[]
+            }
+        },
+        invite: {
+            enabled: boolean,
+            allowed: {
+                users: string[],
+                channels: string[],
+                roles: string[]
+            }
+        },
+        pings: {
+            mass: number,
+            everyone: boolean,
+            roles: boolean,
+            allowed: {
+                roles: string[],
+                rolesToMention: string[],
+                users: string[],
+                channels: string[]
+            }
+        }
+    }
+    welcome: {
+        enabled: boolean,
+        verificationRequired: {
+            message: boolean,
+            role: string
+        },
+        welcomeRole: string,
+        channel: string,
+        message: string
+    }
+    stats: {
+        enabled: boolean,
+        channel: string,
+        text: string
+    }[]
+    logging: {
+        logs: {
+            enabled: boolean,
+            channel: string,
+            toLog: string
+        },
+        staff: {
+            channel: string
+        }
+    }
+    verify: {
+        enabled: boolean,
+        role: string
+    }
+    tickets: {
+        enabled: boolean,
+        category: string,
+        types: string,
+        customTypes: string[],
+        supportRole: string,
+        maxTickets: number
+    }
+    moderation: {
+        mute: {
+            timeout: boolean,
+            role: string,
+            text: string,
+            link: string
+        },
+        kick: {
+            text: string,
+            link: string
+        },
+        ban: {
+            text: string,
+            link: string
+        },
+        softban: {
+            text: string,
+            link: string
+        },
+        warn: {
+            text: string,
+            link: string
+        },
+        role: {
+            role: string
+        }
+    }
+    tracks: {
+        name: string,
+        retainPrevious: boolean,
+        nullable: boolean,
+        track: string[],
+        manageableBy: string[]
+    }[]
+    roleMenu: {
+        enabled: boolean,
+        allowWebUI: boolean,
+        options: {
+            name: string,
+            description: string,
+            min: number,
+            max: number,
+            options: {
+                name: string,
+                description: string,
+                role: string
+            }[]
+        }[]
+    }
+    tags: {}
+};
\ No newline at end of file
diff --git a/src/utils/memory.ts b/src/utils/memory.ts
index a4f9501..0cbf955 100644
--- a/src/utils/memory.ts
+++ b/src/utils/memory.ts
@@ -14,7 +14,7 @@
                 logging: guildData.logging,
                 tickets: guildData.tickets,
             }; // TODO: REMOVE GUILD FROM MEMORY WHEN THESE UPDATE
-        }
+        } // TODO: Add a "lastAccessed" prop, delete after 15 minutes
         return this.memory[guild];
     }
 }
diff --git a/src/utils/readConfig.ts b/src/utils/readConfig.ts
index 50cb6c6..b363fc0 100644
--- a/src/utils/readConfig.ts
+++ b/src/utils/readConfig.ts
@@ -1,165 +1,5 @@
+import client from './client.js';
 
 export default async function readConfig(guild: string): Promise<any> {
-
-    let config = {
-        singleEventNotifications: {
-            statsChannelDeleted: false
-        },
-        filters: {
-            images: {
-                NSFW: true,
-                size: true
-            },
-            malware: true,
-            wordFilter: {
-                enabled: true,
-                words: {
-                    strict: [],
-                    loose: []
-                },
-                allowed: {
-                    users: [],
-                    roles: [],
-                    channels: []
-                }
-            },
-            invite: {
-                enabled: false,
-                allowed: {
-                    users: [],
-                    channels: [],
-                    roles: []
-                }
-            },
-            pings: {
-                mass: 5,
-                everyone: true,
-                roles: true,
-                allowed: {
-                    roles: [],
-                    rolesToMention: [],
-                    users: [],
-                    channels: []
-                }
-            }
-        },
-        welcome: {
-            enabled: true,
-            verificationRequired: {
-                message: false,
-                role: false
-            },
-            welcomeRole: null,
-            channel: '895209752315961344', // null, channel ID or 'dm'
-            message: "Welcome to the server, {@}!"
-        },
-        stats: [
-            {
-                enabled: true,
-                channel: '951910554291818526',
-                text: "{count} members | {count:bots} bots | {count:humans} humans"
-            }
-        ],
-        logging: {
-            logs: {
-                enabled: true,
-                channel: '952247098437427260',
-                toLog: "3fffff" // "3ffffe" = - channelUpdate, "3fffff" = all
-            },
-            staff: {
-                channel: "895212366252367933"
-            }
-        },
-        verify: {
-            enabled: true,
-            role: '934941369137524816',
-        },
-        tickets: {
-            enabled: true,
-            category: "952302254302584932",
-            types: "3f",
-            customTypes: null,
-            supportRole: null,
-            maxTickets: 5
-        },
-        moderation: {
-            mute: {
-                timeout: true,
-                role: "934941369137524816", // TODO: Remove this role after the time
-                text: null,
-                link: null
-            },
-            kick: {
-                text: "Appeal here",
-                link: "https://clicks.codes"
-            },
-            ban: {
-                text: null,
-                link: null
-            },
-            softban: {
-                text: null,
-                link: null
-            },
-            warn: {
-                text: null,
-                link: null
-            },
-            role: {
-                role: "934941369137524816"
-            },
-        },
-        tracks: [
-            {
-                name: "Moderation",
-                retainPrevious: false,
-                nullable: true,
-                track: [
-                    "934941369137524816",
-                    "934941399806246984",
-                    "934941408849186856",
-                    "934941466734764092"
-                ],
-                manageableBy: []
-            },
-            {
-                name: "Verification",
-                retainPrevious: false,
-                nullable: true,
-                track: [
-                    "963166531318067250"
-                ],
-                manageableBy: []
-            }
-        ],
-        roleMenu: {
-            enabled: true,
-            allowWebUI: true,
-            options: [
-                {
-                    name: "Gender",
-                    description: "What's your gender?",
-                    min: 1,
-                    max: 1,
-                    options: [
-                        { name: "Male", role: "959901318019948574" },
-                        { name: "Female", role: "959901346000154674" },
-                        { name: "Non Binary", description: "Better than the others", role: "959901378363420704"}
-                    ]
-                },
-                {
-                    name: "Pick",
-                    min: 0,
-                    max: 4,
-                    options: [
-                        { name: "Test Role 1", role: "934941369137524816" },
-                        { name: "Test Role 2", role: "934941399806246984" },
-                        { name: "Test Role 3", role: "934941408849186856" },
-                        { name: "Test Role 4", role: "934941466734764092" }
-                    ]
-                }
-            ]
-        }
-    };
-    return config;
+    return await client.database.read(guild);
 }