Mock data and add expression set selection page

This commit is contained in:
Thiago Chaves 2022-07-13 18:39:51 +03:00
parent 79ba58bb36
commit 47ea97adaf
13 changed files with 228 additions and 4 deletions

View File

@ -17,7 +17,6 @@ const Template: ComponentStory<typeof ExpressionSetCard> = (args) => (
export const Daily = Template.bind({}); export const Daily = Template.bind({});
Daily.args = { Daily.args = {
id: 1,
name: "Daily", name: "Daily",
description: "Words for daily practice", description: "Words for daily practice",
word_count: 11, word_count: 11,

View File

@ -1,12 +1,10 @@
export interface ExpressionSetCardProps { export interface ExpressionSetCardProps {
id: number;
name: string; name: string;
description: string; description: string;
word_count: number; word_count: number;
} }
export function ExpressionSetCard({ export function ExpressionSetCard({
id,
name, name,
description, description,
word_count, word_count,

View File

@ -7,7 +7,7 @@ export function Navigation() {
<NavigationItem <NavigationItem
text="practice" text="practice"
iconUrl="/icons/calendar.svg" iconUrl="/icons/calendar.svg"
href="/practice" href="/expression-sets"
/> />
<NavigationItem <NavigationItem
text="settings" text="settings"

View File

@ -0,0 +1,14 @@
import { useState } from "react";
import { MockData } from "../mock";
export function useExpressionData() {
const [state] = useState(MockData);
return {
catefories: state.categories,
expressions: state.expressions,
expression_sets: state.expression_sets,
expression_to_category: state.expression_to_category,
expression_to_expression_set: state.expression_to_expression_set,
};
}

1
src/mock/index.ts Normal file
View File

@ -0,0 +1 @@
export * from "./mock-data";

127
src/mock/mock-data.ts Normal file
View File

@ -0,0 +1,127 @@
import {
Category,
Expression,
ExpressionSet,
ExpressionToCategory,
ExpressionToExpressionSet,
} from "../model";
interface RawExpressionDataItem {
prompt: string;
description: string;
category: string;
expression_set: string;
}
interface RawExpressionSetItem {
name: string;
description: string;
}
const RawExpressionData: RawExpressionDataItem[] = [
["koira", "noun", "daily", "dog, dog paddle (swimming stroke)"],
["liite", "noun", "daily", "attachment, appendix, affix, supplement"],
["havaita", "verb", "daily", "to observe, to detect, to perceive"],
["tukea", "verb", "daily", "to support, finance, sponsor, substantiate"],
].map(([prompt, category, expression_set, description]) => ({
prompt,
description,
category,
expression_set,
}));
const RawExpressionSetData: RawExpressionSetItem[] = [
["daily", "New expressions and poorly remembered expressions"],
["weekly", "Expressions to be reviewed at the end of the week"],
["monthly", "Expressions to be reviewed at the end of the month"],
["yearly", "Expressions to be reviewed at the end of the year"],
["ancient", "Expressions here should be memorized by now"],
].map(([name, description]) => ({ name, description }));
interface MockData {
// Tables
categories: Category[];
expressions: Expression[];
expression_sets: ExpressionSet[];
// Relationships
expression_to_category: ExpressionToCategory[];
expression_to_expression_set: ExpressionToExpressionSet[];
}
export function parseRawData(
raw_expression_data: RawExpressionDataItem[],
raw_expression_set_data: RawExpressionSetItem[]
): MockData {
const category_names = new Set(
raw_expression_data.map((item) => item.category)
);
const categories: Category[] = Array.from(category_names).map(
(name, index) => ({
id: index + 1,
name,
description: name,
})
);
const expressions: Expression[] = raw_expression_data.map(
({ prompt, description }, index) => ({
id: index + 1,
prompt,
description,
})
);
const expression_sets: ExpressionSet[] = raw_expression_set_data.map(
({ name, description }, index) => ({
id: index + 1,
name,
description,
})
);
const expression_to_category: ExpressionToCategory[] =
raw_expression_data.map((item, index) =>
matchExpressionAndCategory(index + 1, item, categories)
);
const expression_to_expression_set: ExpressionToExpressionSet[] =
raw_expression_data.map((item, index) =>
matchExpressionAndExpressionSet(index + 1, item, expression_sets)
);
return {
expressions,
expression_sets,
categories,
expression_to_category,
expression_to_expression_set,
};
}
function matchExpressionAndCategory(
expression_id: number,
{ category }: RawExpressionDataItem,
categories: Category[]
): ExpressionToCategory {
const category_id = categories.find(({ name }) => name === category)?.id || 0;
return {
category_id,
expression_id,
};
}
function matchExpressionAndExpressionSet(
expression_id: number,
{ expression_set }: RawExpressionDataItem,
expression_sets: ExpressionSet[]
): ExpressionToExpressionSet {
const expression_set_id =
expression_sets.find(({ name }) => name === expression_set)?.id || 0;
return {
expression_id,
expression_set_id,
};
}
export const MockData = parseRawData(RawExpressionData, RawExpressionSetData);

7
src/model/Category.ts Normal file
View File

@ -0,0 +1,7 @@
export type CategoryId = number;
export type Category = {
id: CategoryId;
name: string;
description: string;
};

7
src/model/Expression.ts Normal file
View File

@ -0,0 +1,7 @@
export type ExpressionId = number;
export type Expression = {
id: ExpressionId;
prompt: string;
description: string;
};

View File

@ -0,0 +1,7 @@
export type ExpressionSetId = number;
export type ExpressionSet = {
id: ExpressionSetId;
name: string;
description: string;
};

View File

@ -0,0 +1,13 @@
import { CategoryId } from "./Category";
import { ExpressionId } from "./Expression";
import { ExpressionSetId } from "./ExpressionSet";
export type ExpressionToCategory = {
expression_id: ExpressionId;
category_id: CategoryId;
};
export type ExpressionToExpressionSet = {
expression_id: ExpressionId;
expression_set_id: ExpressionSetId;
};

4
src/model/index.ts Normal file
View File

@ -0,0 +1,4 @@
export * from "./Category";
export * from "./Expression";
export * from "./ExpressionSet";
export * from "./Relationships";

View File

@ -0,0 +1,37 @@
import type { NextPage } from "next";
import Link from "next/link";
import { ExpressionSetCard } from "../components/ExpressionSetCard";
import { Page } from "../components/Page";
import { useExpressionData } from "../hooks/useExpressionData";
const ExpressionSetsPage: NextPage = () => {
const { expression_sets, expression_to_expression_set } = useExpressionData();
return (
<Page>
<div className="content-list">
{expression_sets.map(({ id, name, description }) => (
<Link
key={id}
href={{ pathname: "/practice", query: { "set-id": id } }}
passHref
>
<a>
<ExpressionSetCard
name={name}
description={description}
word_count={
expression_to_expression_set.filter(
(item) => item.expression_set_id === id
).length
}
/>
</a>
</Link>
))}
</div>
</Page>
);
};
export default ExpressionSetsPage;

View File

@ -19,6 +19,16 @@
display: block; display: block;
flex: 1; flex: 1;
position: relative; position: relative;
/* Will it conflict with overlays? Move elsewhere? */
padding: 16px;
overflow-y: auto;
}
.content-list {
display: grid;
grid-template-columns: 1fr;
grid-gap: 16px;
} }
/* Navigation */ /* Navigation */