Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mark #27

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open

Mark #27

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
902764a
Setup prettier ✨
markwitt1 Apr 8, 2024
b4b6a5c
Ran `npm run format:fix`
markwitt1 Apr 8, 2024
1093f7d
Enable formatOnSave
markwitt1 Apr 8, 2024
2f4fff6
Remove redundant metadata (check https://nextjs.org/docs/app/building…
markwitt1 Apr 8, 2024
69169f0
Redesign content.ts to be single source of truth
markwitt1 Apr 8, 2024
dbd5530
Proposal: Refactor App to completely abstract away content from UI co…
markwitt1 Apr 10, 2024
34f5adb
Add @typescript-eslint/recommended for better linting such as no-unus…
markwitt1 Apr 10, 2024
0c98c4f
Redo Sidebar using ShadCN accordion. Improve Routing. Refactor quiz c…
markwitt1 Apr 10, 2024
bf3b68f
randomize question options
markwitt1 Apr 10, 2024
55ed4fc
Add ESLint rule to only warn about unused variables instead of errori…
markwitt1 Apr 10, 2024
57b1d37
Update NavBar to get chapters from props
markwitt1 Apr 10, 2024
aa40a94
Adjust Question component to support quiz mode + implement quiz mode
markwitt1 Apr 11, 2024
e936fc9
Adopt StartScreen and EndScreen for quiz
markwitt1 Apr 11, 2024
3e8f2dd
Cleanup unused files
markwitt1 Apr 11, 2024
10e4628
Implement Retry Feature
markwitt1 Apr 15, 2024
d74f975
Install Posthog (https://eu.posthog.com/project/20336/onboarding/prod…
markwitt1 Apr 15, 2024
471e718
Add PostHog event tracking to quiz and chapter pages
markwitt1 Apr 15, 2024
565e9f2
Add `prettier-plugin-tailwindcss`https://tailwindcss.com/blog/automat…
markwitt1 Apr 15, 2024
7892cb0
Ran `npx prettier --write .`
markwitt1 Apr 15, 2024
3dcce1e
Fix svg rules
markwitt1 Apr 18, 2024
833df1d
Install dependencies for testing
markwitt1 Apr 20, 2024
dca4866
Setup first test
markwitt1 Apr 20, 2024
434b8ba
Reinstall using pnpm
markwitt1 Apr 21, 2024
3b6a91b
Ignore eslint during build
markwitt1 Apr 21, 2024
dc0b597
Add more example tests
markwitt1 Apr 21, 2024
2352ec3
remove unused script
markwitt1 Apr 21, 2024
b6a9d8c
remove test chapter
markwitt1 Apr 22, 2024
dc40134
Implement keyboard shortcuts as well as fixing button errors
markwitt1 Apr 22, 2024
4d5a77d
Add back showing question index
markwitt1 Apr 24, 2024
87f8bb0
add keyboard shortcut to submit answer
markwitt1 Apr 24, 2024
dd1f7f2
remove sidebar in quiz page
markwitt1 Apr 24, 2024
be4e77f
Authentication
markwitt1 Apr 26, 2024
837d80a
Add documentation
markwitt1 Apr 26, 2024
5b55a08
Add explanation feature using OpenAI and React-Query
markwitt1 Apr 26, 2024
c7f7192
Add documentation for OpenAI feature
markwitt1 Apr 26, 2024
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
5 changes: 5 additions & 0 deletions .concopyuse
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.tsx
*/**.tsx
*/**/***.tsx
*/**/***/****.tsx
*/**/***/****/*****.tsx
7 changes: 6 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PUBLIC_POSTHOG_HOST=

NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
NEXT_PUBLIC_SUPABASE_ANON_KEY=

OPENAI_API_KEY=
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
scripts/*
9 changes: 8 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
{
"extends": "next/core-web-vitals"
"extends": [
"next/core-web-vitals",
"prettier",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"no-unused-vars": "warn"
}
}
6 changes: 3 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
- package-ecosystem: 'npm' # See documentation for possible values
directory: '/' # Location of package manifests
schedule:
interval: "weekly"
interval: 'weekly'
8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"trailingComma": "es5",
"semi": true,
"tabWidth": 2,
"singleQuote": true,
"jsxSingleQuote": true,
"plugins": ["prettier-plugin-tailwindcss"]
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"editor.formatOnSave": true
}
120 changes: 99 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,114 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
# LogiCola

## Getting Started
LogiCola is a web-based instructional program that helps students learn logic. It is a remake of the original LogiCola software created by the late Professor Harry Gensler, built using modern web technologies.

First, run the development server:
## Project Structure

The project follows a standard Next.js project structure with some additional directories and files:

- `__tests__`: Contains test files for various components and pages.

- `app`: Contains tests for pages.
- `components`: Contains tests for individual components.

- `app`: Contains the main application code.

- `[chapter]`: Dynamic route for individual chapters.
- `[subchapter]`: Dynamic route for subchapters within a chapter.
- `quiz`: Contains the quiz page for a subchapter.
- `layout.tsx`: Layout component for chapter pages.
- `page.tsx`: Page component for displaying a chapter.
- `auth`: Contains the authentication page.
- `error`: Contains the error page.
- `layout.tsx`: Main layout component for the application.
- `page.tsx`: Home page component.

- `components`: Contains reusable components used throughout the application.

- `NoSSR`: Component for rendering content only on the client-side.
- `question`: Contains components related to displaying and interacting with questions.
- `quiz`: Contains components for the quiz functionality.
- `ui`: Contains UI components such as accordion, button, card, dropdown menu, input, and label, coming from [ShadCN UI](https://ui.shadcn.com/)
- Other individual component files.

- `lib`: Contains utility functions and libraries.

- `serversidePostHog.ts`: PostHog client for server-side usage.

- `supabase-browser.ts`: Supabase client for browser-side usage.

- `supabase-server.ts`: Supabase client for server-side usage.

- `utils.ts`: Utility functions used in the application.

- `public`: Contains public assets such as images.

- `types`: Contains TypeScript type definitions.

- Other configuration files and directories such as `next.config.js`, `tailwind.config.js`, `tsconfig.json`, etc.

## Testing

The project includes tests for various components and pages. The tests are located in the `__tests__` directory and are organized into subdirectories corresponding to the component or page being tested (they "mirror" the project structure).

The tests are written using Vitest and React Testing Library.

The project uses Tailwind CSS for styling. The styles are defined in the `tailwind.config.js` file and are applied to components using utility classes.

## Prerequisites

The project uses the PNPM package manager. To install PNPM, run the following command:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
npm install -g pnpm
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
For user authentication, the project uses Supabase.

For analytics, the project uses PostHog.

To explain questions, the project uses the OpenAI API.

You will need to create accounts for these services and set up projects to get the required environment variables.

## Environment Variables

The project uses environment variables to store sensitive information such as API keys and secrets. These variables are stored in a `.env.local` file at the root of the project.

The following environment variables are required:

- `NEXT_PUBLIC_SUPABASE_URL`: The URL of your Supabase project.
- `NEXT_PUBLIC_SUPABASE_ANON_KEY`: The anonymous key for your Supabase project.

- `NEXT_PUBLIC_POSTHOG_API_KEY`: The API key for your PostHog project.
- `NEXT_PUBLIC_POSTHOG_HOST`: The host for your PostHog project.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
- `OPENAI_API_KEY`: The API key for the OpenAI API.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
Create a `.env.local` file at the root of the project and add these variables to it.

## Learn More
## Installation

To learn more about Next.js, take a look at the following resources:
To install the project dependencies, run the following command:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
```bash
pnpm install
```

## Development

To start the development server, run the following command:

```bash
pnpm dev
```

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
This will start the Next.js development server and open the application in your default browser.

## Deploy on Vercel
## Build

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
To build the project for production, run the following command:

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
```bash
pnpm build
```
8 changes: 8 additions & 0 deletions __tests__/app/page.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { render, screen } from '@testing-library/react';
import Page from '@/app/page';
import '@testing-library/jest-dom';

test('Page', () => {
render(<Page />);
expect(screen.getByText('What is LogiCola?')).toBeDefined();
});
21 changes: 21 additions & 0 deletions __tests__/components/navBar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { render, screen } from '@testing-library/react';
import Navbar from '@/components/navbar';
import { content } from '@/content';

describe('Navbar', () => {
it('renders the logo and title', () => {
render(<Navbar chapters={content.chapters} />);
expect(screen.getByAltText('Logicola')).toBeInTheDocument();
expect(screen.getByText('LogiCola')).toBeInTheDocument();
});

it('renders the chapters dropdown', () => {
render(<Navbar chapters={content.chapters} />);
expect(screen.getByText('Chapters')).toBeInTheDocument();
});

it('renders the donate link', () => {
render(<Navbar chapters={content.chapters} />);
expect(screen.getByText('Donate')).toBeInTheDocument();
});
});
30 changes: 30 additions & 0 deletions __tests__/components/optionsList.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { render, fireEvent } from '@testing-library/react';
import { OptionsList } from '@/components/question/optionsList';

describe('OptionsList', () => {
const mockOnOptionClick = vitest.fn();

const props = {
options: ['Option 1', 'Option 2', 'Option 3'],
selectedOptionIndices: new Set([0]),
showSolution: false,
correctIndices: [0, 2],
onOptionClick: mockOnOptionClick,
};

it('renders options correctly', () => {
const { getAllByRole } = render(<OptionsList {...props} />);
const options = getAllByRole('button');
expect(options).toHaveLength(props.options.length);
for (let i = 0; i < options.length; i++) {
expect(options[i]).toHaveTextContent(props.options[i]);
}
});

it('calls onOptionClick when an option is clicked', () => {
const { getAllByRole } = render(<OptionsList {...props} />);
const options = getAllByRole('button');
fireEvent.click(options[0]);
expect(mockOnOptionClick).toHaveBeenCalledWith(0);
});
});
18 changes: 18 additions & 0 deletions __tests__/components/quiz/startScreen.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { StartScreen } from '@/components/quiz/startScreen';

describe('StartScreen', () => {
const onClickStart = vitest.fn();

it('renders the start screen content', () => {
render(<StartScreen onClickStart={onClickStart} questionsCount={10} />);
expect(screen.getByText('Ready for a challenge?')).toBeInTheDocument();
expect(screen.getByText('10 questions')).toBeInTheDocument();
});

it('calls onClickStart when the start button is clicked', () => {
render(<StartScreen onClickStart={onClickStart} questionsCount={10} />);
fireEvent.click(screen.getByText('Start Quiz'));
expect(onClickStart).toHaveBeenCalled();
});
});
23 changes: 23 additions & 0 deletions __tests__/components/sidebar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { render, screen } from '@testing-library/react';
import { Sidebar } from '@/components/sidebar';
import { useParams } from 'next/navigation';
import type { Mock } from 'vitest';

vitest.mock('next/navigation', () => ({
useParams: vitest.fn(),
}));

describe('Sidebar', () => {
beforeEach(() => {
(useParams as Mock).mockReturnValue({
chapter: 'chapter1',
subchapter: 'subchapter1',
question: '1',
});
});

it('renders the chapter accordion', () => {
render(<Sidebar />);
expect(screen.getByText('Basic Propositional Logic')).toBeInTheDocument();
});
});
9 changes: 9 additions & 0 deletions __tests__/setupTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { expect, afterEach } from 'vitest';
import { cleanup } from '@testing-library/react';
import * as matchers from '@testing-library/jest-dom/matchers';

expect.extend(matchers);

afterEach(() => {
cleanup();
});
Loading