From 8a3b351119a0ec776c950917ca5b23db4b68eee3 Mon Sep 17 00:00:00 2001 From: Obiajulu-gif Date: Mon, 26 Jan 2026 09:14:40 +0100 Subject: [PATCH 01/10] feat: add CI workflow and contributing guidelines for import rules --- .github/workflows/ci.yml | 89 ++++++++++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 27 ++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 CONTRIBUTING.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e726b2d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,89 @@ +name: CI + +on: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop + +jobs: + lint-imports: + name: lint-imports + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Lint absolute imports + shell: bash + run: | + set -euo pipefail + pattern="^[[:space:]]*(import|export)[^;]*from[[:space:]]+['\"]src/|^[[:space:]]*import[[:space:]]+['\"]src/" + if command -v rg >/dev/null 2>&1; then + matches=$(rg -n \ + --glob '!**/node_modules/**' \ + --glob '!**/dist/**' \ + --glob '!**/build/**' \ + --glob '!**/.next/**' \ + --glob '!**/coverage/**' \ + --glob '!**/out/**' \ + --glob '!**/tmp/**' \ + --glob '!**/.turbo/**' \ + --glob '!**/.cache/**' \ + --glob '*.ts' \ + --glob '*.tsx' \ + "$pattern" . || true) + else + matches=$(grep -RIn \ + --include='*.ts' \ + --include='*.tsx' \ + --exclude-dir=node_modules \ + --exclude-dir=dist \ + --exclude-dir=build \ + --exclude-dir=.next \ + --exclude-dir=coverage \ + --exclude-dir=out \ + --exclude-dir=tmp \ + --exclude-dir=.turbo \ + --exclude-dir=.cache \ + -E "$pattern" . || true) + fi + if [ -n "$matches" ]; then + echo "ERROR: Absolute imports from \"src/\" are not allowed. Use relative paths instead." + echo "$matches" + exit 1 + fi + + build: + name: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 18 + cache: npm + - name: Install dependencies + run: npm ci + - name: Build frontend + run: npm --workspace frontend run build + - name: Build backend + run: npm --workspace backend run build + + type-check: + name: type-check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 18 + cache: npm + - name: Install dependencies + run: npm ci + - name: Type-check frontend + run: npm --workspace frontend exec -- tsc --noEmit -p tsconfig.json + - name: Type-check backend + run: npm --workspace backend exec -- tsc --noEmit -p tsconfig.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..41903df --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,27 @@ +# Contributing + +## Import Guidelines +Rule: Always use relative imports. + +Bad: +```ts +import X from "src/components/X"; +``` + +Good: +```ts +import X from "../../components/X"; +``` + +CI will reject PRs containing src/* imports. + +Issue/PR: https://github.com/MindBlockLabs/mindBlock_app/pull/0000 (placeholder) + +Local check: +``` +grep -r "from ['\"]src/" --include="*.ts" --include="*.tsx" . +``` + +## Branch Protection +main and develop require status checks: lint-imports, build, type-check. +Require branches to be up-to-date before merging. From 408bf9e6be953c6e25dd67aba034e5ff0dcd86ee Mon Sep 17 00:00:00 2001 From: samad13 Date: Mon, 26 Jan 2026 12:53:03 +0100 Subject: [PATCH 02/10] Build-Responsive-Layout-for-Mobile-and-Desktop --- frontend/app/dashboard/page.tsx | 33 ++++++---- frontend/app/layout.tsx | 31 ++++------ frontend/components/ClientLayout.tsx | 29 +++++++++ frontend/components/SideNav.tsx | 60 ++++++++++++------- .../components/dashboard/CategoryCard.tsx | 16 ++++- .../components/dashboard/DailyQuestCard.tsx | 25 ++++++-- 6 files changed, 136 insertions(+), 58 deletions(-) create mode 100644 frontend/components/ClientLayout.tsx diff --git a/frontend/app/dashboard/page.tsx b/frontend/app/dashboard/page.tsx index ce80534..695e5e4 100644 --- a/frontend/app/dashboard/page.tsx +++ b/frontend/app/dashboard/page.tsx @@ -1,4 +1,4 @@ -'use client'; +"use client"; import { useRouter } from "next/navigation"; import DailyQuestCard from "@/components/dashboard/DailyQuestCard"; @@ -35,32 +35,45 @@ const Dashboard = () => { return (
-
-
-
+
+
+
+
- Mind Block + Mind Block
- mind block + + mind block +
-
+
- 3 Day Streak + + 3 Day Streak +
- 1.1K Points + + 1.1K Points +
+
-
+
diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index 6ad9a15..7b691b3 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -1,25 +1,19 @@ -import type { Metadata } from 'next'; -import { Geist, Geist_Mono } from 'next/font/google'; -import './globals.css'; -import { ToastProvider } from '@/components/ui/ToastProvider'; -import StoreProvider from '@/providers/storeProvider'; -import SideNav from "@/components/SideNav"; +import { Geist, Geist_Mono } from "next/font/google"; +import "./globals.css"; +import { ToastProvider } from "@/components/ui/ToastProvider"; +import StoreProvider from "@/providers/storeProvider"; +import ClientLayout from "@/components/ClientLayout"; const geistSans = Geist({ - variable: '--font-geist-sans', - subsets: ['latin'], + variable: "--font-geist-sans", + subsets: ["latin"], }); const geistMono = Geist_Mono({ - variable: '--font-geist-mono', - subsets: ['latin'], + variable: "--font-geist-mono", + subsets: ["latin"], }); -export const metadata: Metadata = { - title: 'Create Next App', - description: 'Generated by create next app', -}; - export default function RootLayout({ children, }: Readonly<{ @@ -32,10 +26,9 @@ export default function RootLayout({ > -
- -
{children}
-
+ + + {children}
diff --git a/frontend/components/ClientLayout.tsx b/frontend/components/ClientLayout.tsx new file mode 100644 index 0000000..a9d16c3 --- /dev/null +++ b/frontend/components/ClientLayout.tsx @@ -0,0 +1,29 @@ +"use client"; + +import { useState } from "react"; +import SideNav from "@/components/SideNav"; +import { Menu } from "lucide-react"; + +export default function ClientLayout({ + children, +}: { + children: React.ReactNode; +}) { + const [sidebarOpen, setSidebarOpen] = useState(false); + + return ( +
+ setSidebarOpen(false)} /> + +
{children}
+
+ ); +} diff --git a/frontend/components/SideNav.tsx b/frontend/components/SideNav.tsx index 3cc21e1..5b1a919 100644 --- a/frontend/components/SideNav.tsx +++ b/frontend/components/SideNav.tsx @@ -11,31 +11,47 @@ const navItems = [ { label: "Feeds", href: "/feeds", icon: Bell }, ]; -const SideNav = () => { + +const SideNav = ({ open, onClose }: { open: boolean; onClose: () => void }) => { const pathname = usePathname(); return ( -