Move errors route into get_reminders route. Add database migration.
This commit is contained in:
		
							
								
								
									
										4
									
								
								migrations/20230903131153_reminder_status_timing.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								migrations/20230903131153_reminder_status_timing.sql
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					ALTER TABLE reminders ADD COLUMN `status_change_time` DATETIME;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- This is a best-guess as to the status change time.
 | 
				
			||||||
 | 
					UPDATE reminders SET `status_change_time` = `utc_time`;
 | 
				
			||||||
@@ -166,15 +166,21 @@ impl ComponentDataModel {
 | 
				
			|||||||
                    .await;
 | 
					                    .await;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ComponentDataModel::DelSelector(selector) => {
 | 
					            ComponentDataModel::DelSelector(selector) => {
 | 
				
			||||||
                let selected_id = component.data.values.join(",");
 | 
					                for id in &component.data.values {
 | 
				
			||||||
 | 
					                    match id.parse::<u32>() {
 | 
				
			||||||
 | 
					                        Ok(id) => {
 | 
				
			||||||
 | 
					                            if let Some(reminder) = Reminder::from_id(&data.database, id).await {
 | 
				
			||||||
 | 
					                                reminder.delete(&data.database).await.unwrap();
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                warn!("Attempt to delete non-existent reminder");
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                sqlx::query!(
 | 
					                        Err(e) => {
 | 
				
			||||||
                    "UPDATE reminders SET `status` = 'deleted' WHERE FIND_IN_SET(id, ?)",
 | 
					                            warn!("Error casting ID to integer: {:?}.", e);
 | 
				
			||||||
                    selected_id
 | 
					                        }
 | 
				
			||||||
                )
 | 
					                    }
 | 
				
			||||||
                .execute(&data.database)
 | 
					                }
 | 
				
			||||||
                .await
 | 
					 | 
				
			||||||
                .unwrap();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let reminders = Reminder::from_guild(
 | 
					                let reminders = Reminder::from_guild(
 | 
				
			||||||
                    &ctx,
 | 
					                    &ctx,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -304,7 +304,10 @@ WHERE
 | 
				
			|||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
        db: impl Executor<'_, Database = Database>,
 | 
					        db: impl Executor<'_, Database = Database>,
 | 
				
			||||||
    ) -> Result<(), sqlx::Error> {
 | 
					    ) -> Result<(), sqlx::Error> {
 | 
				
			||||||
        sqlx::query!("UPDATE reminders SET `status` = 'deleted' WHERE uid = ?", self.uid)
 | 
					        sqlx::query!(
 | 
				
			||||||
 | 
					            "UPDATE reminders SET `status` = 'deleted', `status_change_time` = NOW() WHERE uid = ?",
 | 
				
			||||||
 | 
					            self.uid
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        .execute(db)
 | 
					        .execute(db)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
        .map(|_| ())
 | 
					        .map(|_| ())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -166,7 +166,6 @@ pub async fn initialize(
 | 
				
			|||||||
                routes::dashboard::guild::get_reminders,
 | 
					                routes::dashboard::guild::get_reminders,
 | 
				
			||||||
                routes::dashboard::guild::edit_reminder,
 | 
					                routes::dashboard::guild::edit_reminder,
 | 
				
			||||||
                routes::dashboard::guild::delete_reminder,
 | 
					                routes::dashboard::guild::delete_reminder,
 | 
				
			||||||
                routes::dashboard::guild::get_reminder_errors,
 | 
					 | 
				
			||||||
                routes::dashboard::export::export_reminders,
 | 
					                routes::dashboard::export::export_reminders,
 | 
				
			||||||
                routes::dashboard::export::export_reminder_templates,
 | 
					                routes::dashboard::export::export_reminder_templates,
 | 
				
			||||||
                routes::dashboard::export::export_todos,
 | 
					                routes::dashboard::export::export_todos,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -171,6 +171,8 @@ pub async fn import_reminders(
 | 
				
			|||||||
                                    uid: generate_uid(),
 | 
					                                    uid: generate_uid(),
 | 
				
			||||||
                                    username: record.username,
 | 
					                                    username: record.username,
 | 
				
			||||||
                                    utc_time: record.utc_time,
 | 
					                                    utc_time: record.utc_time,
 | 
				
			||||||
 | 
					                                    status: "pending".to_string(),
 | 
				
			||||||
 | 
					                                    status_change_time: None,
 | 
				
			||||||
                                };
 | 
					                                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                create_reminder(
 | 
					                                create_reminder(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,7 @@ use crate::{
 | 
				
			|||||||
    routes::{
 | 
					    routes::{
 | 
				
			||||||
        dashboard::{
 | 
					        dashboard::{
 | 
				
			||||||
            create_database_channel, create_reminder, template_name_default, DeleteReminder,
 | 
					            create_database_channel, create_reminder, template_name_default, DeleteReminder,
 | 
				
			||||||
            DeleteReminderTemplate, PatchReminder, Reminder, ReminderError, ReminderTemplate,
 | 
					            DeleteReminderTemplate, PatchReminder, Reminder, ReminderTemplate,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        JsonResult,
 | 
					        JsonResult,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -318,15 +318,18 @@ pub async fn create_guild_reminder(
 | 
				
			|||||||
    .await
 | 
					    .await
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[get("/api/guild/<id>/reminders")]
 | 
					#[get("/api/guild/<id>/reminders?<status>")]
 | 
				
			||||||
pub async fn get_reminders(
 | 
					pub async fn get_reminders(
 | 
				
			||||||
    id: u64,
 | 
					    id: u64,
 | 
				
			||||||
    cookies: &CookieJar<'_>,
 | 
					    cookies: &CookieJar<'_>,
 | 
				
			||||||
    serenity_context: &State<Context>,
 | 
					    serenity_context: &State<Context>,
 | 
				
			||||||
    pool: &State<Pool<MySql>>,
 | 
					    pool: &State<Pool<MySql>>,
 | 
				
			||||||
 | 
					    status: Option<String>,
 | 
				
			||||||
) -> JsonResult {
 | 
					) -> JsonResult {
 | 
				
			||||||
    check_authorization!(cookies, serenity_context.inner(), id);
 | 
					    check_authorization!(cookies, serenity_context.inner(), id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let status = status.unwrap_or("pending".to_string());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sqlx::query_as_unchecked!(
 | 
					    sqlx::query_as_unchecked!(
 | 
				
			||||||
        Reminder,
 | 
					        Reminder,
 | 
				
			||||||
        "SELECT
 | 
					        "SELECT
 | 
				
			||||||
@@ -355,10 +358,13 @@ pub async fn get_reminders(
 | 
				
			|||||||
         reminders.tts,
 | 
					         reminders.tts,
 | 
				
			||||||
         reminders.uid,
 | 
					         reminders.uid,
 | 
				
			||||||
         reminders.username,
 | 
					         reminders.username,
 | 
				
			||||||
         reminders.utc_time
 | 
					         reminders.utc_time,
 | 
				
			||||||
 | 
					         reminders.status,
 | 
				
			||||||
 | 
					         reminders.status_change_time
 | 
				
			||||||
        FROM reminders
 | 
					        FROM reminders
 | 
				
			||||||
        LEFT JOIN channels ON channels.id = reminders.channel_id
 | 
					        LEFT JOIN channels ON channels.id = reminders.channel_id
 | 
				
			||||||
        WHERE `status` = 'pending' AND reminders.guild_id = (SELECT id FROM guilds WHERE guild = ?)",
 | 
					        WHERE FIND_IN_SET(`status`, ?) AND reminders.guild_id = (SELECT id FROM guilds WHERE guild = ?)",
 | 
				
			||||||
 | 
					        status,
 | 
				
			||||||
        id
 | 
					        id
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    .fetch_all(pool.inner())
 | 
					    .fetch_all(pool.inner())
 | 
				
			||||||
@@ -567,7 +573,9 @@ pub async fn edit_reminder(
 | 
				
			|||||||
         reminders.tts,
 | 
					         reminders.tts,
 | 
				
			||||||
         reminders.uid,
 | 
					         reminders.uid,
 | 
				
			||||||
         reminders.username,
 | 
					         reminders.username,
 | 
				
			||||||
         reminders.utc_time
 | 
					         reminders.utc_time,
 | 
				
			||||||
 | 
					         reminders.status,
 | 
				
			||||||
 | 
					         reminders.status_change_time
 | 
				
			||||||
        FROM reminders
 | 
					        FROM reminders
 | 
				
			||||||
        LEFT JOIN channels ON channels.id = reminders.channel_id
 | 
					        LEFT JOIN channels ON channels.id = reminders.channel_id
 | 
				
			||||||
        WHERE uid = ?",
 | 
					        WHERE uid = ?",
 | 
				
			||||||
@@ -591,7 +599,10 @@ pub async fn delete_reminder(
 | 
				
			|||||||
    reminder: Json<DeleteReminder>,
 | 
					    reminder: Json<DeleteReminder>,
 | 
				
			||||||
    pool: &State<Pool<MySql>>,
 | 
					    pool: &State<Pool<MySql>>,
 | 
				
			||||||
) -> JsonResult {
 | 
					) -> JsonResult {
 | 
				
			||||||
    match sqlx::query!("UPDATE reminders SET `status` = 'deleted' WHERE uid = ?", reminder.uid)
 | 
					    match sqlx::query!(
 | 
				
			||||||
 | 
					        "UPDATE reminders SET `status` = 'deleted', `status_change_time` = NOW() WHERE uid = ?",
 | 
				
			||||||
 | 
					        reminder.uid
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    .execute(pool.inner())
 | 
					    .execute(pool.inner())
 | 
				
			||||||
    .await
 | 
					    .await
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -604,35 +615,3 @@ pub async fn delete_reminder(
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
#[get("/api/guild/<id>/errors")]
 | 
					 | 
				
			||||||
pub async fn get_reminder_errors(
 | 
					 | 
				
			||||||
    id: u64,
 | 
					 | 
				
			||||||
    cookies: &CookieJar<'_>,
 | 
					 | 
				
			||||||
    serenity_context: &State<Context>,
 | 
					 | 
				
			||||||
    pool: &State<Pool<MySql>>,
 | 
					 | 
				
			||||||
) -> JsonResult {
 | 
					 | 
				
			||||||
    check_authorization!(cookies, serenity_context.inner(), id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sqlx::query_as_unchecked!(
 | 
					 | 
				
			||||||
        ReminderError,
 | 
					 | 
				
			||||||
        "SELECT
 | 
					 | 
				
			||||||
         reminders.status,
 | 
					 | 
				
			||||||
         reminders.utc_time,
 | 
					 | 
				
			||||||
         reminders.name,
 | 
					 | 
				
			||||||
         reminders.uid,
 | 
					 | 
				
			||||||
         reminders.channel_id AS channel
 | 
					 | 
				
			||||||
        FROM reminders
 | 
					 | 
				
			||||||
        LEFT JOIN channels ON channels.id = reminders.channel_id
 | 
					 | 
				
			||||||
        WHERE (`status` = 'failed' OR reminders.channel_id IS NULL) AND reminders.guild_id = (SELECT id FROM guilds WHERE guild = ?)",
 | 
					 | 
				
			||||||
        id
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    .fetch_all(pool.inner())
 | 
					 | 
				
			||||||
    .await
 | 
					 | 
				
			||||||
    .map(|r| Ok(json!(r)))
 | 
					 | 
				
			||||||
    .unwrap_or_else(|e| {
 | 
					 | 
				
			||||||
        warn!("Failed to complete SQL query: {:?}", e);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        json_err!("Could not load reminders")
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -150,18 +150,8 @@ pub struct Reminder {
 | 
				
			|||||||
    uid: String,
 | 
					    uid: String,
 | 
				
			||||||
    username: Option<String>,
 | 
					    username: Option<String>,
 | 
				
			||||||
    utc_time: NaiveDateTime,
 | 
					    utc_time: NaiveDateTime,
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Serialize)]
 | 
					 | 
				
			||||||
pub struct ReminderError {
 | 
					 | 
				
			||||||
    #[serde(with = "string")]
 | 
					 | 
				
			||||||
    channel: u64,
 | 
					 | 
				
			||||||
    status: String,
 | 
					    status: String,
 | 
				
			||||||
    #[serde(default = "name_default")]
 | 
					    status_change_time: Option<NaiveDateTime>,
 | 
				
			||||||
    name: String,
 | 
					 | 
				
			||||||
    #[serde(default)]
 | 
					 | 
				
			||||||
    uid: String,
 | 
					 | 
				
			||||||
    utc_time: NaiveDateTime,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Serialize, Deserialize)]
 | 
					#[derive(Serialize, Deserialize)]
 | 
				
			||||||
@@ -574,7 +564,9 @@ pub async fn create_reminder(
 | 
				
			|||||||
             reminders.tts,
 | 
					             reminders.tts,
 | 
				
			||||||
             reminders.uid,
 | 
					             reminders.uid,
 | 
				
			||||||
             reminders.username,
 | 
					             reminders.username,
 | 
				
			||||||
             reminders.utc_time
 | 
					             reminders.utc_time,
 | 
				
			||||||
 | 
					             reminders.status,
 | 
				
			||||||
 | 
					             reminders.status_change_time
 | 
				
			||||||
            FROM reminders
 | 
					            FROM reminders
 | 
				
			||||||
            LEFT JOIN channels ON channels.id = reminders.channel_id
 | 
					            LEFT JOIN channels ON channels.id = reminders.channel_id
 | 
				
			||||||
            WHERE uid = ?",
 | 
					            WHERE uid = ?",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -688,6 +688,44 @@ li.highlight {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* END */
 | 
					/* END */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					div.reminderError {
 | 
				
			||||||
 | 
					    margin: 10px;
 | 
				
			||||||
 | 
					    padding: 14px;
 | 
				
			||||||
 | 
					    background-color: #f5f5f5;
 | 
				
			||||||
 | 
					    border-radius: 8px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					div.reminderError .errorHead {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-direction: row;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					div.reminderError .errorIcon {
 | 
				
			||||||
 | 
					    padding: 8px;
 | 
				
			||||||
 | 
					    border-radius: 4px;
 | 
				
			||||||
 | 
					    margin-right: 12px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					div.reminderError .errorIcon.deleted {
 | 
				
			||||||
 | 
					    background-color: #e7e5e4;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					div.reminderError .errorIcon.success {
 | 
				
			||||||
 | 
					    background-color: #d9f99d;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					div.reminderError .errorIcon.errored {
 | 
				
			||||||
 | 
					    background-color: #fecaca;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					div.reminderError .errorHead .reminderName {
 | 
				
			||||||
 | 
					    font-size: 1rem;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					    color: rgb(54, 54, 54);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* other stuff */
 | 
					/* other stuff */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.half-rem {
 | 
					.half-rem {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,7 +57,7 @@ function switch_pane(selector) {
 | 
				
			|||||||
        el.classList.add("is-hidden");
 | 
					        el.classList.add("is-hidden");
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    document.getElementById(selector).classList.remove("is-hidden");
 | 
					    document.querySelector(`*[data-name=${selector}]`).classList.remove("is-hidden");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function update_select(sel) {
 | 
					function update_select(sel) {
 | 
				
			||||||
@@ -735,16 +735,19 @@ document.addEventListener("DOMContentLoaded", async () => {
 | 
				
			|||||||
                    });
 | 
					                    });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                const matches = window.location.href.match(/dashboard\/(\d+)/);
 | 
					                const matches = window.location.href.match(
 | 
				
			||||||
 | 
					                    /dashboard\/(\d+)(\/)?([a-zA-Z\-]+)?/
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
                if (matches) {
 | 
					                if (matches) {
 | 
				
			||||||
                    let id = matches[1];
 | 
					                    let id = matches[1];
 | 
				
			||||||
 | 
					                    let kind = matches[3];
 | 
				
			||||||
                    let name = guildNames[id];
 | 
					                    let name = guildNames[id];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    const event = new CustomEvent("guildSwitched", {
 | 
					                    const event = new CustomEvent("guildSwitched", {
 | 
				
			||||||
                        detail: {
 | 
					                        detail: {
 | 
				
			||||||
                            guild_name: name,
 | 
					                            guild_name: name,
 | 
				
			||||||
                            guild_id: id,
 | 
					                            guild_id: id,
 | 
				
			||||||
                            pane: "guild",
 | 
					                            pane: kind,
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +1,18 @@
 | 
				
			|||||||
function loadErrors() {
 | 
					function loadErrors() {
 | 
				
			||||||
    return fetch(`/dashboard/api/guild/${guildId()}/errors`).then((response) =>
 | 
					    return fetch(
 | 
				
			||||||
        response.json()
 | 
					        `/dashboard/api/guild/${guildId()}/reminders?status=deleted,sent,error`
 | 
				
			||||||
    );
 | 
					    ).then((response) => response.json());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
document.addEventListener("paneLoad", (ev) => {
 | 
					document.addEventListener("paneLoad", (ev) => {
 | 
				
			||||||
    if (ev.detail.pane !== "reminder-errors") {
 | 
					    if (ev.detail.pane !== "errors") {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Load errors
 | 
					    // Load errors
 | 
				
			||||||
    loadErrors().then((res) => {});
 | 
					    loadErrors().then((res) => {
 | 
				
			||||||
 | 
					        console.log(res);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $loader.classList.add("is-hidden");
 | 
					    $loader.classList.add("is-hidden");
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -332,16 +332,16 @@
 | 
				
			|||||||
                <p class="subtitle is-hidden-desktop">Press the <span class="icon"><i class="fal fa-bars"></i></span> to get started</p>
 | 
					                <p class="subtitle is-hidden-desktop">Press the <span class="icon"><i class="fal fa-bars"></i></span> to get started</p>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </section>
 | 
					        </section>
 | 
				
			||||||
        <section id="guild" class="is-hidden">
 | 
					        <section data-name="reminders" class="is-hidden">
 | 
				
			||||||
            {% include "reminder_dashboard/reminder_dashboard" %}
 | 
					            {% include "reminder_dashboard/reminder_dashboard" %}
 | 
				
			||||||
        </section>
 | 
					        </section>
 | 
				
			||||||
        <section id="reminder-errors" class="is-hidden">
 | 
					        <section data-name="errors" class="is-hidden">
 | 
				
			||||||
            {% include "reminder_dashboard/reminder_errors" %}
 | 
					            {% include "reminder_dashboard/reminder_errors" %}
 | 
				
			||||||
        </section>
 | 
					        </section>
 | 
				
			||||||
        <section id="guild-error" class="is-hidden">
 | 
					        <section data-name="guild-error" class="is-hidden">
 | 
				
			||||||
            {% include "reminder_dashboard/guild_error" %}
 | 
					            {% include "reminder_dashboard/guild_error" %}
 | 
				
			||||||
        </section>
 | 
					        </section>
 | 
				
			||||||
        <section id="user-error" class="is-hidden">
 | 
					        <section data-name="user-error" class="is-hidden">
 | 
				
			||||||
            {% include "reminder_dashboard/user_error" %}
 | 
					            {% include "reminder_dashboard/user_error" %}
 | 
				
			||||||
        </section>
 | 
					        </section>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@@ -375,16 +375,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<template id="guildListEntry">
 | 
					<template id="guildListEntry">
 | 
				
			||||||
    <li>
 | 
					    <li>
 | 
				
			||||||
        <a class="switch-pane" data-pane="guild" data-slug="reminders">
 | 
					        <a class="switch-pane" data-pane="reminders" data-slug="reminders">
 | 
				
			||||||
            <span class="icon"><i class="fas fa-map-pin"></i></span> <span class="guild-name">%guildname%</span>
 | 
					            <span class="icon"><i class="fas fa-map-pin"></i></span> <span class="guild-name">%guildname%</span>
 | 
				
			||||||
        </a>
 | 
					        </a>
 | 
				
			||||||
        <ul class="guild-submenu">
 | 
					        <ul class="guild-submenu">
 | 
				
			||||||
            <li>
 | 
					            <li>
 | 
				
			||||||
                <a class="switch-pane" data-pane="guild" data-slug="reminders">
 | 
					                <a class="switch-pane" data-pane="reminders" data-slug="reminders">
 | 
				
			||||||
                    <span class="icon"><i class="fas fa-calendar-alt"></i></span> Reminders
 | 
					                    <span class="icon"><i class="fas fa-calendar-alt"></i></span> Reminders
 | 
				
			||||||
                </a>
 | 
					                </a>
 | 
				
			||||||
                <a class="switch-pane" data-pane="reminder-errors" data-slug="errors">
 | 
					                <a class="switch-pane" data-pane="errors" data-slug="errors">
 | 
				
			||||||
                    <span class="icon"><i class="fas fa-exclamation-triangle"></i></span> Errors
 | 
					                    <span class="icon"><i class="fas fa-file-alt"></i></span> Logs
 | 
				
			||||||
                </a>
 | 
					                </a>
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
        </ul>
 | 
					        </ul>
 | 
				
			||||||
@@ -392,11 +392,11 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template id="guildReminder">
 | 
					<template id="guildReminder">
 | 
				
			||||||
    {% include "reminder_dashboard/guild_reminder" %}
 | 
					    {% include "reminder_dashboard/templates/guild_reminder" %}
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template id="guildError">
 | 
					<template id="reminderError">
 | 
				
			||||||
 | 
					    {% include "reminder_dashboard/templates/reminder_error" %}
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script src="/static/js/iro.js"></script>
 | 
					<script src="/static/js/iro.js"></script>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
    <strong>Create Reminder</strong>
 | 
					    <strong>Create Reminder</strong>
 | 
				
			||||||
    <div id="reminderCreator">
 | 
					    <div id="reminderCreator">
 | 
				
			||||||
        {% set creating = true %}
 | 
					        {% set creating = true %}
 | 
				
			||||||
        {% include "reminder_dashboard/guild_reminder" %}
 | 
					        {% include "reminder_dashboard/templates/guild_reminder" %}
 | 
				
			||||||
        {% set creating = false %}
 | 
					        {% set creating = false %}
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <br>
 | 
					    <br>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,51 @@
 | 
				
			|||||||
<div>
 | 
					<div>
 | 
				
			||||||
 | 
					    <div class="reminderError">
 | 
				
			||||||
 | 
					        <div class="errorHead">
 | 
				
			||||||
 | 
					            <div class="errorIcon deleted">
 | 
				
			||||||
 | 
					                <span class="icon">
 | 
				
			||||||
 | 
					                    <i class="fas fa-trash"></i>
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="reminderName">
 | 
				
			||||||
 | 
					                Reminder
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="reminderTime">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="reminderError">
 | 
				
			||||||
 | 
					        <div class="errorHead">
 | 
				
			||||||
 | 
					            <div class="errorIcon errored">
 | 
				
			||||||
 | 
					                <span class="icon">
 | 
				
			||||||
 | 
					                    <i class="fas fa-exclamation-triangle"></i>
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="reminderName">
 | 
				
			||||||
 | 
					                Reminder
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="reminderTime">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="reminderError">
 | 
				
			||||||
 | 
					        <div class="errorHead">
 | 
				
			||||||
 | 
					            <div class="errorIcon success">
 | 
				
			||||||
 | 
					                <span class="icon">
 | 
				
			||||||
 | 
					                    <i class="fas fa-check"></i>
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="reminderName">
 | 
				
			||||||
 | 
					                Reminder
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="reminderTime">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script src="/static/js/reminder_errors.js"></script>
 | 
					<script src="/static/js/reminder_errors.js"></script>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					<div class="reminderError">
 | 
				
			||||||
 | 
					    <div class="errorIcon">
 | 
				
			||||||
 | 
					        <span>
 | 
				
			||||||
 | 
					            <i class="fas fa-trash"></i>
 | 
				
			||||||
 | 
					        </span>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					        <span class="reminderName"></span>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					        <span></span>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user