diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..501b6a3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,33 @@ +# EditorConfig — consistent formatting across editors and contributors +# https://editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{html,css}] +indent_size = 2 + +[*.js] +indent_size = 2 + +[*.{json,yml,yaml}] +indent_size = 2 + +[*.py] +indent_size = 4 + +[*.{r,R}] +indent_size = 2 + +[Makefile] +indent_style = tab diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..437ca70 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,51 @@ +# Auto-detect text files and normalise line endings to LF +* text=auto eol=lf + +# Explicitly declare text files +*.html text eol=lf +*.css text eol=lf +*.js text eol=lf +*.ts text eol=lf +*.json text eol=lf +*.md text eol=lf +*.yml text eol=lf +*.yaml text eol=lf +*.toml text eol=lf +*.xml text eol=lf +*.svg text eol=lf +*.txt text eol=lf +*.sh text eol=lf +*.py text eol=lf +*.r text eol=lf +*.R text eol=lf + +# Windows-specific files keep CRLF +*.bat text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=crlf + +# Binary files — no diff, no merge, no line-ending conversion +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.webp binary +*.avif binary +*.woff binary +*.woff2 binary +*.ttf binary +*.eot binary +*.otf binary +*.pdf binary +*.zip binary +*.gz binary +*.tar binary +*.mp4 binary +*.webm binary +*.mp3 binary +*.ogg binary + +# Lock files — exact merge to prevent conflicts +package-lock.json merge=ours +yarn.lock merge=ours diff --git a/.githooks/commit-msg b/.githooks/commit-msg new file mode 100755 index 0000000..c57d3f7 --- /dev/null +++ b/.githooks/commit-msg @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Commit message hook: enforce prefix convention from CONTRIBUTING.md +set -euo pipefail + +MSG_FILE="$1" +MSG=$(head -1 "$MSG_FILE") + +RED='\033[0;31m' +NC='\033[0m' + +# Skip merge commits and fixup/squash commits +if echo "$MSG" | grep -qE '^(Merge|Revert|fixup!|squash!)'; then + exit 0 +fi + +# Allowed prefixes (from CONTRIBUTING.md) +PREFIXES="Add|Fix|Update|Translate|Docs|Refactor|Test|CI|Chore|Merge" + +if ! echo "$MSG" | grep -qE "^(${PREFIXES}):"; then + echo -e "${RED}Invalid commit message format.${NC}" + echo "" + echo "Commit message must start with one of these prefixes:" + echo " Add: — New feature, course, or tool" + echo " Fix: — Bug fix or broken link" + echo " Update: — Improvement to existing content or code" + echo " Translate: — Translation work" + echo " Docs: — Documentation changes" + echo " Refactor: — Code restructuring (no behaviour change)" + echo " Test: — Adding or updating tests" + echo " CI: — CI/CD pipeline changes" + echo " Chore: — Maintenance (deps, configs, tooling)" + echo "" + echo "Example: Add: interactive Theory of Change lab" + echo "" + echo "Your message was: $MSG" + exit 1 +fi + +# Warn if subject line is too long +if [ ${#MSG} -gt 72 ]; then + echo -e "\033[0;33mWARNING:\033[0m Commit subject is ${#MSG} chars (recommended max: 72)" +fi diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..b7bb6a2 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# Pre-commit hook: catch common mistakes before they're committed +set -euo pipefail + +RED='\033[0;31m' +YELLOW='\033[0;33m' +NC='\033[0m' # No Color + +echo "Running pre-commit checks..." + +# 1. Block commits of sensitive files +SENSITIVE_PATTERNS=('.env' '.env.local' '.env.production' 'credentials.json' '*.pem' '*.key') +STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM) + +for pattern in "${SENSITIVE_PATTERNS[@]}"; do + while IFS= read -r file; do + if [[ -n "$file" ]]; then + echo -e "${RED}BLOCKED:${NC} Refusing to commit sensitive file: $file" + echo "If this is intentional, use: git commit --no-verify" + exit 1 + fi + done < <(echo "$STAGED_FILES" | grep -E "^${pattern//\*/.*}$" 2>/dev/null || true) +done + +# 2. Check for debug/console statements in staged JS/TS/Python files +CODE_FILES=$(echo "$STAGED_FILES" | grep -E '\.(js|ts|py)$' || true) +if [ -n "$CODE_FILES" ]; then + ISSUES=0 + while IFS= read -r file; do + if git diff --cached "$file" | grep -E '^\+.*console\.(log|debug|warn)\(' | grep -v '// keep' > /dev/null 2>&1; then + echo -e "${YELLOW}WARNING:${NC} console.log/debug/warn found in $file" + ISSUES=$((ISSUES + 1)) + fi + if git diff --cached "$file" | grep -E '^\+.*(debugger|breakpoint\(\))' > /dev/null 2>&1; then + echo -e "${RED}BLOCKED:${NC} debugger statement found in $file" + exit 1 + fi + done <<< "$CODE_FILES" + if [ $ISSUES -gt 0 ]; then + echo -e "${YELLOW}Found $ISSUES file(s) with console statements. Consider removing them.${NC}" + fi +fi + +# 3. Check for merge conflict markers +if [ -n "$STAGED_FILES" ]; then + while IFS= read -r file; do + if [ -f "$file" ] && grep -rn '<<<<<<<\|=======\|>>>>>>>' "$file" > /dev/null 2>&1; then + echo -e "${RED}BLOCKED:${NC} Merge conflict markers found in $file" + exit 1 + fi + done <<< "$STAGED_FILES" +fi + +# 4. Warn on large files (> 500KB) +while IFS= read -r file; do + if [ -f "$file" ]; then + SIZE=$(wc -c < "$file") + if [ "$SIZE" -gt 512000 ]; then + SIZE_KB=$((SIZE / 1024)) + echo -e "${YELLOW}WARNING:${NC} Large file (${SIZE_KB}KB): $file" + fi + fi +done <<< "$STAGED_FILES" + +echo "Pre-commit checks passed." diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..3a5ebdf --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,8 @@ +# CODEOWNERS — defines default reviewers for pull requests +# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners + +# Default owner for everything +* @Varnasr + +.github/ @Varnasr +src/ @Varnasr diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..4772ab0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,28 @@ +--- +name: Bug Report +about: Report a broken link, layout issue, or JavaScript error +title: "[Bug] " +labels: bug +assignees: '' +--- + +**Describe the bug** +A clear description of what's wrong. + +**Page/URL** +Which page is affected? + +**Steps to reproduce** +1. Go to '...' +2. Click on '...' +3. See error + +**Expected behavior** +What should happen instead? + +**Screenshots** +If applicable, add screenshots. + +**Device** +- Browser: [e.g., Chrome 120] +- Device: [e.g., desktop / iPhone 14] diff --git a/.github/ISSUE_TEMPLATE/content_issue.md b/.github/ISSUE_TEMPLATE/content_issue.md new file mode 100644 index 0000000..452e80f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/content_issue.md @@ -0,0 +1,16 @@ +--- +name: Content Issue +about: Report outdated, incorrect, or missing content +title: "[Content] " +labels: content +assignees: '' +--- + +**Page/Course affected** +Which page or course has the issue? + +**What's wrong?** +Describe the content issue (outdated stat, broken citation, missing topic, etc.) + +**Suggested correction** +If you know the correct information, please share it with a source/reference. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..f341ef4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,19 @@ +--- +name: Feature Request +about: Suggest a new tool, course, or improvement +title: "[Feature] " +labels: enhancement +assignees: '' +--- + +**What problem does this solve?** +A clear description of the need. + +**Proposed solution** +How you'd like it to work. + +**Alternatives considered** +Any other approaches you've thought about. + +**Additional context** +Any relevant links, screenshots, or examples. diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..6fbd8ca --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,42 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | --------- | +| Latest (main branch) | Yes | + +## Reporting a Vulnerability + +If you discover a security vulnerability in ViewStack, please report it responsibly. + +**Do NOT open a public GitHub issue for security vulnerabilities.** + +Instead, please email **hello@impactmojo.in** with: + +- A description of the vulnerability +- Steps to reproduce the issue +- Any potential impact +- Suggested fix (if you have one) + +We will acknowledge your report within 48 hours and aim to release a fix within 7 days for critical issues. + +## Scope + +The following are in scope: + +- Cross-site scripting (XSS) in any page +- Authentication or authorisation bypass +- Exposed secrets or credentials +- Insecure dependencies with known CVEs +- Open redirects + +## Out of Scope + +- Denial of service attacks +- Social engineering +- Issues in third-party services + +## Recognition + +We're happy to credit security researchers in our changelog. Let us know if you'd like to be acknowledged. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a93afad --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,24 @@ +version: 2 +updates: + # npm dependencies + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + open-pull-requests-limit: 5 + labels: + - "dependencies" + commit-message: + prefix: "Chore:" + # GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + open-pull-requests-limit: 5 + labels: + - "ci" + commit-message: + prefix: "CI:" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..29c3b85 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,19 @@ +## What does this PR do? + +Brief description of the change. + +## Type of change + +- [ ] Bug fix (broken link, layout, JS error) +- [ ] New content (course, case study, translation) +- [ ] New feature or tool +- [ ] Accessibility improvement +- [ ] Performance improvement +- [ ] Documentation update + +## Checklist + +- [ ] Tested on desktop browser +- [ ] Tested on mobile browser +- [ ] No console errors +- [ ] Links are working diff --git a/.gitignore b/.gitignore index 71da7d5..13987e7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,12 @@ dist/ .env .env.local *.log + +# Added by git standards propagation +.DS_Store +Thumbs.db +build/ +coverage/ +.vscode/ +.idea/ +*.swp diff --git a/.gitmessage b/.gitmessage new file mode 100644 index 0000000..3ff9114 --- /dev/null +++ b/.gitmessage @@ -0,0 +1,19 @@ +# : +# +# Prefixes: +# Add: — New feature, course, or tool +# Fix: — Bug fix or broken link +# Update: — Improvement to existing content or code +# Translate: — Translation work +# Docs: — Documentation changes +# Refactor: — Code restructuring (no behaviour change) +# Test: — Adding or updating tests +# CI: — CI/CD pipeline changes +# Chore: — Maintenance (deps, configs, tooling) +# +# Example: +# Add: interactive Theory of Change lab +# Fix: broken nav dropdown on mobile Safari +# +# Body (optional): explain *why*, not *what* — the diff shows what changed. +# Wrap at 72 characters. diff --git a/package.json b/package.json index e4db07d..8916bb8 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "dev": "vite", "build": "vite build", - "preview": "vite preview" + "preview": "vite preview", + "prepare": "git config core.hooksPath .githooks" }, "dependencies": { "react": "^18.3.1",