Untitled

mail@pastecode.io avatar
unknown
python
a year ago
107 kB
2
Indexable
Never
import nextcord
from nextcord import SelectOption, TextInputStyle
from nextcord.ui import Select, View
import random
import datetime

# Local Classes
import apis

TOKEN = "MTEyODY5ODgxOTU4OTE4OTY0Mg.GWH7Nd.jaVYew8OesS52fLRQAm239kzXz49h_ewPpvj0c"

GuildID = 1089484031848095746  # Change this with your guild ID


intents = nextcord.Intents.default()
intents.message_content = True
bot = nextcord.Client(intents=intents)

colors = {
    "main": 0x50b7df,
    "error": 0x800000,
    "log": 0x50b7df
}

channelIDs = {
    "logs": 1090580658113478746,
    "applicationReview": 1126436493733404753,
    "postApprovers": 1126446209880555551,
    "posts": 1091086875072143370,
    "stage2Approvers": 1126442023952601098,
    "stage3Logs": 1126442153896329267
}

categoryIDs = {
    "tickets": {
        "building": 1090296932322254908,
        "scripting": 1090296932322254908,
        "modelling": 1090296932322254908,
        "other": 1090296932322254908,
        "support": 1090296932322254908,
        "claimed": 1090296933261791283,
        "closed": 1090296934234849340,
        "clientTickets": 1136710881854631946
    },
    "stage3": 1090296932322254908
}


roleIDs = {
    "Builder": 1090628596101558352,
    "GFX artist": 1089547945784918036,
    "VFX artist": 1089547964965462016,
    "SFX artist": 1089548002609332314,
    "Video Editing": 1089548274731593848,
    "Animator": 1089556519630155877,
    "Scripter": 1090629206670577664,
    "Modeller": 1089547787814838372,
    "Clothing": 1089553245090893886,
    "UI designer": 1089547909164437736,
    "Discord": 1089556541125963916,
    "postRole": 1090000777851965562,
    "development": 1090000777851965562,
    "stage1Role": 1089547394842107985,
    "stage2Role": 1089547433924636682,
    "stageHelpers": 1095075767534223522,
    "stage2": {
        "Builder": 1092438767345877032,
        "Scripter": 1092438862913097808,
        "Modeller": 1092438932395937822,
        "UI designer": 1092438978231291944,
        "SFX artist": 1092439033893892127,
        "GFX artist": 1089547945784918036,
        "Video Editing": 1092439222717251704,
        "Animator": 1092439271471841310,
        "Discord": 1092439358352662600,
        "VFX artist": 1092439066777235536,
        "Clothing": 1092439315960836106
    },
    "stage2Needed": {
        "Builder": 1092438767345877032,
        "Scripter": 1092438862913097808,
        "Modeller": 1092438932395937822,
        "UI designer": 1092438978231291944,
        "SFX artist": 1092439152085180577,
        "GFX artist": 1092439033893892127,
        "Video Editing": 1092439222717251704,
        "Animator": 1092439271471841310,
        "Discord": 1092439358352662600,
        "VFX artist": 1092439066777235536,
        "Clothing": 1092439315960836106
    },
    "applicationRoleIDs": {
        1092438767345877032: "Builder",
        1092438862913097808: "Scripter",
        1092438932395937822: "Modeller",
        1092438978231291944: "UI designer",
        1092439152085180577: "SFX artist",
        1092439033893892127: "GFX artist",
        1092439222717251704: "Video Editing",
        1092439271471841310: "Animator",
        1092439358352662600: "Discord",
        1092439066777235536: "VFX artist",
        1092439315960836106: "Clothing"
    },
    "tickets": {
        "building": {
            "inter": 1090628596101558352,
            "advanced": 1089547760346337403},
        "scripting": {
            "inter": 1089547879598788688,
            "advanced": 1090629206670577664},
        "modelling": 1089547787814838372,  # Check
        "other": [1089547909164437736,
                  1089547945784918036,
                  1089547964965462016,
                  1089548002609332314,
                  1089548274731593848,
                  1089556519630155877,
                  1089553245090893886,
                  1089556541125963916],
        "ticketPermissions": [
            1132055529737425047,
            1132055009341755504,
            1132055493838385253,
            1130122319847751840,]
    },
    "viewTickets": 1130122319847751840,
    "stage3Role": 1094281019735154830,
    "staff": 1095075767534223522,
    "owner": 1089484916040945735,
    "customer": 1089493536946270288,
    "stage3": {
        "paypal": 1090572010616275016,
        "robux": 1090572077855162439,
        "developer": 1090000777851965562
    },
    "stage1Application": 1089547394842107985
}

groupRankIDs = {
    "member": 1,
    "developer": 5
}

shirtLinks = {
    1: "https://www.roblox.com/catalog/13048570258/test",
    2: "https://www.roblox.com/catalog/12910793232/Payment",
    3: "https://www.roblox.com/catalog/10655012956/Payment"
}

shirtIDs = {
    1: 13048570258,
    2: 12910793232,
    3: 10655012956
}

paypalText = f"""
To process PayPal payments, please instruct the customer to remit 25% of the total amount to the Group's PayPal address, kaye.beaumont@hotmail.co.uk, using the Friends & Family option."

Do you understand this rule?
"""

robuxText = f"""
In regard to Robux payments, it is required that you possess a shirt within the group which shall serve as the basis for all your transactions. By doing so, a portion amounting to 25% of your earnings will be allocated to the group.

During the initial phase of this process, it is imperative that you establish a designated value for a particular shirt within the group.
"""
# Write an API call to the discord API

stage2References = {
    "Builder": [
        "https://www.juliettesinteriors.co.uk/wp-content/uploads/2022/07/modern-round-coffee-table-1.jpg",
        "https://www.tts-group.co.uk/on/demandware.static/-/Sites-TTSGroupE-commerceMaster/default/dwf7ebe2af/images/hi-res/1051796_08_FF45742.jpg",
        "https://cdn.ecommercedns.uk/files/8/212198/0/6754630/image.jpg"],
    "Modeller": [
        "https://npr.brightspotcdn.com/dims4/default/8b8744f/2147483647/strip/true/crop/1296x972+0+0/resize/880x660!/quality/90/?url=https%3A%2F%2Fnpr.brightspotcdn.com%2Fa1%2F13%2F51a9da3d40fdb9dcd1e8ffc2613b%2Fdeath-cap-susan-staci.jpeg",
        "https://m.media-amazon.com/images/I/71XfuQvhvhS.jpg",
        "https://i.ebayimg.com/images/g/UzYAAOSwRTViziQv/s-l1200.jpg"],
    "Scripter": [None, None, None],
    "UI designer": [
        "https://cdn.discordapp.com/attachments/1120681025127841812/1122545236397281390/915d0d15861cc35cc7591a4f70ce2907a74a4def-removebg-preview.png",
        "https://cdn.discordapp.com/attachments/1120681025127841812/1122545236787331072/maxresdefault__4_-removebg-preview.png"],
    "SFX artist": [
        "https://youtu.be/yasu55EWI_M"],
    "Video Editing": [
        "https://youtu.be/qaNiw_iDicw",
        "https://youtu.be/lvbPCkPIOL8"],
    "Animator": [
        "https://youtu.be/iCKBoDKQJBM",
        "https://youtu.be/SOp50Rbq5dg"],
    "Discord": [
        "https://discord.gg/VUaPm8UjgT",
        "https://discord.gg/sG5EdQuWny"
    ],
    "VFX artist": [
        "https://realtimevfx.com/uploads/default/original/2X/c/c6c3e3be9e249a495c79fd4dd6c2e3a268b83719.gif",
        "https://cdna.artstation.com/p/assets/images/images/040/235/598/original/dan-santos-2.gif?1628249936",
        "https://i.pinimg.com/originals/49/82/52/498252ef8ab1153807a102361b4a70c0.gif"],
    "GFX artist": [
        "https://www.roblox.com/users/470376608/profile",
        "https://thumbs.dreamstime.com/b/scary-mysterious-forest-swamp-misty-night-marshy-ancient-creepy-trees-dusk-fantasy-woodland-scenery-d-illustration-155268334.jpg",
        "https://devforum-uploads.s3.dualstack.us-east-2.amazonaws.com/uploads/original/4X/1/a/6/1a605ce8c325638da534fc34c50e15913ac9a7ef.png"],
    "Clothing": [
        "https://media.discordapp.net/attachments/1118255883533697127/1129761577466339379/214800584PAQzCvT.jpg?width=754&height=754",
        "https://media.discordapp.net/attachments/1118255883533697127/1129761577856413767/jsqwcxorxlofttnpnalqkgq4gioijmyd1fqusbiwcuhjhbli.jpeg.jpg?width=716&height=754",
        "https://media.discordapp.net/attachments/1118255883533697127/1129761578175189042/B1WWMAfTfHS._CLa_21402000_91XCIE8FJsL.png_00214020000.00.02140.02000.0_AC_SX425_.png"
    ]
}
stage2Tasks = {
    "Builder": [nextcord.Embed(
        title="Stage 2: Building",
        description=f'Your task is to build a [modern coffee table](https://www.juliettesinteriors.co.uk/wp-content/uploads/2022/07/modern-round-coffee-table-1.jpg).',
        color=colors["main"]
    ),
        nextcord.Embed(
        title="Stage 2: Building",
        description=f'Your task is to build a [wooden hut]( https://www.tts-group.co.uk/on/demandware.static/-/Sites-TTSGroupE-commerceMaster/default/dwf7ebe2af/images/hi-res/1051796_08_FF45742.jpg).',
        color=colors['main']
    ),
        nextcord.Embed(
        title="Stage 2: Building",
        description=f'Your task is to build a [remote control](https://cdn.ecommercedns.uk/files/8/212198/0/6754630/image.jpg).',
        color=colors['main'])
    ],
    "Scripter": [nextcord.Embed(
        title="Stage 2: Scripting",
        description=f"""
You should create objects that allow users to interact with them.
This should include doors and switches.""",
        color=colors["main"]
    ),
        nextcord.Embed(
        title="Stage 2: Scripting",
        description=f"""
Your task is to script a quest and mission system.
This should allow a user to ask an NPC what specific task needs to be fulfilled and when it is completed the NPC acknowledges it and/or the user is rewarded.""",
        color=colors['main']
    ),
        nextcord.Embed(
        title="Stage 2: Scripting",
        description=f"""
Your task is to script a weapon and combat system.
This should include a functioning health bar and a damage system.""",
        color=colors['main'])
    ],
    "Modeller": [nextcord.Embed(
        title="Stage 2: Modelling",
        description=f'Your task is to model a [mushroom](https://npr.brightspotcdn.com/dims4/default/8b8744f/2147483647/strip/true/crop/1296x972+0+0/resize/880x660!/quality/90/?url=https%3A%2F%2Fnpr.brightspotcdn.com%2Fa1%2F13%2F51a9da3d40fdb9dcd1e8ffc2613b%2Fdeath-cap-susan-staci.jpeg).',
        color=colors["main"]
    ),
        nextcord.Embed(
        title="Stage 2: Modelling",
        description=f'Your task is to model a [gaming chair](https://m.media-amazon.com/images/I/71XfuQvhvhS.jpg).',
        color=colors['main']
    ),
        nextcord.Embed(
        title="Stage 2: Modelling",
        description=f'Your task is to model a [bycicle](https://i.ebayimg.com/images/g/UzYAAOSwRTViziQv/s-l1200.jpg).',
        color=colors['main'])
    ],
    "UI designer": [nextcord.Embed(
        title="Stage 2: UI Design",
        description=f'Your task is to create a [coins GUI](https://cdn.discordapp.com/attachments/1120681025127841812/1122545236397281390/915d0d15861cc35cc7591a4f70ce2907a74a4def-removebg-preview.png).',
        color=colors["main"]
    ),
        nextcord.Embed(
        title="Stage 2: UI Design",
        description=f'Your task is to create a [shop GUI](https://cdn.discordapp.com/attachments/1120681025127841812/1122545236787331072/maxresdefault__4_-removebg-preview.png).',
        color=colors['main']
    ),
    ],
    "SFX artist": [nextcord.Embed(
        title="Stage 2: SFX Design",
        description=f'our task is to create a 1-minute [beat soundtrack](https://youtu.be/yasu55EWI_M).',
        color=colors["main"]
    ),
    ],
    "Video Editing": [nextcord.Embed(
        title="Stage 2: Video editing",
        description=f"""
Make a video based on the reference below.""",
        color=colors["main"]
    ),
        nextcord.Embed(
        title="Stage 2: Video editing",
        description=f"""
Make a video based on the reference below.""",
        color=colors['main']
    ),
        nextcord.Embed(
        title="Stage 2: Video editing",
        description=f"""
Make a video based on the reference below.""",
        color=colors['main']
    ),
    ],
    "Animator": [nextcord.Embed(
        title="Stage 2: Animation",
        description=f'Your task is to create a [death animation](https://youtu.be/iCKBoDKQJBM).',
        color=colors["main"]
    ),
        nextcord.Embed(
        title="Stage 2: Animation",
        description=f'Your task is to create a [sprinting animation](https://youtu.be/SOp50Rbq5dg).',
        color=colors['main']
    ),
    ],
    "Discord": [nextcord.Embed(
        title="Stage 2: Discord Server Creator",
        description=f"""
Your task is to create a military-related Discord Server.
This should have similar channels and roles to the reference shown.
[Reference](https://discord.gg/VUaPm8UjgT)""",
        color=colors["main"]
    ),
        nextcord.Embed(
        title="Stage 2: Discord Server Creator",
        description=f"""
Your task is to create a gaming-related Discord Server.
This should have similar channels and roles to the reference shown.
[Reference](https://discord.gg/sG5EdQuWny)""",
        color=colors['main']
    )
    ],
    "VFX artist": [nextcord.Embed(
        title="Stage 2: Video editing",
        description=f"""
Make a VFX based on the reference below""",
        color=colors["main"]
    ),
        nextcord.Embed(
        title="Stage 2: Video editing",
        description=f"""
Make a VFX based on the reference below""",
        color=colors['main']
    ),
        nextcord.Embed(
        title="Stage 2: Video editing",
        description=f"""
Make a VFX based on the reference below""",
        color=colors['main']
    ),
    ],
    "GFX artist": [nextcord.Embed(
        title="Stage 2: GFX",
        description=f"""
Make a GFX of your choosing with the avatar with the username "MaxTheGamer867""",
        color=colors["main"]
    ),
        nextcord.Embed(
        title="Stage 2: GFX",
        description=f"""
Make a creepy GFX with a misty atmosphere with swamplands.
[Reference](https://thumbs.dreamstime.com/b/scary-mysterious-forest-swamp-misty-night-marshy-ancient-creepy-trees-dusk-fantasy-woodland-scenery-d-illustration-155268334.jpg)""",
        color=colors['main']
    ),
        nextcord.Embed(
        title="Stage 2: GFX",
        description=f"""
Make a Space GFX that includes a rocket in the background and the Earth.
[Reference](https://devforum-uploads.s3.dualstack.us-east-2.amazonaws.com/uploads/original/4X/1/a/6/1a605ce8c325638da534fc34c50e15913ac9a7ef.png)""",
        color=colors['main']
    ),
    ],
    "Clothing": [
        nextcord.Embed(title="Stage 2: Clothing",
                       description="Make a piece of clothing similar to that of the reference below.", color=colors['main']),
        nextcord.Embed(title="Stage 2: Clothing",
                       description="Make a piece of clothing similar to that of the reference below.", color=colors['main']),
        nextcord.Embed(title="Stage 2: Clothing",
                       description="Make a piece of clothing similar to that of the reference below.", color=colors['main']),
    ]
}
editPostFields = {}
postTypeField = {}
GroupName = "Bright Productions"
GroupLink = "https://www.roblox.com/groups/15704617/Bright-Productions#!/about"
GroupID = 15704617
editContentMsg = """Double check your post before submitting. To edit later, use the `/post` command.

Complete all required fields (*). Add relevant details or information.
"""

stage1Text = """
INFORMATION:

Customers will join the Server and may require commissions to be completed. Please note that we only accept Robux through a group t-shirt sale and/or PayPal.

You should ensure that you remain professional when dealing with or communicating with Customers at all times. Additionally, please abide by Discord TOS and Bright Production Commission's Rules.

When a Customer is paying via Robux, it will always go through our group. You can then request a payout, and you will be paid via the group using Group Funds.

When a Customer is paying via PayPal, kindly ask them to send 25% of the payment you are receiving to kaye.beaumont@hotmail.co.uk.
"""


def generateRoleDropdown():
    options = []
    options.append(SelectOption(
        label="Builder", description="Apply to be a Builder", value="Builder"))
    options.append(SelectOption(
        label="Scripter", description="Apply to be a Scripter", value="Scripter"))
    options.append(SelectOption(
        label="Modeller", description="Apply to be a Modeller", value="Modeller"))
    options.append(SelectOption(
        label="UI", description="Apply to be a UI designer", value="UI designer"))
    options.append(SelectOption(
        label="GFX", description="Apply to be a GFX artist", value="GFX artist"))
    options.append(SelectOption(
        label="Animator", description="Apply to be an Animator", value="Animator"))
    options.append(SelectOption(
        label="VFX", description="Apply to be a VFX artist", value="VFX artist"))
    options.append(SelectOption(
        label="SFX", description="Apply to be a SFX artist", value="SFX artist"))
    options.append(SelectOption(
        label="Clothing", description="Apply to be a Clothing creator", value="Clothing"))
    options.append(SelectOption(
        label="Video Editing", description="Apply to be a Video Editor", value="Video Editing"))
    options.append(SelectOption(
        label="Discord Server Designer", description="Apply to be a Discord Server Designer", value="Discord"))
    return options


@ bot.event
async def on_ready():
    print(f"{bot.user} is now online!")


@ bot.event
async def on_message(message):
    if not message.author.bot:
        if message.author.id == 513062533687672854 and message.content == "Cheers!":
            guild = bot.get_guild(GuildID)
            channel = guild.get_channel(int(message.channel.id))
            await channel.send("https://flxt.tmsimg.com/assets/p183897_b_v8_ak.jpg")
        if isinstance(message.channel, nextcord.DMChannel):
            pass
        elif isinstance(message.channel, nextcord.TextChannel):
            if message.channel.category is not None:
                ticketsCategory = categoryIDs['tickets']
                if int(message.channel.category.id) in ticketsCategory.values():
                    if not int(message.channel.category.id) == ticketsCategory['closed']:
                        channel = message.channel
                        embed = nextcord.Embed(
                            title="Message Sent!", description=message.content, color=colors['main'])
                        await channel.send(embed=embed)
                        otherChannelID = channel.topic
                        guild = bot.get_guild(GuildID)
                        channel = guild.get_channel(int(otherChannelID))
                        embed = nextcord.Embed(
                            title="Message Received!", description=message.content, color=colors['main'])
                        await channel.send(embed=embed)


class applyButtons(nextcord.ui.View):
    def __init__(self):
        super().__init__(timeout=5 * 60)
        self.value = None

    @ nextcord.ui.button(label="Apply", style=nextcord.ButtonStyle.green)
    async def newpost(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        self.value = 1
        self.stop()


class roleDeniedModal(nextcord.ui.Modal):
    def __init__(self, user, roleName, message):
        self.user = user
        self.roleName = roleName
        self.message = message

        super().__init__(
            "Role Denied.",
            timeout=5 * 60,
        )
        self.reason = nextcord.ui.TextInput(
            label="Reason for denying",
            placeholder="Provide a detailed reason for denying the post.",
            required=True,
            min_length=1,
            max_length=4000,
            style=TextInputStyle.paragraph
        )

        self.add_item(self.reason)

    async def callback(self, interaction: nextcord.Interaction) -> None:
        messageToDelete = await interaction.response.send_message(content=".", ephemeral=True)
        embed = nextcord.Embed(
            title="Stage 1 FAILED", description=f"""
The user <@{self.user.id}> has been denied for the role `{self.roleName}` by <@{interaction.user.id}>

Reason: `{self.reason.value}`""", color=colors['error'])
        guild = bot.get_guild(GuildID)
        logsChannel = guild.get_channel(channelIDs['logs'])
        await logsChannel.send(embed=embed, view=None)
        await self.message.delete()

        embed = nextcord.Embed(
            title="Role application denied",
            description=f"You have been denied for the role `{self.roleName}` for the reason `{self.reason.value}` by <@{interaction.user.id}>", color=colors['error'])
        try:
            await self.user.send(embed=embed, view=None)
            await messageToDelete.delete()
        except:
            await messageToDelete.edit(content="User has their DM's turned off.")


class roleReviewButtons(nextcord.ui.View):
    def __init__(self, user, roleName, message):
        super().__init__(timeout=None)
        self.value = None
        self.user = user
        self.roleName = roleName
        self.message = message

    @ nextcord.ui.button(label="Accept", style=nextcord.ButtonStyle.green)
    async def approve(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        embed = nextcord.Embed(title=f"Application Accepted",
                               description=f'You are now welcome to proceed to the commands channel where you can utilize the command "/stage1" in order to progress with your application.', color=colors['main'])
        try:
            await self.user.send(embed=embed, view=None)
        except:
            await interaction.response.send_message(content="User has their DM's turned off.", ephemeral=True)
        guild = bot.get_guild(GuildID)
        logsChannel = guild.get_channel(channelIDs['logs'])
        embed = nextcord.Embed(
            title="Stage 1 PASSED", description=f"The user <@{self.user.id}> has been approved for the role `{self.roleName}` by <@{interaction.user.id}>", color=colors['log'])
        await logsChannel.send(embed=embed, view=None)
        await self.message.delete()
        roles = roleIDs['stage2Needed']
        roleToAdd = guild.get_role(roles[self.roleName])

        await self.user.add_roles(roleToAdd)

        roleID = roleIDs['stage1Application']
        role = guild.get_role(roleID)
        await self.user.add_roles(role)
        self.stop()

    @ nextcord.ui.button(label="Deny", style=nextcord.ButtonStyle.red)
    async def deny(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        modal = roleDeniedModal(self.user, self.roleName, self.message)
        await interaction.response.send_modal(modal=modal)


class groupDoneButton(nextcord.ui.View):
    def __init__(self, response, message):
        super().__init__(timeout=10 * 60)
        self.value = None
        self.response = response
        self.message = message

    @ nextcord.ui.button(label="Done", style=nextcord.ButtonStyle.green)
    async def done(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        response = self.response
        robloxID = response['robloxID']
        rolesApplying = response['role']
        if apis.isGroupMember(robloxID):
            embed = nextcord.Embed(title="Application Submitted!",
                                   description="Your application is being reviewed, please wait for a response from a staff member.", color=colors['main'])
            await self.message.edit(embed=embed, view=None)

            guild = bot.get_guild(GuildID)
            channel = guild.get_channel(
                channelIDs['applicationReview'])

            for role in rolesApplying:
                message = await channel.send(content="Loading post", view=None)
                embed = nextcord.Embed(title=f"Stage 1 application for {role}", description=f"""
The user `{interaction.user.id}` has posted an application for stage 1 with the responses:

Roblox Username: `{response['robloxUsername']}`
Discord Username: `{interaction.user}`
Activity: `{response['activity']}`
Age: `{response['age']}`
""", color=colors['log'])
                embed.add_field(name="Past work", value=response['pastWork'])
                try:
                    embed.set_author(name=interaction.user.name,
                                     icon_url=interaction.user.avatar.url)
                except:
                    pass

                view = roleReviewButtons(
                    interaction.user, role, message)
                await message.edit(content=None, embed=embed, view=view)

                await interaction.user.edit(nick=response['robloxUsername'])
        else:
            embed = nextcord.Embed(title="You are not in the group",
                                   description=f"Please join the [Roblox group]({GroupLink}) with the account you have specified earlier to proceed.", color=colors['error'])
            await interaction.response.send_message(embed=embed, ephemeral=True)


class trueAndFalse(nextcord.ui.View):
    def __init__(self):
        super().__init__(timeout=5 * 60)
        self.value = None

    @ nextcord.ui.button(label="Yes", style=nextcord.ButtonStyle.green)
    async def yes(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        self.value = 1
        self.stop()

    @ nextcord.ui.button(label="No", style=nextcord.ButtonStyle.red)
    async def no(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        self.value = 2
        self.stop()


class pastWorkTrueAndFalse(nextcord.ui.View):
    def __init__(self, dictToSend, message):
        super().__init__(timeout=5 * 60)
        self.value = None
        self.dictToSend = dictToSend
        self.message = message

    @ nextcord.ui.button(label="Yes", style=nextcord.ButtonStyle.green)
    async def yes(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        modal = pastWorkModal(self.dictToSend, self.message)
        await interaction.response.send_modal(modal=modal)

    @ nextcord.ui.button(label="No", style=nextcord.ButtonStyle.red)
    async def no(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        embed = nextcord.Embed(
            title="You have failed", description="You have failed this application. Sorry!", color=colors['error'])
        await self.message.edit(embed=embed, view=None)


class groupButton(nextcord.ui.View):
    def __init__(self, response, message):
        super().__init__()
        self.value = None
        self.response = response
        self.message = message

    @ nextcord.ui.button(label="Yes", style=nextcord.ButtonStyle.green)
    async def yes(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        response = self.response
        robloxID = response['robloxID']
        rolesApplying = response['role']

        if apis.isGroupMember(robloxID):
            embed = nextcord.Embed(title="Application being reviewed",
                                   description="Your application is being reviewed, please wait for a response from a staff member.", color=colors['main'])
            await self.message.edit(embed=embed, view=None)

            guild = bot.get_guild(GuildID)
            channel = guild.get_channel(
                channelIDs['applicationReview'])

            for role in rolesApplying:
                message = await channel.send(content="Loading post", view=None)
                embed = nextcord.Embed(title=f"Stage 1 application for {role}", description=f"""
The user `{interaction.user.id}` has posted an application for stage 1 with the responses:

Roblox Username: `{response['robloxUsername']}`
Discord Username: `{interaction.user}`
Activity: `{response['activity']}`
Age: `{response['age']}`
""", color=colors['log'])
                embed.add_field(name="Past work", value=response['pastWork'])
                try:
                    embed.set_author(name=interaction.user.name,
                                     icon_url=interaction.user.avatar.url)
                except:
                    pass

                view = roleReviewButtons(
                    interaction.user, role, message)
                await message.edit(content=None, embed=embed, view=view)

            await interaction.user.edit(nick=response['robloxUsername'])
        else:
            embed = nextcord.Embed(title="You are not in the group",
                                   description=f"Please join the [Roblox group]({GroupLink}) with the account you have specified earlier to proceed.", color=colors['error'])
            await interaction.response.send_message(embed=embed, ephemeral=True)

    @ nextcord.ui.button(label="No", style=nextcord.ButtonStyle.red)
    async def no(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        embed = nextcord.Embed(title="Please join the group",
                               description=f"Please join the group using [this link]({GroupLink}) and once done click the button below.", color=colors['main'])
        view = groupDoneButton(self.response, self.message)
        await self.message.edit(embed=embed, view=view)


class pastWorkModal(nextcord.ui.Modal):
    def __init__(self, response, message):
        self.response = response
        self.message = message
        super().__init__(
            "Past work.",
            timeout=5 * 60,
        )
        self.pastworkfield = nextcord.ui.TextInput(
            label="Links to past work seperated by a new line",
            placeholder="Based on what role you are applying for.",
            required=True,
            min_length=1,
            max_length=4000,
            style=TextInputStyle.paragraph
        )

        self.add_item(self.pastworkfield)

    async def callback(self, interaction: nextcord.Interaction) -> None:
        pastWorkValue = self.pastworkfield.value
        links = pastWorkValue.splitlines()
        if len(links) > 6:
            embed = nextcord.Embed(title="Too many links provided",
                                   description="Please provide 6 or less links.",
                                   color=colors['error'])
            await self.message.edit(embed=embed)
        else:
            stringToSend = ""
            for link in links:
                currentString = f"[Link]({link}) "
                stringToSend = stringToSend + currentString
            embed = nextcord.Embed(
                title="Are you in the group?", description=f"Are you in the group called [{GroupName}]({GroupLink})!", color=colors['main'])
            response = self.response
            response['pastWork'] = stringToSend
            view = groupButton(response, self.message)
            await self.message.edit(embed=embed, view=view)


class rolesModal(nextcord.ui.Modal):
    def __init__(self, user, message, role):
        self.user = user
        self.message = message
        self.role = role
        super().__init__(
            "Apply for a role.",
            timeout=5 * 60,
        )
        self.robloxfield = nextcord.ui.TextInput(
            label="Roblox Username",
            placeholder="Ex Roblox",
            required=True,
            min_length=3,
            max_length=20,
        )
        self.activity = nextcord.ui.TextInput(
            label="How active are you on Discord, 1-10?",
            placeholder="One number ex 8",
            required=True,
            min_length=1,
            max_length=256,
        )
        self.age = nextcord.ui.TextInput(
            label="What is your age?",
            placeholder="One number ex 15",
            required=True,
            min_length=1,
            max_length=256,
        )
        self.add_item(self.robloxfield)
        self.add_item(self.activity)
        self.add_item(self.age)

    async def callback(self, interaction: nextcord.Interaction) -> None:
        guild = bot.get_guild(GuildID)
        logsChannel = guild.get_channel(channelIDs['logs'])
        robloxUsername = self.robloxfield.value
        discordUsername = interaction.user
        activity = self.activity.value
        age = self.age.value
        robloxID = apis.getID(robloxUsername)
        if not activity.isdigit():
            embed = nextcord.Embed(
                title="Invalid Field", description="Please provide a valid activity with no other charachters.", color=colors['error'])
            await self.message.edit(embed=embed)

        elif not age.isdigit():
            embed = nextcord.Embed(
                title="Invalid Field", description="Please provide a valid age number with no other charachters.", color=colors['error'])
            await self.message.edit(embed=embed)

        elif not type(robloxUsername) == str:
            embed = nextcord.Embed(
                title="Invalid Field", description="Please provide a valid Roblox username with no other charachters.", color=colors['error'])
            await self.message.edit(embed=embed)

        else:
            if int(age) < 13:
                embed = nextcord.Embed(
                    title="Underaged", description="You are under the age to apply. Sorry and try again next time.", color=colors['error'])
                await self.message.edit(embed=embed)
                embed = nextcord.Embed(
                    title="Underaged Log", description=f"The user: `{interaction.user.id}` has found to be underaged in his application.", color=colors['log'])
                await logsChannel.send(embed=embed)
            elif int(activity) < 6:
                embed = nextcord.Embed(
                    title="Application failed", description="You have failed the application due to being inactive.", color=colors['error'])
                await self.message.edit(embed=embed)

            elif int(activity) > 10 or int(age) > 100:
                embed = nextcord.Embed(
                    title="Invalid Field", description="Please provide a valid age.", color=colors['error'])
                await self.message.edit(embed=embed)
            else:
                if robloxID:
                    messageToDelete = await interaction.response.send_message(content=".", ephemeral=True)
                    await messageToDelete.delete()
                    embed = nextcord.Embed(
                        title="Stage 1", description="Are you fluent in English?", color=colors['main'])
                    view = trueAndFalse()

                    await self.message.edit(embed=embed, view=view)
                    await view.wait()

                    if view.value == 2:
                        embed = nextcord.Embed(
                            title="You have failed", description="You have failed this application. Sorry!", color=colors['error'])
                        await self.message.edit(embed=embed, view=None)

                    else:
                        embed = nextcord.Embed(
                            title="Stage 1", description="Do you have past work/projects or a portfolio?", color=colors['main'])
                        dictToSend = {
                            'robloxUsername': robloxUsername,
                            'activity': activity,
                            'age': age,
                            'robloxID': robloxID,
                            'role': self.role
                        }
                        view = pastWorkTrueAndFalse(dictToSend, self.message)
                        await self.message.edit(embed=embed, view=view)

                else:
                    embed = nextcord.Embed(
                        title="Invalid Field", description="Please provide a valid Roblox username.", color=colors['error'])
                    await self.message.edit(embed=embed)


@bot.slash_command(guild_ids=[GuildID], description="❓ ・Begin your application to join our Development Team. ")
async def apply(interaction: nextcord.Interaction):
    message = None

    async def roleCallback(cbinteraction):
        listToSend = []
        for value in roleDropdown.values:
            listToSend.append(value)
        modal = rolesModal(interaction.user, message, listToSend)
        await cbinteraction.response.send_modal(modal=modal)
    options = generateRoleDropdown()
    roleDropdown = Select(
        placeholder="What role are you applying for?", options=options, max_values=8)
    roleDropdown.callback = roleCallback
    view = View(timeout=300)
    view.add_item(roleDropdown)
    embed = nextcord.Embed(title="Apply for a role",
                           description="You are now applying for a role, please answer the following questions.", color=colors['main'])
    message = await interaction.response.send_message(embed=embed, view=view, ephemeral=True)


def ticketDropdownOptions():
    options = []
    ticketOption1 = SelectOption(
        label="Building", description="For building services", value=1)
    ticketOption2 = SelectOption(
        label="Scripting", description="For scripting services", value=2)
    ticketOption3 = SelectOption(
        label="Modelling", description="For modelling services", value=3)
    ticketOption4 = SelectOption(
        label="Support", description="For moderator support", value=5)
    ticketOption5 = SelectOption(
        label="Other", description="For other services", value=4)

    options.append(ticketOption1)
    options.append(ticketOption2)
    options.append(ticketOption3)
    options.append(ticketOption4)
    options.append(ticketOption5)
    return options


class ticketButtons(nextcord.ui.View):
    def __init__(self, ticketOwner, message, channel):
        super().__init__(timeout=None)
        self.value = None
        self.owner = ticketOwner
        self.message = message
        self.channel = channel

    emoji = nextcord.PartialEmoji(name="🎟️")

    @ nextcord.ui.button(label="Claim", style=nextcord.ButtonStyle.blurple, emoji=emoji)
    async def claim(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        userRoles = interaction.user.roles
        roleFound = False
        guild = bot.get_guild(GuildID)
        developmentRole = guild.get_role(roleIDs['development'])
        if developmentRole in userRoles:
            roleFound = True
        ticketRoles = roleIDs['tickets']
        for ticketPermissionRoleID in ticketRoles['ticketPermissions']:
            role = guild.get_role(ticketPermissionRoleID)
            if role in userRoles:
                roleFound = True
                break

        if roleFound:
            embed = nextcord.Embed(
                title=f"Ticket has been claimed", description=f"This ticket has been claimed by <@{interaction.user.id}>", color=colors['main'])
            await interaction.response.send_message(embed=embed, ephemeral=False)
            button.disabled = True
            await self.message.edit(view=self)
            guild = bot.get_guild(GuildID)
            ticketsChannels = categoryIDs['tickets']
            category = guild.get_channel(ticketsChannels['claimed'])
            await self.channel.edit(name=self.channel.name + " " + interaction.user.name, category=category)
        else:
            embed = nextcord.Embed(
                title="You do not have permission to do this action.", color=colors['error'])
            await interaction.response.send_message(embed=embed, ephemeral=True)

    emoji = nextcord.PartialEmoji(name="πŸ”’")

    @ nextcord.ui.button(label="Close", style=nextcord.ButtonStyle.grey, emoji=emoji)
    async def close(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        userRoles = interaction.user.roles
        roleFound = False
        guild = bot.get_guild(GuildID)
        developmentRole = guild.get_role(roleIDs['development'])
        if developmentRole in userRoles:
            roleFound = True
        ticketRoles = roleIDs['tickets']
        for ticketPermissionRoleID in ticketRoles['ticketPermissions']:
            role = guild.get_role(ticketPermissionRoleID)
            if role in userRoles:
                roleFound = True
                break

        if roleFound:
            for child in self.children:
                if type(child) == nextcord.ui.Button and child.label == "Re-open":
                    button.disabled = True
                    child.disabled = False
                    await self.message.edit(view=self)
                    guild = bot.get_guild(GuildID)
                    ticketsChannels = categoryIDs['tickets']
                    category = guild.get_channel(ticketsChannels['closed'])
                    await self.channel.edit(category=category)
                    embed = nextcord.Embed(
                        title="Ticket has been closed", description=f"The ticket has been closed by <@{interaction.user.id}>.", color=colors['main'])
                    await self.channel.send(embed=embed)
                    break
        else:
            embed = nextcord.Embed(
                title="You do not have permission to do this action.", color=colors['error'])
            await interaction.response.send_message(embed=embed, ephemeral=True)

    emoji = nextcord.PartialEmoji(name="πŸ”“")

    @ nextcord.ui.button(label="Re-open", style=nextcord.ButtonStyle.green, disabled=True, emoji=emoji)
    async def reopen(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        userRoles = interaction.user.roles
        roleFound = False
        guild = bot.get_guild(GuildID)
        developmentRole = guild.get_role(roleIDs['development'])
        if developmentRole in userRoles:
            roleFound = True
        ticketRoles = roleIDs['tickets']
        for ticketPermissionRoleID in ticketRoles['ticketPermissions']:
            role = guild.get_role(ticketPermissionRoleID)
            if role in userRoles:
                roleFound = True
                break

        if roleFound:
            for child in self.children:
                if type(child) == nextcord.ui.Button and child.label == "Close":
                    button.disabled = True
                    child.disabled = False
                    await self.message.edit(view=self)
                    guild = bot.get_guild(GuildID)
                    ticketsChannels = categoryIDs['tickets']
                    category = guild.get_channel(ticketsChannels['claimed'])
                    await self.channel.edit(category=category)
                    embed = nextcord.Embed(title="Ticket has been re-opened",
                                           description=f"The ticket has been re-opened by <@{interaction.user.id}>.", color=colors['main'])
                    await self.channel.send(embed=embed)
                    break
        else:
            embed = nextcord.Embed(
                title="You do not have permission to do this action.", color=colors['error'])
            await interaction.response.send_message(embed=embed, ephemeral=True)

    emoji = nextcord.PartialEmoji(name="πŸ—‘οΈ")

    @ nextcord.ui.button(label="Delete", style=nextcord.ButtonStyle.red, disabled=False, emoji=emoji)
    async def delete(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        role = roleIDs['owner']
        if interaction.user.get_role(role):
            await self.channel.delete()
        else:
            embed = nextcord.Embed(
                title="You do not have permission to delete tickets.", color=colors['error'])
            await interaction.response.send_message(embed=embed, ephemeral=True)


class ticketModal(nextcord.ui.Modal):
    def __init__(self, user, value, message, username):
        self.user = user
        self.value = value
        self.message = message
        self.username = username

        super().__init__(
            "Ticket Format.",
            timeout=10 * 60,
        )
        self.need = nextcord.ui.TextInput(
            label="What do you need",
            placeholder="What are the features that you are looking for?.",
            required=True,
            min_length=1,
            max_length=100,
            style=TextInputStyle.short
        )

        self.preference = nextcord.ui.TextInput(
            label="What is your developer preference?",
            placeholder="If you do not have one say N/A.",
            required=True,
            min_length=1,
            max_length=100,
            style=TextInputStyle.short
        )

        self.references = nextcord.ui.TextInput(
            label="Reference Image",
            placeholder="Please provide reference images in the form of links.",
            required=True,
            min_length=1,
            max_length=3000,
            style=TextInputStyle.paragraph
        )
        self.budget = nextcord.ui.TextInput(
            label="Budget",
            placeholder="What is your budget.",
            required=True,
            min_length=1,
            max_length=100,
            style=TextInputStyle.short
        )

        self.paymentMethod = nextcord.ui.TextInput(
            label="Payment Method",
            placeholder="What is your payment method ex PayPal.",
            required=True,
            min_length=1,
            max_length=100,
            style=TextInputStyle.short
        )
        self.add_item(self.need)
        self.add_item(self.preference)
        self.add_item(self.references)
        self.add_item(self.budget)
        self.add_item(self.paymentMethod)

    async def callback(self, interaction: nextcord.Interaction):
        messageToDelete = await interaction.response.send_message(content="Enjoy!")
        value = self.value
        user = self.user
        username = self.username
        message = self.message
        guild = bot.get_guild(GuildID)
        tickets = categoryIDs['tickets']
        ticketRoles = roleIDs['tickets']
        staffRole = roleIDs['staff']
        viewTicketRoleID = roleIDs['viewTickets']
        viewTicketRole = guild.get_role(viewTicketRoleID)
        staffRole = guild.get_role(staffRole)
        channelID = 0
        developerOverwrites = {
            guild.default_role: nextcord.PermissionOverwrite(view_channel=False),
            staffRole: nextcord.PermissionOverwrite(view_channel=True),
            viewTicketRole: nextcord.PermissionOverwrite(view_channel=True)
        }
        clientOverwrites = {
            guild.default_role: nextcord.PermissionOverwrite(view_channel=False),
            interaction.user: nextcord.PermissionOverwrite(view_channel=True),
            staffRole: nextcord.PermissionOverwrite(view_channel=True),
        }
        categoryID = tickets['clientTickets']
        clientCategory = guild.get_channel(categoryID)
        clientChannel = await clientCategory.create_text_channel(name=f"{interaction.user.name}", overwrites=clientOverwrites)

        referencesText = ""
        splittedReferences = self.references.value.splitlines()
        for item in splittedReferences:
            referencesText += f"[Link]({item}) "

        embed = nextcord.Embed(
            title="Format", description=f"""
Username: {username}            
Needs: {self.need.value}            
Developer Preference: {self.preference.value}            
References: {referencesText}            
Budget: {self.budget.value}             
Payment Method: {self.paymentMethod.value}            
            
            """, color=colors['main'])
        embeds = [embed]
        userID = apis.getID(username)
        if userID:
            avatar = apis.avatar(userID)
            embed.set_thumbnail(url=avatar)
        await clientChannel.send(embed=embed)
        if value == 1:
            buildingRoles = ticketRoles['building']
            role = guild.get_role(buildingRoles['inter'])
            developerOverwrites[role] = nextcord.PermissionOverwrite(
                view_channel=True)
            role = guild.get_role(buildingRoles['advanced'])
            developerOverwrites[role] = nextcord.PermissionOverwrite(
                view_channel=True)
            categoryID = tickets['building']
            category = guild.get_channel(categoryID)
            channel = await category.create_text_channel(name=f"Building - None", overwrites=developerOverwrites)
            await channel.edit(name=channel.name, topic=clientChannel.id)
            await clientChannel.edit(name=clientChannel.name, topic=channel.id)
            clientChannel.name = channel.id
            embed = nextcord.Embed(
                title="Ticket", description=f"This ticket has been opened by an anonomous user", color=colors['main'])
            channelMessage = await channel.send(embed=embed)
            view = ticketButtons(interaction.user, channelMessage, channel)
            await channelMessage.edit(embed=embed, view=view)
            await channel.send(embeds=embeds)
            channelID = channel.id
        elif value == 2:
            scriptingRoles = ticketRoles['scripting']
            role = guild.get_role(scriptingRoles['inter'])
            developerOverwrites[role] = nextcord.PermissionOverwrite(
                view_channel=True)
            role = guild.get_role(scriptingRoles['advanced'])
            developerOverwrites[role] = nextcord.PermissionOverwrite(
                view_channel=True)
            categoryID = tickets['scripting']
            category = guild.get_channel(categoryID)
            channel = await category.create_text_channel(name=f"Scripting - None", overwrites=developerOverwrites)
            await channel.edit(name=channel.name, topic=clientChannel.id)
            await clientChannel.edit(name=clientChannel.name, topic=channel.id)
            clientChannel.name = channel.id
            embed = nextcord.Embed(
                title="Ticket", description=f"This ticket has been opened by an anonomous user", color=colors['main'])
            channelMessage = await channel.send(embed=embed)
            view = ticketButtons(interaction.user, channelMessage, channel)
            await channelMessage.edit(embed=embed, view=view)
            await channel.send(embeds=embeds)
            channelID = channel.id
        elif value == 3:
            roleID = ticketRoles['modelling']
            role = guild.get_role(roleID)
            developerOverwrites[role] = nextcord.PermissionOverwrite(
                view_channel=True)
            categoryID = tickets['modelling']
            category = guild.get_channel(categoryID)
            channel = await category.create_text_channel(name=f"Modelling - None", overwrites=developerOverwrites)
            await channel.edit(name=channel.name, topic=clientChannel.id)
            await clientChannel.edit(name=clientChannel.name, topic=channel.id)
            clientChannel.name = channel.id
            embed = nextcord.Embed(
                title="Ticket", description=f"This ticket has been opened by an anonomous user", color=colors['main'])
            channelMessage = await channel.send(embed=embed)
            view = ticketButtons(interaction.user, channelMessage, channel)
            await channelMessage.edit(embed=embed, view=view)
            await channel.send(embeds=embeds)
            channelID = channel.id
        elif value == 4:
            otherRoleIDs = ticketRoles['other']
            for item in otherRoleIDs:
                role = guild.get_role(item)
                developerOverwrites[role] = nextcord.PermissionOverwrite(
                    view_channel=True)
            categoryID = tickets['other']
            category = guild.get_channel(categoryID)
            channel = await category.create_text_channel(name=f"Other - None", overwrites=developerOverwrites)
            await channel.edit(name=channel.name, topic=clientChannel.id)
            await clientChannel.edit(name=clientChannel.name, topic=channel.id)
            clientChannel.name = channel.id
            embed = nextcord.Embed(
                title="Ticket", description=f"This ticket has been opened by an anonomous user", color=colors['main'])
            channelMessage = await channel.send(embed=embed)
            view = ticketButtons(interaction.user, channelMessage, channel)
            await channelMessage.edit(embed=embed, view=view)
            await channel.send(embeds=embeds)
            channelID = channel.id
        elif value == 5:
            categoryID = tickets['support']
            category = guild.get_channel(categoryID)
            channel = await category.create_text_channel(name=f"Support - None", overwrites=developerOverwrites)
            await channel.edit(name=channel.name, topic=clientChannel.id)
            await clientChannel.edit(name=clientChannel.name, topic=channel.id)
            embed = nextcord.Embed(
                title="Ticket", description=f"This ticket has been opened by an anonomous user", color=colors['main'])
            channelMessage = await channel.send(embed=embed)
            view = ticketButtons(interaction.user, channelMessage, channel)
            await channelMessage.edit(embed=embed, view=view)
            await channel.send(embeds=embeds)
            channelID = channel.id
        clientChannel.topic = channelID
        embed = nextcord.Embed(
            title="Ticket", description=f"Your ticket has been created <#{clientChannel.id}>", color=colors['main'])
        await message.edit(embed=embed, view=None)
        messageToDelete.delete()

@ bot.slash_command(guild_ids=[GuildID], description="🎟️ ・For Developer or Moderation Team assistance, use this command.")
async def ticket(interaction: nextcord.Interaction, username: str):
    message = None

    async def ticketCallback(cbinteraction):
        for value in ticketDropdown.values:
            value = int(value)
            modal = ticketModal(interaction.user, value, message, username)
            await cbinteraction.response.send_modal(modal=modal)

    view = View()
    options = ticketDropdownOptions()
    ticketDropdown = Select(
        placeholder="What kind of ticket would you like to open?", options=options, max_values=1)
    ticketDropdown.callback = ticketCallback
    view.add_item(ticketDropdown)
    embed = nextcord.Embed(
        title="Ticket", description="Open a ticket", color=colors['main'])
    message = await interaction.response.send_message(embed=embed, view=view, ephemeral=True)


# POST COMMAND
"""
ALL THE CODE BELOW BELONGS TO THE POST COMMAND
"""

# Other Commands

# OTHER FUNCTIONS


def allFieldsFilled(userID):
    failed = False
    userField = editPostFields[userID]
    field = userField['postinfo']
    if not 'title' in field and not 'description' in field:
        failed = True
     # Payment
    userField = editPostFields[userID]
    field = userField['paymentinfo']
    if not 'robux' in field and not 'usd' in field:
        failed = True
    # Payment Type
    if not userField['paymentType']:
        failed = True
    # Misc Info
    field = userField['miscInfo']
    if not "portofolio" in field:
        failed = True

    return failed


def generateEmbed(user):
    embed = nextcord.Embed()
    userID = user.id
    if not editPostFields[userID]['postinfo']:
        embed = nextcord.Embed(
            title="*Your Title Here*", description="No description Provided")
    else:
        userField = editPostFields[userID]
        field = userField['postinfo']
        if 'title' in field and 'description' in field:
            embed = nextcord.Embed(title=field['title'],
                                   description=field['description'])
    # Payment
    userField = editPostFields[userID]
    field = userField['paymentinfo']
    embed.add_field(name="Payment", value="*Nothing Provided*")
    if 'robux' in field and 'usd' in field:
        embed.set_field_at(index=0, name="Payment",
                           value=f"""
**Robux: ** {field['robux']}
**USD: ** {field['usd']}""")

    elif 'robux' in field:
        embed.set_field_at(index=0, name="Payment",
                           value=f"""
**Robux: ** {field['robux']}""")

    elif 'usd' in field:
        embed.set_field_at(index=0, name="Payment",
                           value=f"""
**USD: ** {field['usd']}""")
    if 'robux' in field or 'usd' in field:
        robuxValue = None
        if 'robux' in field:
            embed.set_field_at(index=0, name="Payment",
                               value=f"**Robux** {field['robux']}")
            robuxValue = field['robux']
        if 'usd' in field:
            if robuxValue:
                embed.set_field_at(index=0, name="Payment",
                                   value=f"""
**Robux: ** {robuxValue}
**USD: ** {field['usd']}""")

    # Payment Type
    if userField['paymentType']:
        embed.add_field(name="Payment Type", value=userField['paymentType'])
    else:
        embed.add_field(name="Payment Type", value="None Provided")

    # Misc Info
    field = userField['miscInfo']
    if "portofolio" in field:
        currentField = field['portofolio']
        embed.add_field(name="Portofolio",
                        value=f"[{currentField['text']}]({currentField['value']})", inline=False)
    else:
        embed.add_field(name="Portofolio",
                        value="Nothing Provided", inline=False)
    if "pastWork" in field:
        embed.add_field(name="Past Work",
                        value=f"{field['pastWork']}", inline=False)
    else:
        embed.add_field(name="Past Work",
                        value="Nothing Provided", inline=False)

    embed.add_field(name="Posted By",
                    value=f"<@{userID}>")

    try:
        embed.set_author(name=user.name, icon_url=user.avatar.url)
    except:
        pass
    embed.color = colors['main']
    return embed


def getPostInfo(userID):
    title = None
    desc = None
    imageurl = None
    thumburl = None

    embed = nextcord.Embed()
    userField = editPostFields[userID]
    field = userField['postinfo']
    if 'title' in field and 'description' in field:
        title = field['title']
        desc = field['description']
    try:
        if field['imageurl']:
            embed.set_image(url=field['imageurl'])
            imageurl = field['imageurl']
    except:
        pass
    try:
        if field['thumbnailurl']:
            embed.set_thumbnail(url=field['thumbnailurl'])
            thumburl = field['thumbnailurl']
    except:
        pass
    return {"title": title, "desc": desc, "imageurl": imageurl, "thumburl": thumburl}


def generateAllRolesDropdown():
    options = []
    option = SelectOption(label="Scripter", value=1,
                          description="For scripting jobs")
    options.append(option)

    option = SelectOption(label="Programmer", value=2,
                          description="For programming jobs")
    options.append(option)
    option = SelectOption(label="Builder", value=3,
                          description="For building jobs")
    options.append(option)
    option = SelectOption(label="Modeler", value=4,
                          description="For modeling jobs")
    options.append(option)
    option = SelectOption(label="UI Design", value=5,
                          description="For graphic jobs")
    options.append(option)
    option = SelectOption(label="Graphics", value=6,
                          description="For graphic jobs")
    options.append(option)
    option = SelectOption(label="Video Editor", value=7,
                          description="For video editing jobs")
    options.append(option)
    option = SelectOption(label="Sound", value=8,
                          description="For sound jobs")
    options.append(option)
    option = SelectOption(label="Clothing", value=9,
                          description="For clothing jobs")
    options.append(option)
    option = SelectOption(label="Effects", value=10,
                          description="For vfx jobs")
    options.append(option)
    option = SelectOption(label="Voice Actor", value=11,
                          description="For voice actor jobs")
    options.append(option)
    option = SelectOption(label="Translator", value=12,
                          description="For translation jobs")
    options.append(option)
    option = SelectOption(label="Animator", value=13,
                          description="For animation jobs")
    options.append(option)
    option = SelectOption(label="Texturing Artist", value=14,
                          description="For texture jobs")
    options.append(option)
    option = SelectOption(label="Other", value=15,
                          description="For other jobs")
    options.append(option)
    return options


def generatePaymentType():
    options = []
    paymentType1 = SelectOption(
        label="Per Task", description="Paid per task complated", value="Per Task")
    paymentType2 = SelectOption(
        label="Partial up-Front", description="Paid parcially up Front, then the rest upon completion.", value="Partial up-Front")
    paymentType3 = SelectOption(
        label="Up Front", description="Paid fully before the task is begun.", value="Up Front")
    paymentType4 = SelectOption(
        label="Upon Completion", description="Payment given when the work is completed.", value="Upon Completion")
    options.append(paymentType1)
    options.append(paymentType2)
    options.append(paymentType3)
    options.append(paymentType4)
    return options
# Callbacks


class postInfo(nextcord.ui.Modal):
    def __init__(self, interaction, user):
        self.interaction = interaction
        self.user = user
        super().__init__(
            "Post information.",
            timeout=5 * 60,
        )
        self.titlefield = nextcord.ui.TextInput(
            label="What Developer are you?",
            placeholder="Ex Clothing Designer",
            required=True,
            min_length=1,
            max_length=256,

        )

        self.descriptionfield = nextcord.ui.TextInput(
            label="Description",
            placeholder="Write about your experience, projects you have worked on, a bit about yourself, etc.",
            required=True,
            min_length=1,
            max_length=4000,
            style=TextInputStyle.paragraph,

        )

        field = editPostFields[self.user.id]['postinfo']
        try:
            self.titlefield.default_value = field['title']
            self.descriptionfield.default_value = field['description']
        except:
            pass
        self.add_item(self.titlefield)
        self.add_item(self.descriptionfield)

    async def callback(self, interaction: nextcord.Interaction) -> None:
        embed = generateEmbed(self.user)
        embed.title = self.titlefield.value
        embed.description = self.descriptionfield.value
        field = editPostFields[self.user.id]['postinfo']
        field['title'] = self.titlefield.value
        field['description'] = self.descriptionfield.value
        try:
            await self.interaction.edit(embed=embed)
        except:
            pass


class paymentInfo(nextcord.ui.Modal):
    def __init__(self, interaction, user):
        self.interaction = interaction
        self.user = user
        super().__init__(
            "Payment information.",
            timeout=5 * 60,
        )
        self.robux = nextcord.ui.TextInput(
            label="Robux",
            placeholder="Amount to pay in robux",
            required=False,
            min_length=1,
            max_length=150,

        )

        self.money = nextcord.ui.TextInput(
            label="USD",
            placeholder="Amount to pay in USD",
            required=False,
            min_length=1,
            max_length=150,

        )

        field = editPostFields[self.user.id]['paymentinfo']
        try:
            self.robux.default_value = field['robux']
        except:
            pass
        try:
            self.money.default_value = field['usd']
        except:
            pass

        self.add_item(self.robux)
        self.add_item(self.money)

    async def callback(self, interaction: nextcord.Interaction) -> None:

        # Remove all strings
        embed = generateEmbed(self.user)
        robuxAmount = self.robux.value
        moneyAmount = self.money.value
        # robuxAmount = re.sub("\D", "", self.robux.value)
        # moneyAmount = re.sub("\D", "", self.money.value)
        userField = editPostFields[self.user.id]
        if len(robuxAmount.splitlines()) > 1:
            embed = nextcord.Embed(
                title="Too many lines", description="Please input a value with only 1 line.", color=colors['error'])
            await interaction.response.send_message(embed=embed)
        elif len(moneyAmount.splitlines()) > 1:
            embed = nextcord.Embed(
                title="Too many lines", description="Please input a value with only 1 line.", color=colors['error'])
            await interaction.response.send_message(embed=embed)
        else:
            if not robuxAmount == "" and not moneyAmount == "":
                embed.set_field_at(index=0, name="Payment", value=f"""
**Robux:** {robuxAmount}
**USD:**     {moneyAmount}
""")
                userField['paymentinfo'] = {
                    "robux": robuxAmount, "usd": moneyAmount}

            elif not robuxAmount == "":
                embed.set_field_at(index=0, name="Payment", value=f"""
**Robux:** {robuxAmount}
""")
                userField['paymentinfo'] = {"robux": robuxAmount}
            elif not moneyAmount == "":
                embed.set_field_at(index=0, name="Payment", value=f"""
**USD:**     {moneyAmount}
""")
                userField['paymentinfo'] = {"usd": moneyAmount}
            else:
                await interaction.response.send_message("Please provide valid payment.", ephemeral=True)
                embed.set_field_at(index=0, name="Payment",
                                   value=f"Nothing provided")
        await self.interaction.edit(embed=embed)


class miscInfo(nextcord.ui.Modal):
    def __init__(self, interaction, user):
        self.interaction = interaction
        self.user = user
        super().__init__(
            "Misc information.",
            timeout=5 * 60,
        )

        self.portofolio = nextcord.ui.TextInput(
            label="Portofolio",
            placeholder="A link to your portofolio",
            required=False,
            min_length=1,
            max_length=2048,
            style=TextInputStyle.paragraph,
        )

        self.pastwork = nextcord.ui.TextInput(
            label="Past Work",
            placeholder="Links to your past work, seperated by a NEW LINE",
            required=True,
            min_length=1,
            max_length=2048,
            style=TextInputStyle.paragraph,
        )

        field = editPostFields[self.user.id]['miscInfo']
        try:
            self.portofolio.default_value = field['portofolio']['text']
        except:
            pass
        try:
            self.pastwork.default_value = field['pastWorkLinks']
        except:
            pass
        self.add_item(self.portofolio)
        self.add_item(self.pastwork)

    async def callback(self, interaction: nextcord.Interaction) -> None:
        userField = editPostFields[self.user.id]
        field = userField['miscInfo']

        if self.portofolio.value:
            if "https://" in self.portofolio.value:
                newText = self.portofolio.value.replace("https://", "")
                newText = newText.split("/", 1)[0]
                field['portofolio'] = {"text": newText,
                                       "value": self.portofolio.value}
        if self.pastwork.value:
            pastWorkExamples = self.pastwork.value.splitlines()
            if len(pastWorkExamples) <= 4:
                pastWorkValues = ""
                pastWorkLinks = []
                for example in pastWorkExamples:
                    pastWorkValues = pastWorkValues + f"[Link]({example}) "
                    pastWorkLinks.append(f"{example} \n")
                field['pastWork'] = pastWorkValues
                field['pastWorkLinks'] = pastWorkLinks
            else:
                await interaction.response.send_message(content="Please provide 4 or less links.", ephemeral=True)
        embed = generateEmbed(self.user)
        await self.interaction.edit(embed=embed)


class postDeniedModal(nextcord.ui.Modal):
    def __init__(self, user, message, embed):
        self.user = user
        self.message = message
        self.embed = embed

        super().__init__(
            "Post Denial.",
            timeout=5 * 60,
        )
        self.reason = nextcord.ui.TextInput(
            label="Reason for denying",
            placeholder="Provide a detailed reason for denying the post.",
            required=True,
            min_length=10,
            max_length=1500,
            style=TextInputStyle.paragraph
        )

        self.add_item(self.reason)

    async def callback(self, interaction: nextcord.Interaction) -> None:
        messageToDelete = await interaction.response.send_message(content="Loading...")
        await messageToDelete.delete()
        channel = bot.get_channel(channelIDs['logs'])
        await channel.send(content=f"The following post has been denied for the reason: `{self.reason.value}`", embed=self.embed)
        try:
            await self.user.send(content=f"Your post has been denied for the reason: `{self.reason.value}`", embed=self.embed)
        except:
            await interaction.response.send_message(content="User has their DM's turned off.", ephemeral=True)
        await self.message.delete()

# Buttons


class postApprovalButtons(nextcord.ui.View):
    def __init__(self, interaction, user, embed):
        super().__init__(timeout=None)
        self.value = None
        self.interaction = interaction
        self.user = user
        self.embed = embed

    @ nextcord.ui.button(label="Approve", style=nextcord.ButtonStyle.green)
    async def approve(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        channel = bot.get_channel(channelIDs['posts'])
        await channel.send(embed=self.embed, content=f"New post by: <@{self.user.id}>")
        try:
            await self.user.send(content="Your post has been approved.", embed=self.embed)
        except:
            await interaction.response.send_message(content="User has their DM's turned off.", ephemeral=True)
        await self.interaction.delete()

    @ nextcord.ui.button(label="Deny", style=nextcord.ButtonStyle.red)
    async def deny(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        modal = postDeniedModal(self.user, self.interaction, self.embed)
        await interaction.response.send_modal(modal=modal)


class confirmationButtons(nextcord.ui.View):
    def __init__(self, interaction, user):
        super().__init__(timeout=None)
        self.value = None
        self.interaction = interaction
        self.user = user

    @ nextcord.ui.button(label="Confirm", style=nextcord.ButtonStyle.green)
    async def finishVerification(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        self.value = 1
        channel = bot.get_channel(channelIDs['postApprovers'])
        embed = generateEmbed(self.user)
        message = await channel.send(content="Loading post...")
        view = postApprovalButtons(message, self.user, embed)
        await message.edit(content=f"Post by <@{interaction.user.id}>", embed=embed, view=view)
        await self.interaction.edit(embed=None, view=None, content="Your post has been sent for review.")

    @ nextcord.ui.button(label="Go Back", style=nextcord.ButtonStyle.red)
    async def cancel(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        self.value = 2
        embed = generateEmbed(self.user)
        editView = editButtons(self.interaction, self.user)

        async def paymentTypeCallback(cbinteraction):
            for value in paymentTypeDropdown.values:
                editPostFields[interaction.user.id]['paymentType'] = value
                embed = generateEmbed(interaction.user)
                await interaction.edit(embed=embed)

        async def channelCallback(cbinteraction):

            for value in dropdownForHire.values:
                if postTypeField[interaction.user.id] == 1:
                    editPostFields[interaction.user.id]['postChannel'] = {
                        "value": int(value), "type": 1}
                else:
                    editPostFields[interaction.user.id]['postChannel'] = {
                        "value": int(value), "type": 2}

        if postTypeField[interaction.user.id] == 1:
            options = generateAllRolesDropdown()
        else:
            options = generateRoleDropdown(interaction.user.roles)
        dropdownForHire = Select(
            placeholder="What channel to post to?", options=options, max_values=1)
        dropdownForHire.callback = channelCallback
        editView.add_item(dropdownForHire)

        # Payment Type
        options = generatePaymentType()
        paymentTypeDropdown = Select(
            placeholder="Payment Type?", options=options, max_values=1)
        paymentTypeDropdown.callback = paymentTypeCallback
        editView.add_item(paymentTypeDropdown)

        await self.interaction.edit(view=editView, embed=embed, content=editContentMsg)


class deleteButton(nextcord.ui.View):
    def __init__(self, interaction, user):
        super().__init__(timeout=None)
        self.value = None
        self.interaction = interaction
        self.user = user

    @ nextcord.ui.button(label="πŸ—‘οΈ", style=nextcord.ButtonStyle.red)
    async def info(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        self.value = 1
        if interaction.user == self.user:
            await self.interaction.delete()
        else:
            interaction.response.send_message(content="Not your post.")
        self.stop()


class editButtons(nextcord.ui.View):
    def __init__(self, interaction, user):
        super().__init__(timeout=None)
        self.value = None
        self.interaction = interaction
        self.user = user

    @ nextcord.ui.button(label="Edit Post Info", style=nextcord.ButtonStyle.red)
    async def info(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        self.value = 1
        modal = postInfo(self.interaction, self.user)
        await interaction.response.send_modal(modal=modal)

    @ nextcord.ui.button(label="Edit Payment", style=nextcord.ButtonStyle.red)
    async def payment(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        self.value = 2
        modal = paymentInfo(self.interaction, self.user)
        await interaction.response.send_modal(modal=modal)

    @ nextcord.ui.button(label="Edit Misc Info", style=nextcord.ButtonStyle.red)
    async def cancel(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        self.value = 3
        modal = miscInfo(self.interaction, self.user)
        await interaction.response.send_modal(modal=modal)

    @ nextcord.ui.button(label="Finish", style=nextcord.ButtonStyle.red)
    async def finish(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        self.value = 4
        failed = allFieldsFilled(self.user.id)
        if failed == True:
            await interaction.response.send_message(content="Make sure that you have filled in everything before sending.", ephemeral=True)
        else:
            confirmationEmbed = nextcord.Embed(
                title="Confirmation", description="Are you sure you have double checked your post and made sure that this is what you want to post?", color=colors['main'])
            view = confirmationButtons(self.interaction, self.user)
            await self.interaction.edit(embed=confirmationEmbed, view=view)


# Post Command

@bot.slash_command(guild_ids=[GuildID], description="πŸ“‹ ・Use this command to showcase your portfolio or past work.")
async def post(interaction: nextcord.Interaction):
    embed = nextcord.Embed(
        title="*Your Title Here*", description="No description Provided")
    embed.add_field(name="Payment", value="*Nothing Provided*")
    embed.add_field(name="Payment Type",
                    value="*Nothing Provided*", inline=True)
    embed.add_field(name="Portofolio",
                    value="Nothing Provided", inline=False)
    embed.add_field(name="Past Work",
                    value="Nothing Provided", inline=False)
    embed.add_field(name="Posted By",
                    value=f"<@{interaction.user.id}>")
    embed.color = colors['main']
    try:
        embed.set_author(name=interaction.user.name,
                         icon_url=interaction.user.avatar.url)
    except:
        pass
    message = await interaction.response.send_message(content="Loading...", ephemeral=True)
    editView = editButtons(message, interaction.user)
    postChannel = None
    editPostFields[interaction.user.id] = {
        'postinfo': {}, 'paymentinfo': {}, 'miscInfo': {}, 'paymentType': None, 'postChannel': None, }

    async def paymentTypeCallback(cbinteraction):
        for value in paymentTypeDropdown.values:
            editPostFields[interaction.user.id]['paymentType'] = value
            embed = generateEmbed(interaction.user)
            await message.edit(embed=embed)

    options = []
    # Payment Type
    options = generatePaymentType()
    paymentTypeDropdown = Select(
        placeholder="Payment Type?", options=options, max_values=1)
    paymentTypeDropdown.callback = paymentTypeCallback
    editView.add_item(paymentTypeDropdown)
    await message.edit(view=editView, embed=embed, content=editContentMsg)


class modHelp(nextcord.ui.View):
    def __init__(self, interaction, user):
        super().__init__(timeout=5*60)
        self.value = None
        self.interaction = interaction
        self.user = user

    @ nextcord.ui.button(label="Confirm", style=nextcord.ButtonStyle.green)
    async def yes(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        embed = nextcord.Embed(
            title="Stage 1", description="Someone from the helper team will assist you shortly", color=colors['main'])
        await interaction.response.send_message(embed=embed, ephemeral=True)
        channel = interaction.channel
        await channel.send(content=f"<@{self.user.id}> is in need of assistance in Stage 1. <@&{roleIDs['stageHelpers']}>")
        self.stop()

    @ nextcord.ui.button(label="Go back", style=nextcord.ButtonStyle.grey)
    async def no(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        view = stage1Buttons(self.interaction, interaction.user)
        embed = nextcord.Embed(
            title="Stage 1", description=stage1Text, color=colors['main'])
        await self.interaction.edit(embed=embed, view=view)


class stage1Buttons(nextcord.ui.View):
    def __init__(self, interaction, user):
        super().__init__(timeout=5*60)
        self.value = None
        self.interaction = interaction
        self.user = user

    @ nextcord.ui.button(label="Yes", style=nextcord.ButtonStyle.green)
    async def yes(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        guild = bot.get_guild(GuildID)
        role = guild.get_role(roleIDs['stage1Role'])
        await interaction.user.remove_roles(role)
        role = guild.get_role(roleIDs['stage2Role'])
        await interaction.user.add_roles(role)
        embed = nextcord.Embed(
            title="Sucess", description="You can move on to stage 2.", color=colors['main'])
        await self.interaction.edit(embed=embed, view=None)
        self.stop()

    @ nextcord.ui.button(label="No", style=nextcord.ButtonStyle.red)
    async def no(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        view = modHelp(self.interaction, self.user)
        embed = nextcord.Embed(
            title="Stage 1", description="Do you need moderator assistance?", color=colors['main'])
        await self.interaction.edit(embed=embed, view=view)


@bot.slash_command(guild_ids=[GuildID], description=f"πŸ“Œ ・For Stage 1 applicants, use this command. ")
async def stage1(interaction: nextcord.Interaction):
    hasRole = False
    hasStage3 = False
    hasStage2 = False
    stage1Role = roleIDs['stage1Role']
    stage2Role = roleIDs['stage2Role']
    stage3Role = roleIDs["stage3Role"]
    for role in interaction.user.roles:
        if str(role.id) == str(stage1Role):
            hasRole = True
        elif str(role.id) == str(stage3Role):
            hasStage3 = True
        elif str(role.id) == str(stage2Role):
            hasStage2 = True
    if hasRole:
        view = stage1Buttons(interaction, interaction.user)
        embed = nextcord.Embed(
            title="Stage 1", description=stage1Text, color=colors['main'])
        message = await interaction.response.send_message(embed=embed, view=view, ephemeral=True)
        view = stage1Buttons(message, interaction.user)
        await message.edit(embed=embed, view=view)
    elif hasStage3:
        embed = nextcord.Embed(title="Insufficient Permissions",
                               description="You have not yet reached the appropriate stage to utilize this command. Please use /stage3 to continue your application.", color=colors['error'])
        await interaction.response.send_message(embed=embed, ephemeral=True)
    elif hasStage2:
        embed = nextcord.Embed(title="Insufficient Permissions",
                               description="You have not yet reached the appropriate stage to utilize this command. Please use /stage1 to continue your application.", color=colors['error'])
        await interaction.response.send_message(embed=embed, ephemeral=True)
    else:
        embed = nextcord.Embed(title="Insufficient Permissions",
                               description="You have not yet reached the appropriate stage to utilize this command.", color=colors['error'])
        await interaction.response.send_message(embed=embed, ephemeral=True)


class stage2Approvers(nextcord.ui.View):
    def __init__(self, user, response, text, role, linkType, reference, message):
        super().__init__(timeout=None)
        self.value = None
        self.user = user
        self.response = response
        self.text = text
        self.role = role
        self.message = message
        emoji = nextcord.PartialEmoji(name="πŸ”—")
        if linkType == "1":
            self.add_item(nextcord.ui.Button(
                style=nextcord.ButtonStyle.link, url=response, label="Response", disabled=False, emoji=emoji))
        else:
            self.add_item(nextcord.ui.Button(
                style=nextcord.ButtonStyle.link, url="https://test.com", label="Response", disabled=True, emoji=emoji))
        if reference == "":
            self.add_item(nextcord.ui.Button(
                style=nextcord.ButtonStyle.link, url="https://test.com", label="Reference", disabled=True, emoji=emoji))
        else:
            self.add_item(nextcord.ui.Button(
                style=nextcord.ButtonStyle.link, url=reference, label="Reference", disabled=False, emoji=emoji))

    @ nextcord.ui.button(label="Approve", style=nextcord.ButtonStyle.green)
    async def yes(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        guild = bot.get_guild(GuildID)
        role = guild.get_role(roleIDs['stage2Role'])
        await self.user.remove_roles(role)

        stage3Role = roleIDs['stage3Role']
        role = guild.get_role(stage3Role)
        await self.user.add_roles(role)

        embed = nextcord.Embed(
            title="Stage 2", description=f"Your application in stage2 for {role} has been accepted, congrats!", color=colors['main'])
        try:
            await self.user.send(embed=embed)
        except:
            await interaction.response.send_message(content="User has their DM's turned off.", ephemeral=True)

        logsChannel = guild.get_channel(channelIDs['logs'])
        embed = nextcord.Embed(
            title="Stage 2 approved", description=f"The user {self.user.mention} has been approved in stage 2. by <@{interaction.user.id}>", color=colors['log'])
        await logsChannel.send(embed=embed)
        self.stop()
        await self.message.delete()

    @ nextcord.ui.button(label="Deny", style=nextcord.ButtonStyle.red)
    async def no(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        guild = bot.get_guild(GuildID)
        stage2Roles = roleIDs['stage2']
        selfRoleList = list(self.role)
        role = guild.get_role(stage2Roles[selfRoleList[0]])
        embed = nextcord.Embed(
            title="Stage 2", description=f"Your application in stage2 for {role} has been denied", color=colors['main'])
        try:
            await self.user.send(embed=embed)
        except:
            await interaction.response.send_message(content="User has their DM's turned off.", ephemeral=True)

        logsChannel = guild.get_channel(channelIDs['logs'])
        embed = nextcord.Embed(
            title="Stage 2 denied", description=f"The user {self.user.mention} has been denied in stage 2. by <@{interaction.user.id}>", color=colors['log'])
        await logsChannel.send(embed=embed)
        self.stop()
        await self.message.delete()


class stage2Modal(nextcord.ui.Modal):
    def __init__(self, user, message, text, role, reference):
        self.user = user
        self.message = message
        self.text = text
        self.role = role
        self.reference = reference

        super().__init__(
            "Stage 2.",
            timeout=5 * 60,
        )
        self.upload = nextcord.ui.TextInput(
            label="Upload",
            placeholder="A singular link to the item that you have created.",
            required=True,
            min_length=10,
            max_length=1500,
            style=TextInputStyle.paragraph
        )

        self.add_item(self.upload)

    async def callback(self, interaction: nextcord.Interaction) -> None:
        if len(self.upload.value.splitlines()) > 1:
            await interaction.response.send_message(content="Please only send 1 link", ephemeral=True)
        else:
            embed = nextcord.Embed(title=f"Stage 2",
                                   description="Your response is being reviewed, please wait untill a staff member reaches out to you with your response.",
                                   color=colors['main'])
            await interaction.response.send_message(embed=embed, ephemeral=True)

            embed = nextcord.Embed(
                title=f"Stage 2: {self.text}", description=f"The user <@{self.user.id}> has made an application.", color=colors['log'])
            channel = bot.get_channel(channelIDs['stage2Approvers'])
            message = await channel.send(embed=embed)
            view = stage2Approvers(
                self.user, self.upload.value, self.text, self.role, "1", self.reference, message)
            try:
                await message.edit(embed=embed, view=view)
            except:
                view = stage2Approvers(
                    self.user, self.upload.value, self.text, self.role, "2", self.reference, message)
                await message.edit(embed=embed, view=view)


class stage2Done(nextcord.ui.View):
    def __init__(self, interaction, user, text, role, reference):
        super().__init__(timeout=None)
        self.value = None
        self.interaction = interaction
        self.user = user
        self.text = text
        self.role = role
        self.reference = reference
        emoji = nextcord.PartialEmoji(name="πŸ”—")
        if not (reference == "") and reference:
            try:
                self.add_item(nextcord.ui.Button(
                    style=nextcord.ButtonStyle.link, url=reference, label="Reference", emoji=emoji))
            except:
                self.add_item(nextcord.ui.Button(
                    style=nextcord.ButtonStyle.link, url="https://test.com", label="Reference", disabled=True, emoji=emoji))
        else:
            self.add_item(nextcord.ui.Button(
                style=nextcord.ButtonStyle.link, url="https://test.com", label="Reference", disabled=True, emoji=emoji))

    @ nextcord.ui.button(label="Done", style=nextcord.ButtonStyle.green)
    async def yes(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        modal = stage2Modal(self.user, self.interaction,
                            self.text, self.role, self.reference)
        await interaction.response.send_modal(modal=modal)


@bot.slash_command(guild_ids=[GuildID], description="πŸ“Œ For Stage 2 applicants, use this command.")
async def stage2(interaction: nextcord.Interaction):
    user = interaction.user
    hasRole = False
    hasStage1 = False
    hasStage3 = False
    stage1Role = roleIDs['stage1Role']
    stage2Role = roleIDs['stage2Role']
    stage3Role = roleIDs["stage3Role"]
    for role in interaction.user.roles:
        if str(role.id) == str(stage2Role):
            hasRole = True
        elif str(role.id) == str(stage1Role):
            hasStage1 = True
        elif str(role.id) == str(stage3Role):
            hasStage3 = True
    if hasRole:
        stage2Roles = roleIDs['stage2Needed']
        stage2Values = list(stage2Roles.values())
        stage2Keys = list(stage2Roles.keys())
        index = 0
        roleFound = False
        for role in user.roles:
            if role.id in stage2Values:
                position = list(stage2Roles.values()).index(role.id)
                userRole = stage2Keys[position]
                tasksAvailable = stage2Tasks[userRole]
                referencesAvailable = stage2References[userRole]
                randomNumber = random.randint(0, len(tasksAvailable) - 1)
                task = tasksAvailable[randomNumber]
                try:
                    reference = referencesAvailable[randomNumber]
                except:
                    reference = referencesAvailable[randomNumber - 1]
                if reference == "https://test.com":
                    reference = None
                view = stage2Done(interaction, interaction.user,
                                  f"{userRole}, task {randomNumber + 1}.", {userRole}, reference)
                if index == 0:
                    await interaction.response.send_message(embed=task, view=view, ephemeral=True)
                    index += 1
                else:
                    await interaction.followup.send(embed=task, view=view, ephemeral=True)
                roleFound = True
        if roleFound == False:
            embed = nextcord.Embed(
                title="No role found", description="You do not have the required role to use this command. If you would like to apply for our Development Team, please use /apply.", color=colors['error'])
            await interaction.response.send_message(embed=embed, ephemeral=True)
    elif hasStage1:
        embed = nextcord.Embed(title="Insufficient Permissions",
                               description="You have not yet reached the appropriate stage to utilize this command. Please use /stage1 to continue your application.", color=colors['error'])
        await interaction.response.send_message(embed=embed, ephemeral=True)
    elif hasStage3:
        embed = nextcord.Embed(title="Insufficient Permissions",
                               description="You have not yet reached the appropriate stage to utilize this command. Please use /stage3 to continue your application.", color=colors['error'])
        await interaction.response.send_message(embed=embed, ephemeral=True)
    else:
        embed = nextcord.Embed(title="Insufficient Permissions",
                               description="You have not yet reached the appropriate stage to utilize this command.", color=colors['error'])
        await interaction.response.send_message(embed=embed, ephemeral=True)


async def stage3Logs(discordUsername, robloxUsername, type):
    guild = bot.get_guild(GuildID)
    channel = guild.get_channel(channelIDs["stage3Logs"])
    embed = nextcord.Embed(title="Stage 3 passed", description=f"""
Discord username: <@{discordUsername}>
Roblox Username: {robloxUsername}
Application type: {type}
""", color=colors['log'], timestamp=datetime.datetime.utcnow())
    robloxID = apis.getID(robloxUsername)
    image = apis.avatar(robloxID)
    embed.set_thumbnail(url=image)
    await channel.send(embed=embed)


class stage3Robux(nextcord.ui.View):
    def __init__(self, interaction, user, username, shirtType, price, paymentType):
        super().__init__(timeout=None)
        self.value = None
        self.interaction = interaction
        self.user = user
        self.username = username
        self.shirtType = shirtType
        self.price = price
        self.type = paymentType

    @ nextcord.ui.button(label="Done", style=nextcord.ButtonStyle.green)
    async def yes(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        shirtID = shirtIDs[self.shirtType]
        shirt = apis.getItem(shirtID)
        try:
            price = shirt['price']
            if price == self.price:
                embed = nextcord.Embed(
                    title="Stages Completed", description="You have finished all our stages, congrats!", color=colors['main'])
                await self.interaction.edit(embed=embed, view=None)
                await stage3Logs(self.user.id, self.username, self.type)

                guild = bot.get_guild(GuildID)
                stage3Roles = roleIDs['stage3']
                role = guild.get_role(stage3Roles['robux'])
                await interaction.user.add_roles(role)

                role = guild.get_role(stage3Roles['developer'])
                await interaction.user.add_roles(role)

                stage3Role = roleIDs['stage3Role']
                role = guild.get_role(stage3Role)
                await interaction.user.remove_roles(role)
                appIDs = roleIDs['applicationRoleIDs']
                for role in interaction.user.roles:
                    roleID = role.id
                    if roleID in appIDs:
                        appRole = appIDs[roleID]
                        mainRoleID = roleIDs[appRole]
                        await interaction.user.remove_roles(role)
                        role = guild.get_role(mainRoleID)
                        await interaction.user.add_roles(role)

            else:
                embed = nextcord.Embed(
                    title="Incorrect Price", description=f"The price of the shirt is currently `{shirt['price']}` but it is meant to be `{self.price}`", color=colors['error'])
                await interaction.response.send_message(embed=embed, ephemeral=True)
        except:
            embed = nextcord.Embed(
                title="Ratelimit", description="Please wait and try again.", color=colors['error'])
            await interaction.response.send_message(embed=embed, ephemeral=True)

    @ nextcord.ui.button(label="Help", style=nextcord.ButtonStyle.red)
    async def no(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        await interaction.response.send_message(content=f"<@&{roleIDs['stageHelpers']}> this user needs assistance!")


class stage3Paypal(nextcord.ui.View):
    def __init__(self, interaction, user, username, paymentType):
        super().__init__(timeout=None)
        self.value = None
        self.interaction = interaction
        self.user = user
        self.username = username
        self.type = paymentType

    @ nextcord.ui.button(label="Yes", style=nextcord.ButtonStyle.green)
    async def yes(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        if self.type == 1:
            try:
                await apis.setRank(self.username, groupRankIDs['developer'])
            except Exception as e:
                pass
            embed = nextcord.Embed(
                title="Stages Completed", description="You have finished all our stages, congrats!", color=colors['main'])
            await self.interaction.edit(embed=embed, view=None)
            await stage3Logs(self.user.id, self.username, self.type)
            guild = bot.get_guild(GuildID)
            stage3Roles = roleIDs['stage3']
            role = guild.get_role(stage3Roles['paypal'])
            await interaction.user.add_roles(role)

            role = guild.get_role(stage3Roles['developer'])
            await interaction.user.add_roles(role)
            stage3Role = roleIDs['stage3Role']
            role = guild.get_role(stage3Role)
            await interaction.user.remove_roles(role)

            appIDs = roleIDs['applicationRoleIDs']
            for role in interaction.user.roles:
                roleID = role.id
                if roleID in appIDs:
                    appRole = appIDs[roleID]
                    mainRoleID = roleIDs[appRole]
                    await interaction.user.remove_roles(role)
                    role = guild.get_role(mainRoleID)
                    await interaction.user.add_roles(role)
        elif self.type == 2:
            embed = nextcord.Embed(
                title="Robux", description=robuxText, color=colors['main'])
            price = random.randint(10, 10000)
            shirt = random.randint(1, 3)
            embed.add_field(
                name="Price", value=price, inline=False)
            embed.add_field(
                name="Shirt", value=f"[Shirt]({shirtLinks[shirt]})")
            view = stage3Robux(
                self.interaction, self.user, self.username, shirt, price, 2)
            await self.interaction.edit(embed=embed, view=view)
            guild = bot.get_guild(GuildID)
            stage3Roles = roleIDs['stage3']
            role = guild.get_role(stage3Roles['paypal'])
            await interaction.user.add_roles(role)
            try:
                await apis.setRank(self.username, groupRankIDs['developer'])
            except Exception as e:
                pass

    @ nextcord.ui.button(label="No", style=nextcord.ButtonStyle.red)
    async def no(self, button: nextcord.ui.Button, interaction: nextcord.Interaction):
        await interaction.response.send_message(content=f"<@&{roleIDs['stageHelpers']}> this user needs assistance!")


@bot.slash_command(guild_ids=[GuildID], description="πŸ“Œ For Stage 3 applicants, use this command.")
async def stage3(interaction: nextcord.Interaction, username: str):
    hasRole = False
    hasStage1 = False
    hasStage2 = False
    stage1Role = roleIDs['stage1Role']
    stage2Role = roleIDs['stage2Role']
    stage3Role = roleIDs["stage3Role"]
    for role in interaction.user.roles:
        if str(role.id) == str(stage3Role):
            hasRole = True
        elif str(role.id) == str(stage1Role):
            hasStage1 = True
        elif str(role.id) == str(stage2Role):
            hasStage2 = True
    if hasRole:
        robloxID = apis.getID(username)
        if robloxID and apis.isGroupMember(robloxID) == True:
            guild = bot.get_guild(GuildID)
            staffRole = roleIDs['staff']
            staffRole = guild.get_role(staffRole)
            overwrites = {
                guild.default_role: nextcord.PermissionOverwrite(view_channel=False),
                interaction.user: nextcord.PermissionOverwrite(view_channel=True),
                staffRole: nextcord.PermissionOverwrite(view_channel=True)
            }
            categoryID = categoryIDs['stage3']
            guild = bot.get_guild(GuildID)
            category = guild.get_channel(categoryID)
            channel = await category.create_text_channel(name=interaction.user.name, overwrites=overwrites)
            embed = nextcord.Embed(
                title="Stage 3", description=f"Your channel has been created: <#{channel.id}>", color=colors['main'])
            await interaction.response.send_message(embed=embed, ephemeral=True)
            embed = nextcord.Embed(title="Stage 3", description="""
Welcome to the final stage!

Question 1: What payment methods do you accept?
""", color=colors['main'])
            message = None

            async def dropdownCallback(cbinteraction):
                if len(stage3Dropdown.values) == 1:
                    for value in stage3Dropdown.values:
                        value = int(value)
                        if value == 1:
                            embed = nextcord.Embed(
                                title="Paypal", description=paypalText, color=colors['main'])
                            view = stage3Paypal(
                                message, interaction.user, username, 1)
                            await message.edit(embed=embed, view=view)
                        elif value == 2:
                            embed = nextcord.Embed(
                                title="Robux", description=robuxText, color=colors['main'])
                            price = random.randint(10, 10000)
                            shirt = random.randint(1, 3)
                            embed.add_field(
                                name="Price", value=price, inline=False)
                            embed.add_field(
                                name="Shirt", value=f"[Shirt]({shirtLinks[shirt]})")
                            view = stage3Robux(
                                message, interaction.user, username, shirt, price, 1)
                            await message.edit(embed=embed, view=view)
                            await apis.setRank(username, groupRankIDs['developer'])

                else:
                    embed = nextcord.Embed(
                        title="Paypal", description=paypalText, color=colors['main'])
                    view = stage3Paypal(
                        message, interaction.user, username, 2)
                    await message.edit(embed=embed, view=view)

            options = []
            options.append(SelectOption(label="Paypal", value=1))
            options.append(SelectOption(label="Robux", value=2))
            stage3Dropdown = Select(
                placeholder="What payment method(s) do you acecept??", options=options, max_values=2)
            view = View(timeout=None)
            stage3Dropdown.callback = dropdownCallback
            view.add_item(stage3Dropdown)
            message = await channel.send(embed=embed, view=view)
        else:
            if not robloxID:
                embed = nextcord.Embed(
                    title="Invalid Username", description="Please make sure that your Roblox username is valid and try again.", color=colors['error'])
                await interaction.response.send_message(embed=embed, ephemeral=True)
            elif not apis.isGroupMember(robloxID) == True:
                embed = nextcord.Embed(
                    title="User not in group", description="The username you have sent is not in the group.", color=colors['error'])
                await interaction.response.send_message(embed=embed, ephemeral=True)
    elif hasStage1:
        embed = nextcord.Embed(title="Insufficient Permissions",
                               description="You have not yet reached the appropriate stage to utilize this command. Please use /stage1 to continue your application.", color=colors['error'])
        await interaction.response.send_message(embed=embed, ephemeral=True)
    elif hasStage2:
        embed = nextcord.Embed(title="Insufficient Permissions",
                               description="You have not yet reached the appropriate stage to utilize this command. Please use /stage1 to continue your application.", color=colors['error'])
        await interaction.response.send_message(embed=embed, ephemeral=True)
    else:
        embed = nextcord.Embed(title="Insufficient Permissions",
                               description="You have not yet reached the appropriate stage to utilize this command.", color=colors['error'])
        await interaction.response.send_message(embed=embed, ephemeral=True)
bot.run(TOKEN)