more vocab work

This commit is contained in:
Michael Zhang 2023-06-15 00:32:12 -05:00
parent 00ec52a9a4
commit 84e5c926df
9 changed files with 111 additions and 20 deletions

View file

@ -151,8 +151,7 @@ pub async fn get_kanji(
if let Some(character) = &opts.character {
query = query.bind(character.clone());
}
query = query.bind(opts.skip);
query = query.bind(opts.how_many);
query = query.bind(opts.skip).bind(opts.how_many);
let result = query
.fetch_all(&kanji_db.0)

View file

@ -5,14 +5,15 @@ use crate::kanji::KanjiDb;
#[derive(Debug, Serialize, Deserialize)]
pub struct Vocab {
id: u32,
kanji_writing: String,
kana_writing: String,
furigana: String,
is_common: bool,
jlpt_level: u32,
wanikani_level: u32,
frequency_rank: u32,
jlpt_level: Option<u32>,
wanikani_level: Option<u32>,
frequency_rank: Option<u32>,
}
#[derive(Debug, Derivative, Serialize, Deserialize)]
@ -20,6 +21,21 @@ pub struct Vocab {
pub struct GetVocabOptions {
#[serde(default)]
kanji_id: Option<u32>,
#[serde(default = "default_skip")]
#[derivative(Default(value = "0"))]
skip: u32,
#[serde(default = "default_how_many")]
#[derivative(Default(value = "40"))]
how_many: u32,
}
fn default_skip() -> u32 {
0
}
fn default_how_many() -> u32 {
40
}
#[derive(Debug, Serialize, Deserialize)]
@ -35,10 +51,46 @@ pub async fn get_vocab(
) -> Result<GetVocabResult, String> {
let opts = options.unwrap_or_default();
let kanji_filter_clause = match opts.kanji_id {
Some(_) => format!(
r#"
JOIN KanjiEntityVocabEntity ON KanjiEntityVocabEntity.Vocabs_ID = VocabSet.ID
WHERE KanjiEntityVocabEntity.Kanji_ID = ?
"#
),
None => String::new(),
};
let query_string = format!(
r#"
SELECT * FROM VocabSet
{kanji_filter_clause}
LIMIT ?, ?
"#
);
let mut query = sqlx::query(&query_string);
if let Some(kanji_id) = opts.kanji_id {
query = query.bind(kanji_id);
}
query = query.bind(opts.skip).bind(opts.how_many);
let rows = query
.fetch_all(&kanji_db.0)
.await
.map_err(|err| err.to_string())?;
let vocab = rows
.into_iter()
.map(|row| Vocab {
id: row.get("ID"),
kanji_writing: row.get("KanjiWriting"),
kana_writing: row.get("KanaWriting"),
furigana: row.get("Furigana"),
is_common: row.get("IsCommon"),
jlpt_level: row.get("JlptLevel"),
wanikani_level: row.get("WkLevel"),
frequency_rank: row.get("FrequencyRank"),
})
.collect();
// Count query
let count = {
@ -73,8 +125,5 @@ pub async fn get_vocab(
row.get("Count")
};
Ok(GetVocabResult {
count,
vocab: vec![],
})
Ok(GetVocabResult { count, vocab })
}

View file

@ -20,7 +20,7 @@
.groupHeader {
h1 {
font-size: 2.5em;
text-shadow: 1px 1px black;
text-shadow: 1px 2px black;
}
}
@ -30,6 +30,7 @@
justify-content: space-evenly;
h3 {
border-radius: 4px;
border: 1px solid rgba(255, 255, 255, 0.5);
background-color: rgba(255, 255, 255, 0.25);
}

View file

@ -82,6 +82,8 @@ $kanjiDisplaySize: 120px;
.vocabSection {
flex-grow: 1;
min-height: 0;
display: flex;
flex-direction: column;
gap: 8px;
@ -92,5 +94,6 @@ $kanjiDisplaySize: 120px;
.vocabList {
flex-grow: 1;
min-height: 0;
}
}

View file

@ -1,3 +1,5 @@
$vocabColor: rgb(228, 251, 215);
.main {
width: 100%;
height: 100%;
@ -7,9 +9,25 @@
gap: 8px;
}
.searchBar {
flex-shrink: 0;
}
.vocabList {
flex-grow: 1;
border: 1px solid lightgray;
padding: 12px;
overflow-y: scroll;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 12px;
}
.vocabEntry {
padding: 8px;
background-color: $vocabColor;
border: 1px solid darken($vocabColor, 10%);
border-radius: 4px;
// box-shadow: 0 1px 2px darken($vocabColor, 50%);
}

View file

@ -24,13 +24,21 @@ export default function VocabList({ className, kanjiId }: VocabListProps) {
return (
<main className={classNames(styles.main, className)}>
<Input placeholder="Filter..." autoFocus />
<Input placeholder="Filter..." autoFocus className={styles.searchBar} />
<div>
Displaying {data.vocab.length} of {data.count} results. ({kanjiId})
</div>
<div className={styles.vocabList}></div>
<div className={styles.vocabList}>
{data.vocab.map((vocab) => (
<div key={vocab.id} className={styles.vocabEntry}>
{vocab.kanji_writing}
<br />
{vocab.kana_writing}
</div>
))}
</div>
</main>
);
}

View file

@ -3,4 +3,12 @@ export interface GetVocabResult {
vocab: Vocab[];
}
export interface Vocab {}
export interface Vocab {
id: number;
kanji_writing: string;
kana_writing: string;
furigana: string;
jlpt_level?: number;
wanikani_level?: number;
}

View file

@ -10,7 +10,7 @@
padding: 16px;
}
.test-word {
.testWord {
width: 100%;
text-align: center;
font-size: 4em;
@ -19,9 +19,11 @@
.needHelp {
margin-top: 16px;
display: flex;
summary {
cursor: pointer;
margin-bottom: 8px;
}
}
@ -36,5 +38,8 @@
.possibleAnswer {
border: 1px solid rgba(0, 0, 0, 0.25);
font-size: 1.1em;
padding: 4px 8px;
padding: 4px 12px;
border-radius: 4px;
background-color: rgba(255, 255, 255, 0.25);
cursor: pointer;
}

View file

@ -147,7 +147,7 @@ export function Component() {
/>
)}
<h1 className={styles["test-word"]}>{nextItem.challenge}</h1>
<h1 className={styles.testWord}>{nextItem.challenge}</h1>
<InputBox
submit={formSubmit}