Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Deploy GitHub Pages

on:
push:
branches:
- main
paths:
- docs/**
- .github/workflows/pages.yml
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: github-pages
cancel-in-progress: true

jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Check out site
uses: actions/checkout@v4

- name: Configure GitHub Pages
uses: actions/configure-pages@v5

- name: Upload site artifact
uses: actions/upload-pages-artifact@v3
with:
path: docs

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<p align="center">
<img src="assets/logo.svg" alt="UIT CLI & UIT Studio" width="460">
<img src="assets/logo.svg" alt="UIT STUDIO" width="460">
</p>

<h1 align="center">UIT STUDIO</h1>

<p align="center">
<strong>The modern command-line tool and AI desktop workspace for UIT Moodle LMS.</strong>
<strong>One workspace. Every course.</strong>
</p>

---

## UIT CLI

Fast terminal access to courses, assignments, grades, and materials.
Your Moodle, at terminal speed.

<details>
<summary>macOS</summary>
Expand Down Expand Up @@ -66,7 +68,7 @@ Use `uit login --legacy` for the legacy Moodle portal. An SSO session from UIT S

## UIT Studio

Desktop course workspace with an optional Codex study copilot.
Your course space. Built to focus.

<details>
<summary>macOS</summary>
Expand Down Expand Up @@ -123,13 +125,13 @@ codex --login
The ChatGPT desktop app alone is not sufficient. Sign in to UIT Studio with UIT SSO or a legacy Moodle account.

<p align="center">
<img src="assets/studio-courses.png" alt="UIT Studio courses dashboard" width="860">
<img src="docs/assets/studio-courses.png" alt="UIT Studio courses workspace" width="860">
</p>

Chat with Codex using course context, then continue the same thread in Codex CLI or the ChatGPT desktop app.

<p align="center">
<img src="assets/studio-chat.png" alt="Codex AI Workspace" width="860" style="border-radius: 8px;">
<img src="docs/assets/studio-chat.png" alt="UIT Studio agent workspace" width="860" style="border-radius: 8px;">
</p>

---
Expand Down
Binary file removed assets/course-grades.png
Binary file not shown.
Binary file removed assets/course-materials.png
Binary file not shown.
Binary file removed assets/course-members.png
Binary file not shown.
Binary file removed assets/studio-chat.png
Binary file not shown.
Binary file removed assets/studio-courses.png
Binary file not shown.
Empty file added docs/.nojekyll
Empty file.
File renamed without changes
Binary file added docs/assets/studio-chat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/studio-courses.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/uit-logo-official.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
425 changes: 425 additions & 0 deletions docs/index.html

Large diffs are not rendered by default.

81 changes: 81 additions & 0 deletions docs/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
document.addEventListener("DOMContentLoaded", () => {
const nav = document.getElementById("main-nav");
const updateNav = () => nav?.classList.toggle("is-scrolled", window.scrollY > 12);
window.addEventListener("scroll", updateNav, { passive: true });
updateNav();

const themeToggle = document.getElementById("theme-toggle");
const themeMeta = document.querySelector('meta[name="theme-color"]');
const themeColors = { dark: "#040c19", light: "#eaf6ff" };
const savedTheme = localStorage.getItem("uit-theme")
|| (window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark");
const applyTheme = (theme) => {
const nextTheme = theme === "light" ? "light" : "dark";
document.documentElement.setAttribute("data-theme", nextTheme);
themeMeta?.setAttribute("content", themeColors[nextTheme]);
};
applyTheme(savedTheme);
themeToggle?.addEventListener("click", () => {
const nextTheme = document.documentElement.getAttribute("data-theme") === "dark" ? "light" : "dark";
applyTheme(nextTheme);
localStorage.setItem("uit-theme", nextTheme);
});

window.copyCommand = (text, button) => {
if (!navigator.clipboard) return;
navigator.clipboard.writeText(text).then(() => {
button.classList.add("is-copied");
setTimeout(() => button.classList.remove("is-copied"), 1600);
}).catch(() => undefined);
};

const buttons = document.querySelectorAll(".preview-btn");
const panels = document.querySelectorAll(".product-preview");
const previewFrame = document.querySelector(".hero-screenshot-frame");
buttons.forEach((button) => {
button.addEventListener("click", () => {
const selectedPreview = button.getAttribute("data-preview");
buttons.forEach((item) => {
const selected = item === button;
item.classList.toggle("active", selected);
item.setAttribute("aria-selected", String(selected));
});
panels.forEach((panel) => { panel.hidden = panel.id !== `preview-${selectedPreview}`; });
if (previewFrame) previewFrame.dataset.preview = selectedPreview;
});
});

const cliCards = document.querySelectorAll(".cli-capability[data-cli-command]");
const cliTerminalCommands = document.querySelectorAll(".cli-terminal-command[data-cli-command]");
const setCliHighlight = (command, active) => {
cliCards.forEach((card) => {
card.classList.toggle("is-linked", active && card.dataset.cliCommand === command);
});
cliTerminalCommands.forEach((terminalCommand) => {
terminalCommand.classList.toggle("is-highlighted", active && terminalCommand.dataset.cliCommand === command);
});
};
cliCards.forEach((card) => {
const command = card.dataset.cliCommand;
card.addEventListener("mouseenter", () => setCliHighlight(command, true));
card.addEventListener("mouseleave", () => setCliHighlight(command, false));
card.addEventListener("focus", () => setCliHighlight(command, true));
card.addEventListener("blur", () => setCliHighlight(command, false));
});

document.querySelectorAll(".os-tab").forEach((tab) => {
tab.addEventListener("click", () => {
const card = tab.closest(".dl-card");
const target = tab.dataset.osTarget;
card?.querySelectorAll(".os-tab").forEach((item) => {
const selected = item === tab;
item.classList.toggle("active", selected);
item.setAttribute("aria-selected", String(selected));
});
card?.querySelectorAll(".os-panel").forEach((panel) => {
panel.hidden = panel.dataset.osPanel !== target;
});
});
});

});
Loading
Loading