β˜• The Study Nook

A gentle reminder

Progress counts, even when it happens one small step at a time.

🌿 Start here

πŸ—“οΈ Planning

label: 🌿 New Assignment
icon: plus-circle
style: primary
id: new-assignment
hidden: false
actions:
  - type: templaterCreateNote
    templateFile: "study nook/School/Templates/Assignment Template.md"
    folderPath: "study nook/School/Assignments"
    fileName: "New Assignment"
    openNote: true
label: πŸ“– New Weekly Plan
icon: calendar-plus
style: primary
id: new-weekly-plan
hidden: false
actions:
  - type: templaterCreateNote
    templateFile: "study nook/School/Templates/Weekly Plan Template.md"
    folderPath: "study nook/School"
    fileName: "New Weekly Plan"
    openNote: true
label: 🌸 Schedule Work Session
icon: calendar-clock
style: primary
id: schedule-work-session
hidden: false
actions:
  - type: runTemplaterFile
    templateFile: "study nook/School/Templates/Schedule Work Session.md"
// 🌿 Find the current weekly plan
const today = dv.date("today");

const monday = today.minus({
  days: today.weekday - 1
});

const plans = dv.pages('"study nook/School/Weekly Plans"')
  .where(p => {
    if (!p.week_start) return false;

    const date = dv.date(p.week_start);

    return date &&
      date.toISODate() === monday.toISODate();
  });

if (plans.length > 0) {
  const plan = plans.first();

  dv.paragraph(
    "🌿 " +
    "[[" + plan.file.path +
    "|Open this week's plan]]"
  );

} else {
  dv.paragraph(
    "🌱 No weekly plan created yet for this week!"
  );
}

πŸͺ΄ What Should I Work On?

A little guidance for when starting feels like the hardest part. 🌸

// =============================================
// 🌿 STUDY NOOK: WHAT SHOULD I WORK ON?
// =============================================

const today = dv.date("today").startOf("day");
const todayISO = today.toISODate();

// 🌸 Find all active assignments
const assignments = dv.pages(
  '"study nook/School/Assignments"'
);

// Convert date properties consistently
function toDate(value) {
  if (!value) return null;

  try {
    const parsed = dv.date(value);
    return parsed && parsed.isValid
      ? parsed.startOf("day")
      : null;
  } catch {
    return null;
  }
}

// Read work_days, whether a single date or list
function getWorkDays(page) {
  if (!page.work_days) return [];

  const values = Array.isArray(page.work_days)
    ? page.work_days
    : (typeof page.work_days.array === "function"
        ? page.work_days.array()
        : [page.work_days]);

  return values
    .map(value => {
      const date = toDate(value);
      return date ? date.toISODate() : null;
    })
    .filter(Boolean);
}

// Check whether an assignment is completed
function isComplete(page) {
  const status = String(page.status ?? "")
    .trim()
    .toLowerCase();

  return ["done", "completed", "complete"].includes(status)
    || page.completed === true;
}

// 🌿 Calculate recommendation scores
function analyze(page) {
  const due = toDate(page.due);
  const daysUntilDue = due
    ? Math.round(due.diff(today, "days").days)
    : null;

  const status = String(page.status ?? "")
    .trim()
    .toLowerCase();

  const priority = String(page.priority ?? "Medium")
    .trim()
    .toLowerCase();

  const workDays = getWorkDays(page);
  const scheduledToday = workDays.includes(todayISO);

  let score = 0;
  let reason = "Ready when you are";

  // Deadline urgency
  if (daysUntilDue !== null) {
    if (daysUntilDue < 0) {
      score += 100;
      reason = "⏰ Overdue";
    } else if (daysUntilDue === 0) {
      score += 85;
      reason = "πŸ”₯ Due today";
    } else if (daysUntilDue === 1) {
      score += 65;
      reason = "🌸 Due tomorrow";
    } else if (daysUntilDue === 2) {
      score += 45;
      reason = "πŸ“… Due in 2 days";
    } else if (daysUntilDue <= 7) {
      score += 20;
      reason = "πŸ“– Due this week";
    }
  }

  // Scheduled work takes priority
  if (scheduledToday) {
    score += 55;
    if (daysUntilDue === null || daysUntilDue > 2) {
      reason = "🌿 Scheduled for today";
    }
  }

  // Assignment priority
  if (priority === "high") score += 25;
  if (priority === "medium") score += 10;

  // Encourage finishing started assignments
  if (status === "in progress") score += 15;

  return {
    page,
    score,
    reason,
    priority,
    daysUntilDue,
    scheduledToday,
    status
  };
}

// β˜• Select unfinished assignments
const ranked = assignments
  .where(page => !isComplete(page))
  .array()
  .map(analyze)
  .sort((a, b) => {
    if (b.score !== a.score) return b.score - a.score;

    return (a.daysUntilDue ?? Infinity)
      - (b.daysUntilDue ?? Infinity);
  });

// 🌱 Give a gentle five-minute starting step
function firstStep(item) {
  const name = item.page.file.name.toLowerCase();
  const className = String(item.page.class ?? "")
    .toLowerCase();

  const combined = name + " " + className;

  if (/static|engr 210/.test(combined)) {
    return "Open the next problem and draw the free-body diagram.";
  }

  if (/calc|math/.test(combined)) {
    return "Open the assignment, identify the next problem, and write down the formula or concept you need.";
  }

  if (/statistic|probability/.test(combined)) {
    return "Read the next problem and identify the given values and what you need to find.";
  }

  if (/matlab|me 273|coding/.test(combined)) {
    return "Open MATLAB and your assignment. Choose one small section to work on.";
  }

  if (/me 287|design|solidworks|dino/.test(combined)) {
    return "Open your project files and choose one small design or documentation task.";
  }

  return "Open the assignment and identify the smallest task you can complete in five minutes.";
}

// 🌸 DISPLAY RECOMMENDATIONS
if (ranked.length === 0) {

  dv.paragraph(
    "🌸 Everything is finished! Enjoy a well-earned break."
  );

} else {

  const best = ranked[0];

  dv.header(3, "✨ Your recommended next task");

  dv.paragraph(best.page.file.link);

  dv.paragraph(
    "**" + best.reason + "**" +
    " Β· " +
    best.priority.charAt(0).toUpperCase() +
    best.priority.slice(1) +
    " priority"
  );

  dv.paragraph(
    "🌿 **Your first five minutes:** " +
    firstStep(best)
  );

  if (ranked.length > 1) {

    dv.header(3, "🌷 Other options");

    dv.table(
      ["Assignment", "Why it's here"],
      ranked.slice(1, 3).map(item => [
        item.page.file.link,
        item.reason
      ])
    );

  }

}

β˜• What Do You Have Energy For?

A little progress is still progress. Choose what feels manageable today. 🌿

// ==========================================
// 🌿 STUDY NOOK: COZY ENERGY SELECTOR
// ==========================================

// 🌸 Read existing assignments
const assignments = dv.pages(
  '"study nook/School/Assignments"'
);

const today = moment().startOf("day");

// 🌱 Date helper
function parseDate(value) {
  if (!value) return null;

  const raw = typeof value.toISODate === "function"
    ? value.toISODate()
    : String(value);

  const date = moment(
    raw,
    ["YYYY-MM-DD", "MM/DD/YY", "MM/DD/YYYY"],
    true
  );

  return date.isValid() ? date : null;
}

// 🌷 Completion helper
function isComplete(page) {
  const status = String(page.status ?? "")
    .trim().toLowerCase();

  return ["done", "completed", "complete"]
    .includes(status) || page.completed === true;
}

// ⏳ Read estimates in minutes
function getEstimate(page) {
  const value = page.estimate;

  if (value === undefined || value === null) {
    return null;
  }

  const n = Number(value);

  return Number.isFinite(n) && n > 0 ? n : null;
}

// πŸ“… Check scheduled workdays
function scheduledToday(page) {
  if (!page.work_days) return false;

  const values = typeof page.work_days.array === "function"
    ? page.work_days.array()
    : Array.isArray(page.work_days)
      ? page.work_days
      : [page.work_days];

  return values.some(value => {
    const date = parseDate(value);

    return date &&
      date.format("YYYY-MM-DD") ===
      today.format("YYYY-MM-DD");
  });
}

// 🌿 Give every assignment an urgency score
function score(page) {
  let points = 0;

  const due = parseDate(page.due);

  if (due) {
    const days = due.startOf("day").diff(today, "days");

    if (days < 0) points += 100;
    else if (days === 0) points += 85;
    else if (days === 1) points += 65;
    else if (days <= 3) points += 40;
    else if (days <= 7) points += 20;
  }

  if (scheduledToday(page)) points += 55;

  const priority = String(page.priority ?? "")
    .toLowerCase();

  if (priority === "high") points += 25;
  if (priority === "medium") points += 10;

  if (String(page.status ?? "").toLowerCase()
      === "in progress") {
    points += 15;
  }

  return points;
}

// πŸ“š All unfinished assignments
const active = assignments
  .where(p => !isComplete(p))
  .array()
  .sort((a, b) => score(b) - score(a));

// ==========================================
// 🌸 INTERACTIVE MENU
// ==========================================

const root = dv.container.createDiv();

root.style.padding = "16px";
root.style.border = "1px solid var(--background-modifier-border)";
root.style.borderRadius = "12px";

const menu = root.createDiv();

menu.style.display = "flex";
menu.style.flexWrap = "wrap";
menu.style.gap = "8px";
menu.style.marginBottom = "16px";

const result = root.createDiv();

let currentMode = "15";
let currentIndex = 0;

// 🌱 Recommend a five-minute step
function firstStep(page) {
  const name = (
    page.file.name + " " +
    String(page.class ?? "")
  ).toLowerCase();

  if (/statistic|probability/.test(name)) {
    return "Read one problem and write down the given information.";
  }

  if (/static|engr 210/.test(name)) {
    return "Open one problem and sketch its free-body diagram.";
  }

  if (/calc|math/.test(name)) {
    return "Read the next problem and identify the formula you'll need.";
  }

  if (/matlab|me 273|coding/.test(name)) {
    return "Open MATLAB and identify one small piece of code to work on.";
  }

  if (/dino|solidworks|design|me 287/.test(name)) {
    return "Open your project and choose one tiny design or documentation task.";
  }

  return "Open the assignment and identify the smallest next action.";
}

// β˜• Filter by available time
function choicesFor(mode) {
  if (mode === "5") {
    return active;
  }

  if (mode === "15") {
    // Prefer smaller assignments when available.
    const short = active.filter(p => {
      const estimate = getEstimate(p);
      return estimate !== null && estimate <= 30;
    });

    return short.length ? short : active;
  }

  // Focus mode: prefer more substantial assignments.
  const long = active.filter(p => {
    const estimate = getEstimate(p);
    return estimate !== null && estimate >= 45;
  });

  return long.length ? long : active;
}

// 🌷 Create a mode button
function addMode(label, mode) {
  const button = menu.createEl("button", {
    text: label
  });

  button.style.cursor = "pointer";

  button.addEventListener("click", () => {
    currentMode = mode;
    currentIndex = 0;
    render();
  });

  return {button, mode};
}

const buttons = [
  addMode("🌱 Just 5 minutes", "5"),
  addMode("β˜• I have 15 minutes", "15"),
  addMode("πŸ“š Ready to focus", "focus")
];

// ==========================================
// πŸ•―οΈ DISPLAY SELECTED TASK
// ==========================================

function render() {
  result.replaceChildren();

  buttons.forEach(({button, mode}) => {
    const selected = mode === currentMode;

    button.style.background = selected
      ? "var(--interactive-accent)"
      : "var(--background-secondary)";

    button.style.color = selected
      ? "var(--text-on-accent)"
      : "var(--text-normal)";
  });

  const options = choicesFor(currentMode);

  if (!options.length) {
    result.createEl("p", {
      text: "🌸 No unfinished assignments! Enjoy your break."
    });
    return;
  }

  currentIndex = currentIndex % options.length;
  const page = options[currentIndex];

  const heading = currentMode === "5"
    ? "🌱 Your tiny first step"
    : currentMode === "15"
      ? "β˜• Your mini study session"
      : "πŸ“š Your focus session";

  result.createEl("h4", {text: heading});

  const link = result.createEl("a", {
    text: page.file.name
  });

  link.style.cursor = "pointer";
  link.style.fontWeight = "600";

  link.addEventListener("click", async () => {
    const file = app.vault.getAbstractFileByPath(
      page.file.path
    );

    if (file) {
      await app.workspace.getLeaf(false).openFile(file);
    }
  });

  const estimate = getEstimate(page);
  const due = parseDate(page.due);

  let details = [];

  if (estimate !== null) {
    details.push("⏳ " + estimate + " min estimated");
  }

  if (due) {
    details.push("πŸ“… Due " + due.format("MMM D"));
  }

  if (scheduledToday(page)) {
    details.push("🌿 Scheduled today");
  }

  result.createEl("p", {
    text: details.join(" · ") || "🌷 Ready when you are"
  });

  let guidance = "";

  if (currentMode === "5") {
    guidance = firstStep(page);

  } else if (currentMode === "15") {
    guidance =
      "Set a 15-minute timer. " +
      firstStep(page) +
      " Keep going on that one small part until your timer ends.";

  } else {
    guidance =
      "Give this assignment a focused work block. " +
      firstStep(page) +
      " Then continue through the next manageable section.";
  }

  const guidanceBox = result.createDiv();

  guidanceBox.style.padding = "12px";
  guidanceBox.style.background =
    "var(--background-secondary)";
  guidanceBox.style.borderRadius = "8px";
  guidanceBox.style.marginBottom = "12px";

  guidanceBox.createEl("strong", {
    text: "🌿 Your next step"
  });

  guidanceBox.createEl("p", {
    text: guidance
  });

  // 🌸 Pick an alternative
  if (options.length > 1) {
    const another = result.createEl("button", {
      text: "🌸 Pick Something Else"
    });

    another.addEventListener("click", () => {
      currentIndex = (currentIndex + 1) % options.length;
      render();
    });
  }

  result.createEl("p", {
    text: "πŸ•―οΈ A little progress is still progress."
  }).style.color = "var(--text-muted)";
}

// Start with the cozy 15-minute option
render();

πŸͺ· This Week at a Glance

// 🌿 CURRENT WEEK
const today = dv.date("today");
const monday = today.minus({ days: today.weekday - 1 });
const sunday = monday.plus({ days: 6 });

dv.paragraph(
  "πŸ—“οΈ " +
  monday.toFormat("MMMM d") +
  " – " +
  sunday.toFormat("MMMM d, yyyy")
);


// 🌸 FIND THIS WEEK'S PLAN
const plans = dv.pages('"study nook/School/Weekly Plans"')
  .where(p => {
    if (!p.week_start) return false;

    const date = dv.date(p.week_start);
    return date &&
      date.toISODate() === monday.toISODate();
  });

const currentPlan = plans.first();


// 🌱 THREE PRIORITIES
dv.header(3, "🌱 Three priorities");

if (!currentPlan) {
  dv.paragraph("🌱 No weekly plan created for this week yet.");

} else {
  const content = await dv.io.load(currentPlan.file.path);
  let priorities = [];

  if (content) {
    const lines = content.split(/\r?\n/);
    let inPriorities = false;

    for (const line of lines) {
      const heading = line.match(/^(#{1,6})\s+(.+)$/);

      if (heading) {
        // Recognizes headings regardless of their emoji
        const headingText = heading[2]
          .replace(/^.*?(?=Three priorities)/i, "")
          .replace(/#+\s*$/, "")
          .trim()
          .toLowerCase();

        if (headingText === "three priorities") {
          inPriorities = true;
          continue;
        }

        if (inPriorities) break;
      }

      if (inPriorities) {
        const item = line.match(/^\s*\d+[.)]\s+(.+)$/);

        if (item && item[1].trim()) {
          priorities.push(item[1].trim());
        }
      }
    }
  }

  if (priorities.length) {
    dv.list(priorities.slice(0, 3));
  } else {
    dv.paragraph("🌷 No priorities added to this week's plan yet.");
  }
}


// πŸ“š ASSIGNMENTS DUE THIS WEEK
const assignments = dv.pages('"study nook/School/Assignments"')
  .where(a => a.due)
  .where(a => {
    const due = dv.date(a.due);
    return due &&
      due >= monday &&
      due < sunday.plus({ days: 1 });
  })
  .sort(a => a.due, "asc");

function isComplete(a) {
  const status = String(a.status ?? "")
    .trim()
    .toLowerCase();

  return ["done", "completed", "complete"].includes(status) ||
    a.completed === true;
}

const completed = assignments.where(a => isComplete(a)).length;
const total = assignments.length;
const percent = total
  ? Math.round((completed / total) * 100)
  : 0;


// πŸ“š ASSIGNMENT PROGRESS
dv.header(3, "πŸ“š Assignment progress");

dv.paragraph(
  `**${completed} of ${total} completed (${percent}%)**`
);

const bar = dv.el("div", "");
bar.style.width = "100%";
bar.style.height = "16px";
bar.style.background = "#d1cbb9";
bar.style.borderRadius = "10px";
bar.style.overflow = "hidden";

const fill = bar.createEl("div");
fill.style.width = percent + "%";
fill.style.height = "100%";
fill.style.background = "#81977d";
fill.style.borderRadius = "10px";


// ⏰ DEADLINES THIS WEEK
dv.header(3, "⏰ Deadlines this week");

if (total === 0) {
  dv.paragraph("🌿 No assignments due this week!");

} else {
  dv.table(
    ["Assignment", "Due", "Status"],
    assignments.map(a => [
      a.file.link,
      dv.date(a.due).toFormat("MMM d"),
      isComplete(a)
        ? "βœ… Done"
        : (a.status ?? "Not started")
    ])
  );
}

πŸ•―οΈ Today's focus

  • Must-do: write one clear next action here
  • Study: choose one concept to practice
  • Small win: do a 10-minute starter task

πŸ”” Due today

TABLE WITHOUT ID
  file.link AS "Assignment",
  class AS "Class",
  priority AS "Priority",
  status AS "Status",
  round(estimate / 60, 1) AS "Hours"
FROM "study nook/School/Assignments"
WHERE type = "assignment"
  AND due = date(today)
  AND status != "Done"
SORT priority ASC

⏳ Due in the next 7 days

TABLE WITHOUT ID
  file.link AS "Assignment",
  class AS "Class",
  due AS "Due",
  priority AS "Priority",
  status AS "Status"
FROM "study nook/School/Assignments"
WHERE type = "assignment"
  AND due >= date(today)
  AND due <= date(today) + dur(7 days)
  AND status != "Done"
SORT due ASC

🌱 Progress by class

TABLE WITHOUT ID
  key AS "Class",
  length(rows) AS "Assignments",
  length(filter(rows, (r) => r.status = "Done")) AS "Done",
  length(filter(rows, (r) => r.status != "Done")) AS "Remaining",
  round(100 * length(filter(rows, (r) => r.status = "Done")) / length(rows), 0) + "%" AS "Complete"
FROM "study nook/School/Assignments"
WHERE type = "assignment"
GROUP BY class
SORT key ASC

πŸ“… All upcoming assignments

TABLE WITHOUT ID
  file.link AS "Assignment",
  class AS "Class",
  due AS "Due",
  priority AS "Priority",
  status AS "Status",
  round(estimate / 60, 1) AS "Hours"
FROM "study nook/School/Assignments"
SORT due ASC

🏡️Past due Assignments

⏰ Past Due Assignments

🌿 Let's catch up on anything that slipped past its deadline.

TABLE WITHOUT ID
file.link AS "Assignment",
class AS "Class",
due AS "Due",
status AS "Status"
FROM "study nook/School/Assignments"
WHERE due
  AND date(due) < date(today)
  AND lower(string(status)) != "done"
  AND lower(string(status)) != "completed"
  AND lower(string(status)) != "complete"
  AND completed != true
SORT due ASC

πŸ’šCompleted Assignments

βœ… Completed Assignments

🌿 All finished homework, safely tucked away!

TABLE WITHOUT ID
file.link AS "Assignment",
due AS "Due",
status AS "Status"
FROM "study nook/School/Assignments" OR "study nook/School/Done"
WHERE lower(string(status)) = "done"
   OR lower(string(status)) = "completed"
   OR lower(string(status)) = "complete"
   OR completed = true
SORT due DESC

πŸͺ» Weekly reset

// ======================================
// 🌸 STUDY NOOK: SUNDAY RESET
// ======================================

// 🌿 Find this week and next week
const today = dv.date("today");
const monday = today.minus({
  days: today.weekday - 1
});
const sunday = monday.plus({ days: 6 });
const nextMonday = monday.plus({ days: 7 });
const nextSunday = nextMonday.plus({ days: 6 });

dv.paragraph(
  "β˜• **Week of " +
  monday.toFormat("MMMM d") +
  " – " +
  sunday.toFormat("MMMM d, yyyy") +
  "**"
);

dv.paragraph(
  "*A gentle moment to celebrate your progress and prepare for what comes next.*"
);

// 🌱 Get assignment information
const assignments = dv.pages(
  '"study nook/School/Assignments"'
);

// Convert dates safely
function dateKey(value) {
  if (!value) return "";

  try {
    const parsed = dv.date(value);
    return parsed ? parsed.toISODate() : "";
  } catch {
    return "";
  }
}

// Check completion
function isComplete(page) {
  const status = String(page.status ?? "")
    .trim()
    .toLowerCase();

  return [
    "done",
    "complete",
    "completed"
  ].includes(status) || page.completed === true;
}

const start = monday.toISODate();
const end = sunday.toISODate();

// ======================================
// 🌸 CELEBRATE YOUR PROGRESS
// ======================================

dv.header(3, "🌸 Celebrate your progress");

// Assignments due this week that are done
const finished = assignments
  .where(p => {
    const due = dateKey(p.due);
    return isComplete(p) &&
      due >= start && due <= end;
  })
  .sort(p => p.due, "asc");

if (finished.length > 0) {
  dv.paragraph(
    "🌿 You completed **" +
    finished.length +
    "** assignment(s) due this week!"
  );

  dv.list(
    finished.map(p => p.file.link)
  );
} else {
  dv.paragraph(
    "🌷 No completed assignments due this week are recorded yet. Every little step still counts!"
  );
}

// ======================================
// πŸ‚ THINGS TO CARRY FORWARD
// ======================================

dv.header(3, "πŸ‚ Things to carry forward");

// Unfinished assignments due by Sunday
const unfinished = assignments
  .where(p => {
    const due = dateKey(p.due);
    return due &&
      due <= end &&
      !isComplete(p);
  })
  .sort(p => p.due, "asc");

if (unfinished.length > 0) {

  dv.paragraph(
    "These assignments are still unfinished and may need attention:"
  );

  dv.table(
    ["Assignment", "Due", "Status"],
    unfinished.slice(0, 8).map(p => [
      p.file.link,
      dv.date(p.due).toFormat("MMM d"),
      p.status ?? "Not started"
    ])
  );

  if (unfinished.length > 8) {
    dv.paragraph(
      "🌿 " + (unfinished.length - 8) +
      " more unfinished assignments. See your Past Due section for the full list."
    );
  }

} else {
  dv.paragraph(
    "🌸 Nothing unfinished with a deadline through this Sunday. Beautiful!"
  );
}

// ======================================
// 🌱 PREPARE FOR NEXT WEEK
// ======================================

dv.header(3, "🌱 Prepare for next week");

dv.paragraph(
  "πŸ“… **" +
  nextMonday.toFormat("MMMM d") +
  " – " +
  nextSunday.toFormat("MMMM d, yyyy") +
  "**"
);

// Find next week's plan
const plans = dv.pages(
  '"study nook/School/Weekly Plans"'
);

const nextPlan = plans.find(p =>
  dateKey(p.week_start ?? p.week) ===
  nextMonday.toISODate()
);

if (nextPlan) {
  dv.paragraph(
    "🌿 Your next weekly plan is ready!"
  );
  dv.paragraph(nextPlan.file.link);
} else {
  dv.paragraph(
    "🌷 No plan for next week yet. Use your **New Weekly Plan** button above to create one!"
  );
}

// ======================================
// β˜• GENTLE RESET CHECKLIST
// ======================================

dv.header(3, "β˜• Your Sunday ritual");

dv.paragraph(
  "🌸 **1. Celebrate:** Look at what you finished."
);

dv.paragraph(
  "πŸ‚ **2. Carry over:** Decide which unfinished tasks need attention."
);

dv.paragraph(
  "πŸ“– **3. Plan:** Open next week's plan and choose three priorities."
);

dv.paragraph(
  "πŸ“… **4. Schedule:** Give your homework realistic workdays."
);

dv.paragraph(
  "πŸͺ· **5. Rest:** Close your planner and enjoy your evening."
);

dv.paragraph(
  "*You don't have to finish everything to have made progress this week. πŸ’š*"
);

🧺 Unfinished tasks

Tasks plugin query; task dates use Obsidian Tasks syntax, e.g. πŸ“… 2026-10-26.

not done
path includes School
sort by due
Built with LogoFlowershow