Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
46465b8
new feature groups
Sank34 Jul 1, 2026
16632b6
added user card in sidebar
Sank34 Jul 31, 2026
b7c8433
sidebar refetch
maitable Jul 31, 2026
2e3d69a
Merge remote-tracking branch 'origin/new-feature/groups' into new-fea…
maitable Jul 31, 2026
c8fe379
added banner, needs improvement
Sank34 Jul 31, 2026
8b0af2c
revamped admin panel
maitable Aug 3, 2026
0817444
new dashboard, groups and roadmap with lessons
Sank34 Aug 3, 2026
e8bb8db
Merge remote-tracking branch 'origin/new-feature/groups' into mainten…
maitable Aug 3, 2026
11c92cc
new admin lessons tool and updated roadmap
Sank34 Aug 3, 2026
1649cfa
FINALLY FINISHED THE ADMIN TOOL!!!
Sank34 Aug 4, 2026
970149a
more admin dash stuff (stats + to-do lists)
maitable Aug 4, 2026
9216cc7
added onboarding screen + tour
Sank34 Aug 4, 2026
5c0b768
added rewards shop, improved security and added more caching to impro…
Sank34 Aug 5, 2026
22f9446
competitions!!! (and badges improved)
Sank34 Aug 5, 2026
be9cdc9
added resize & improved sidebar
Sank34 Aug 5, 2026
1c94b2e
darkmode, improved skeletons, improved feed & posts
Sank34 Aug 6, 2026
e4c1392
finished improving darkmode, sidebar & fixed customization issues
Sank34 Aug 10, 2026
042c4d2
complete new workspace system added + emails!
Sank34 Aug 13, 2026
a28402b
updates & bug fixes
Sank34 Aug 17, 2026
e75a908
push update-uri noi
Sank34 Aug 26, 2026
197b68a
added support for code editor redirect read
Sank34 Aug 26, 2026
d0368d8
default pfps, small changes to competitions
maitable Aug 26, 2026
1e7c55a
updates mobile support
Sank34 Aug 27, 2026
e3f87a7
updates -- integrating mobile
Sank34 Sep 1, 2026
584e7db
trainer portal
maitable Sep 4, 2026
5cb080f
birthday feature
Sank34 Sep 4, 2026
5f674a1
bug fix platforma
Sank34 Sep 4, 2026
e805754
GAMES!!!!
Sank34 Sep 6, 2026
ff92699
fixes
maitable Sep 7, 2026
5672391
major update
Sank34 Sep 13, 2026
0673edf
Merge remote-tracking branch 'origin/main' into maintenance/admin-pan…
Copilot Sep 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
24 changes: 24 additions & 0 deletions .github/workflows/design-system.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Design system

on:
pull_request:
push:
branches:
- main

jobs:
design-contract:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Check design-system contract
run: npm run design:check
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
# next.js
/.next/
/out/
/public/monaco/
/public/excalidraw/

# production
/build
Expand All @@ -35,10 +37,12 @@ yarn-error.log*

# env files (can opt-in for committing if needed)
.env*
!.env.example

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
/public/syntax/
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<!-- BEGIN:nextjs-agent-rules -->

# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.

This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.

<!-- END:nextjs-agent-rules -->
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
134 changes: 105 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,122 @@
<div align="center">
<img src="https://media.discordapp.net/attachments/1495347070654218342/1532703552160399360/logo-github.png?ex=6a71c56b&is=6a7073eb&hm=205ec8d045d7f3321b8b87810d10fa7e56165b634561680f87c59adee5a6fa61&=&format=webp&quality=lossless" alt="logo" width="200"><br>
<br>
Learn programming the smart way. <br><br>
<img src="./public/scripticx-readme.png" alt="ScripticX" width="460" />
<p>Learn programming visually, one small idea at a time.</p>
<p>
<a href="https://platform.scripticx.org">Open the platform</a> ·
<a href="https://scripticx.org">Visit the landing page</a>
</p>
</div>

# ScripticX platform

ScripticX is a bilingual (Romanian / English) learning platform for students, teachers and independent learners. It combines the MiniScript+ language with guided lessons, automatically graded problems, a collaborative community and a browser-based editor.

The current release adds the platform experiences that were not part of the original pre-alpha: dedicated workspaces, Groups, Competitions, the Rewards Shop, a structured learning roadmap, accessibility mode and a new editor with GitHub integration.

## What is included

[![GitHub stars](https://img.shields.io/github/stars/Sank34/scripticx?style=social)](https://github.com/Sank34/scripticx/stargazers)
[![License](https://img.shields.io/github/license/Sank34/scripticx)](https://github.com/Sank34/scripticx/blob/main/LICENSE)
[![Version](https://img.shields.io/github/package-json/v/Sank34/scripticx)](https://github.com/Sank34/scripticx/blob/main/package.json)
[![Sponsor](https://img.shields.io/badge/Sponsor-%E2%9D%A4-red)](https://buymeacoffee.com/scripticx)
| Area | What users can do |
| --- | --- |
| **MiniScript+ editor** | Write, run and debug code in the browser with step-through execution, live diagnostics, syntax highlighting and custom editor settings. |
| **Learning roadmap** | Follow localized paths, chapters and lessons with quizzes, progress gates and recommended practice. |
| **Problems** | Search and solve automatically graded problems, browse chapters and download a branded PDF statement. |
| **Groups** | Chat in channels, share images and GIFs, use named custom emoji and preview media in a focused modal. |
| **Competitions** | Join public or invite-only contests, with participant invitations managed by username search or CSV upload. |
| **Rewards Shop** | Spend points on cosmetic items and manage owned items in Inventory. |
| **Workspaces** | Personal, Student and Teacher workspaces expose the tools and navigation relevant to each role. |
| **Community** | Share posts and snippets, mention users, follow progress and compare results on leaderboards. |
| **Accessibility** | Turn on a higher-contrast visual mode designed for projectors and colour-vision differences. |
| **Administration** | Manage content, chapters, announcements, roles and granular permissions from one secure admin surface. |

<br><br>ScripticX is a modern programming learning platform built around MiniScript+, a language built specifically for beginners, avoiding technical barriers. It features an in-browser code editor, auto-graded problems, classes & lessons, live coding sessions, and a full community feed for students to share their progress. The platform is fully bilingual (RO/EN) and runs entirely client-side (private code execution).
## Screenshots

<div align="center">
<img src="./public/releases/official-launch/editor.jpg" alt="ScripticX editor" width="820" />
<br><br>
<img src="./public/releases/official-launch/problems.jpg" alt="ScripticX problems and roadmap chapters" width="820" />
<br><br>
<img src="./public/releases/official-launch/rewards.jpg" alt="ScripticX Rewards Shop" width="820" />
<br><br>
<img src="./public/releases/official-launch/problems-mobile.jpg" alt="ScripticX on mobile" width="360" />
</div>

## MiniScript+

### Main Features
MiniScript+ is a small educational language with readable, beginner-friendly syntax and localized runtime messages. It runs directly in the browser and includes variables, conditions, loops, functions, return values and input/output.

<img src="https://api.iconify.design/lucide:code.svg?color=%2386efac" width="20" height="20" /> **In-browser Editor** <br>
```msp
FUNCTION build(x, y)
RETURN x + y
END

<img src="https://api.iconify.design/lucide:check-circle.svg?color=%2386efac" width="20" height="20" /> **Auto-graded Problems** <br>
FOR i FROM 1 TO 5 INCR 1
PRINT build(i, 2)
END
```

<img src="https://api.iconify.design/lucide:school.svg?color=%2386efac" width="20" height="20" /> **Classes & Lessons**<br>
`INCR` is optional. `RETURN` ends the current function immediately and sends its value back to the caller.

<img src="https://api.iconify.design/lucide:radio.svg?color=%2386efac" width="20" height="20" /> **Livecode**<br>
## Run locally

<img src="https://api.iconify.design/lucide:message-circle.svg?color=%2386efac" width="20" height="20" /> **Community Feed**<br>
Requirements: Node.js 20 or newer and npm 10 or newer.

<img src="https://api.iconify.design/lucide:trending-up.svg?color=%2386efac" width="20" height="20" /> **Progress Tracking**<br>
```bash
git clone https://github.com/Sank34/scripticx.git
cd scripticx
npm install
```

<img src="https://api.iconify.design/lucide:user.svg?color=%2386efac" width="20" height="20" /> **Profiles** <br>
Create `.env.local` with the Supabase project URL and anonymous key:

<div align="center">
```dotenv
NEXT_PUBLIC_SUPABASE_URL=...
NEXT_PUBLIC_SUPABASE_ANON_KEY=...
```

### Sneak Peek
<img src="https://media.discordapp.net/attachments/1479338345367601254/1533885103086895206/image.png?ex=6a721d52&is=6a70cbd2&hm=a3a768d36119a7d5322cb828cd5334d099f81185789dbcd19f66f3a8f4891415&=&format=webp&quality=lossless&width=1536&height=818" alt="logo"><br>
<br>
<img src="https://media.discordapp.net/attachments/1479338345367601254/1533895257773703341/image.png?ex=6a7226c7&is=6a70d547&hm=fe8c08f911f48a69e4143fd184ab07e14f85e8c21ed384b8f6f51d933062af27&=&format=webp&quality=lossless&width=1536&height=818" alt="logo"><br>
<br>
Start the development server at `http://localhost:3000`:

### Tech Stack
![Next.js](https://img.shields.io/badge/Next.js-black?logo=next.js&logoColor=white)
![React](https://img.shields.io/badge/React-20232A?logo=react&logoColor=61DAFB)
![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white)
![Supabase](https://img.shields.io/badge/Supabase-3ECF8E?logo=supabase&logoColor=white)
![Tailwind CSS](https://img.shields.io/badge/Tailwind-06B6D4?logo=tailwindcss&logoColor=white)
```bash
npm run dev
```

</div>
For a production build:

```bash
npm run build
npm run start
```

## Project layout

```text
scripticx/
├── app/ # Next.js routes and API handlers
│ ├── admin/ # Admin workspace and content management
│ ├── editor/ # MiniScript+ and multi-language editor
│ ├── learn/ # Roadmap, paths and lessons
│ ├── problems/ # Problem library and submissions
│ ├── competitions/ # Contest browsing and participation
│ ├── groups/ # Community groups and channels
│ └── workspace/ # Student and teacher tools
├── components/ # Shared UI, shell and feature components
├── hooks/ # Client data and interaction hooks
├── lib/ # Interpreter, permissions, i18n and services
├── public/ # Logos, screenshots and static assets
└── supabase/migrations/ # Database schema and security migrations
```

## Architecture and security

The app uses Next.js App Router with React Server and Client Components, React Query for server-state caching, Tailwind CSS and accessible Radix-based UI primitives. Supabase provides PostgreSQL, authentication, realtime updates and storage.

Authorization is enforced in API handlers and database policies. Platform access modes, workspace restrictions, competitions and custom roles are checked server-side; UI visibility is only a convenience layer. Custom roles can grant specific tools without exposing unrelated admin capabilities.

MiniScript+ executes in the browser. Other supported languages are evaluated by an isolated execution service with explicit limits. See [`docs/code-execution.md`](docs/code-execution.md) for the execution model.

## Internationalization

The `LanguageProvider` switches the interface between Romanian and English and persists the preference for the signed-in account. Lesson, roadmap and problem content use localized fields, so each language can be edited and saved independently in the admin configurator.

## Licence

ScripticX is developed by ScripticX SRL. See the repository licence and the notices included with third-party assets before redistributing the project.
41 changes: 41 additions & 0 deletions app/admin/announcements/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"use client";

import { useState } from "react";
import { Megaphone } from "lucide-react";
import { toast } from "sonner";
import RouteGuard from "@/components/RouteGuard";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { supabase } from "@/lib/supabase";

export default function AdminAnnouncementsPage() {
const [title, setTitle] = useState("");
const [body, setBody] = useState("");
const [href, setHref] = useState("");
const [busy, setBusy] = useState(false);
async function send() {
setBusy(true);
try {
const { data: { session }, error } = await supabase.auth.getSession();
if (error) throw error;
if (!session) throw new Error("Your session has expired. Please sign in again.");

const response = await fetch("/api/admin/announcements", {
method: "POST",
headers: {
"content-type": "application/json",
Authorization: `Bearer ${session.access_token}`,
},
body: JSON.stringify({ title, body, href }),
});
const result = await response.json();
if (!response.ok) throw new Error(result.error || "Could not send announcement");
toast.success(`Announcement sent to ${result.created} users`);
setTitle(""); setBody(""); setHref("");
} catch (error) { toast.error(error instanceof Error ? error.message : "Could not send announcement"); }
finally { setBusy(false); }
}
return <RouteGuard requireAdmin><div className="mx-auto max-w-3xl space-y-6"><header><div className="flex items-center gap-2 text-sm font-medium text-muted-foreground"><Megaphone className="size-4" />Platform announcements</div><h1 className="mt-2 text-3xl font-semibold tracking-tight">Send an announcement</h1><p className="mt-2 text-sm text-muted-foreground">The message appears in every user’s ScripticX notifications.</p></header><Card><CardContent className="space-y-4 p-5"><Input value={title} onChange={(event) => setTitle(event.target.value)} placeholder="Title" maxLength={160} /><Textarea value={body} onChange={(event) => setBody(event.target.value)} placeholder="Message" rows={6} maxLength={2000} /><Input value={href} onChange={(event) => setHref(event.target.value)} placeholder="Optional link, e.g. /updates" maxLength={500} /><Button onClick={() => void send()} disabled={busy || title.trim().length < 2 || body.trim().length < 2} className="gap-2"><Megaphone className="size-4" />{busy ? "Sending…" : "Send to all users"}</Button></CardContent></Card></div></RouteGuard>;
}
10 changes: 5 additions & 5 deletions app/learn/loops/layout.tsx → app/admin/badges/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import type { Metadata } from "next";
import { createPageMetadata } from "@/lib/metadata";

export const metadata: Metadata = createPageMetadata({
title: "Loops in MiniScript+",
description:
"Learn how to repeat instructions with WHILE and follow variable changes step by step.",
path: "/learn/loops",
title: "Badge Management",
description: "Create and manage ScripticX achievement badges.",
path: "/admin/badges",
noIndex: true,
});

export default function LoopsLayout({
export default function AdminBadgesLayout({
children,
}: Readonly<{ children: React.ReactNode }>) {
return children;
Expand Down
Loading
Loading