Skip to content

Commit

Permalink
feat: add lesson search feature
Browse files Browse the repository at this point in the history
  • Loading branch information
andy23512 committed May 14, 2024
1 parent 1e1ec33 commit 50015b9
Show file tree
Hide file tree
Showing 12 changed files with 266 additions and 84 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@ngrx/component": "^17.2.0",
"@ngrx/signals": "^17.2.0",
"@ngrx/store": "^17.2.0",
"fuzzy": "^0.1.3",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.14",
"ramda": "^0.30.0",
Expand Down
96 changes: 96 additions & 0 deletions src/app/data/character-name-map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
export const CHARACTER_NAME_MAP = new Map([
['`', ['backtick', 'backquote', 'grave', 'grave accent']],
['1', ['one']],
['2', ['two']],
['3', ['three']],
['4', ['four']],
['5', ['five']],
['6', ['six']],
['7', ['seven']],
['8', ['eight']],
['9', ['nine']],
['0', ['zero']],
['-', ['hyphen-minus', 'hyphen', 'minus sign', 'dash']],
['=', ['equals sign', 'equal sign']],
['~', ['tilde']],
['!', ['exclamation mark', 'exclamation point', 'bang', 'shriek']],
['@', ['at sign', 'at symbol', 'commercial at', 'address sign']],
[
'#',
[
'number sign',
'hash',
'pound sign',
'pound',
'hashtag',
'hash mark',
'hashmark',
'sharp',
],
],
['$', ['dollar sign', 'peso sign']],
['%', ['percent sign', 'per cent sign']],
['^', ['caret']],
['&', ['ampersand', 'and sign']],
['*', ['asterisk', 'star']],
['(', ['left parentheses', 'left bracket', 'left round bracket']],
[')', ['right parentheses', 'right bracket', 'right round bracket']],
['_', ['underscore', 'underline', 'low line', 'low dash']],
['+', ['plus sign']],

['[', ['left square bracket', 'left bracket']],
[']', ['right square bracket', 'right bracket']],
[
'\\',
[
'backslash',
'hack',
'whack',
'escape',
'reverse slash',
'slosh',
'downwhack',
'backslant',
'bash',
'reverse slant',
'reverse solidus',
'reversed virgule',
],
],
['{', ['left brace', 'left curly bracket']],
['}', ['right brace', 'right curly bracket']],
['|', ['vertical bar', 'pipe', 'bar', 'Sheffer stroke', 'or', 'vbar']],

[';', ['semicolon', 'semi-colon']],
["'", ['apostrophe', 'single quote', 'quote']],
[':', ['colon']],
['"', ['quotation mark', 'double quote']],

[',', ['comma']],
['.', ['full stop', 'period', 'full point', 'point', 'dot', 'baseline dot']],
[
'/',
[
'slash',
'stroke',
'solidus',
'forward slash',
'diagonal',
'division slash',
'fraction slash',
'oblique',
'oblique stroke',
'oblique dash',
'scratch comma',
'separatrix',
'shilling mark',
'slant',
'slash mark',
'slat',
'virgule',
],
],
['<', ['less-than sign', 'left angle bracket', 'left chevron']],
['>', ['greater-than sign', 'right angle bracket', 'right chevron']],
['?', ['question mark', 'interrogation point', 'query', 'eroteme']],
]);
21 changes: 15 additions & 6 deletions src/app/data/topics.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Topic } from '../models/topic.models';
import { LessonWithTopic, Topic } from '../models/topic.models';
import { generateCharacterLesson } from '../utils/lesson.utils';

export const LETTER_TOPIC: Topic = {
id: 'letter',
iconName: 'abc',
name: 'Letter',
name: 'Letters',
type: 'character',
lessons: ['reat', 'ioln', 'ujys', 'kcfd', 'mvhp', 'wgz', 'bqx'].map(
generateCharacterLesson,
Expand All @@ -14,20 +14,21 @@ export const LETTER_TOPIC: Topic = {
export const NUMBER_TOPIC: Topic = {
id: 'number',
iconName: '123',
name: 'Number',
name: 'Numbers',
type: 'character',
lessons: ['123', '456', '7890'].map(generateCharacterLesson).concat([
{
...generateCharacterLesson('1234567890'),
id: 'all',
name: 'All',
components: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
name: 'All Numbers',
},
]),
};

export const SYMBOL_TOPIC: Topic = {
id: 'symbol',
name: 'Symbol',
name: 'Symbols',
iconName: 'question_mark',
type: 'character',
lessons: [
'`~!@',
Expand All @@ -42,3 +43,11 @@ export const SYMBOL_TOPIC: Topic = {
};

export const TOPICS = [NUMBER_TOPIC, LETTER_TOPIC, SYMBOL_TOPIC];
export const LESSONS: LessonWithTopic[] = TOPICS.map((topic) =>
topic.lessons.map((l) => ({ ...l, topic })),
).flat();
export const LESSON_DATA_FOR_SEARCH = LESSONS.map((lesson) =>
[{ key: lesson.name, lesson }]
.concat(lesson.components.map((c) => ({ key: c, lesson })))
.concat(lesson.componentNames.map((n) => ({ key: n, lesson }))),
).flat();
5 changes: 5 additions & 0 deletions src/app/models/topic.models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface Lesson {
id: string;
name: string;
components: string[];
componentNames: string[];
}

export interface Topic {
Expand All @@ -13,3 +14,7 @@ export interface Topic {
type: TopicType;
lessons: Lesson[];
}

export interface LessonWithTopic extends Lesson {
topic: Topic;
}
109 changes: 71 additions & 38 deletions src/app/nav/nav.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,84 @@
[opened]="(isHandset$ | async) === false"
data-style-dense
>
<mat-toolbar class="sticky top-0 z-10 !bg-gray-450 shadow">
<a
[routerLink]="'/'"
aria-label="home page link"
matTooltip="Go to Home page"
(click)="onNavLinkClick()"
>
<button type="button" mat-icon-button>
<mat-icon>home</mat-icon>
<header class="sticky top-0 z-10 shadow">
<mat-toolbar class="sticky top-0 z-10 !bg-gray-450">
<a
[routerLink]="'/'"
aria-label="home page link"
matTooltip="Go to Home page"
(click)="onNavLinkClick()"
>
<button type="button" mat-icon-button>
<mat-icon>home</mat-icon>
</button>
</a>
<a
[routerLink]="'/settings'"
aria-label="settings page link"
matTooltip="Go to Settings page"
(click)="onNavLinkClick()"
>
<button type="button" mat-icon-button>
<mat-icon>settings</mat-icon>
</button>
</a>
<button
type="button"
mat-icon-button
aria-label="button that opens hotkey dialog"
(click)="openHotkeyDialog()"
matTooltip="Open hotkey dialog"
>
<mat-icon>keyboard</mat-icon>
</button>
</a>
<a
[routerLink]="'/settings'"
aria-label="settings page link"
matTooltip="Go to Settings page"
(click)="onNavLinkClick()"
</mat-toolbar>
<mat-form-field
class="w-full [&_.mat-mdc-form-field-subscript-wrapper]:hidden"
>
<button type="button" mat-icon-button>
<mat-icon>settings</mat-icon>
</button>
</a>
<button
type="button"
mat-icon-button
aria-label="button that opens hotkey dialog"
(click)="openHotkeyDialog()"
matTooltip="Open hotkey dialog"
>
<mat-icon>keyboard</mat-icon>
</button>
</mat-toolbar>
<mat-nav-list>
@for (topic of topics; track topic.id) {
<h4 class="flex items-center gap-1" matSubheader>
<mat-icon>{{ topic.iconName || "topic" }}</mat-icon
>{{ topic.name }}
</h4>
@for (lesson of topic.lessons; track lesson.id) {
<input
[ngModel]="searchQuery()"
(ngModelChange)="searchQuery.set($event)"
matInput
type="search"
placeholder="Search Lessons"
aria-label="search box for lesson"
/>
@if (!searchQuery()) {
<button mat-icon-button matSuffix aria-label="clear search query">
<mat-icon>search</mat-icon>
</button>
}
</mat-form-field>
</header>
<mat-nav-list class="!p-0">
@if (searchQuery()) {
@for (lesson of searchResult(); track lesson.id) {
<a
mat-list-item
routerLink="/topic/{{ topic.id }}/lesson/{{ lesson.id }}"
routerLink="/topic/{{ lesson.topic.id }}/lesson/{{ lesson.id }}"
routerLinkActive="list-item-active"
(click)="onNavLinkClick()"
>{{ lesson.name }}</a
>{{ lesson.topic.name }} - {{ lesson.name }}</a
>
} @empty {
<a mat-list-item> No results were found.</a>
}
} @else {
@for (topic of topics; track topic.id) {
<h4 class="flex items-center gap-1" matSubheader>
<mat-icon>{{ topic.iconName || "topic" }}</mat-icon
>{{ topic.name }}
</h4>
@for (lesson of topic.lessons; track lesson.id) {
<a
mat-list-item
routerLink="/topic/{{ topic.id }}/lesson/{{ lesson.id }}"
routerLinkActive="list-item-active"
(click)="onNavLinkClick()"
>{{ lesson.name }}</a
>
}
}
}
</mat-nav-list>
Expand Down
Loading

0 comments on commit 50015b9

Please sign in to comment.