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

add search component #18

Merged
merged 15 commits into from
Mar 1, 2025
127 changes: 127 additions & 0 deletions components/SearchHistory.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<script setup lang='ts'>
import { ref } from 'vue'
import type { Category, Record, HistoryAvailable } from '@/interfaces'
import type { Header, Item } from 'vue3-easy-data-table'
const allCategoryText: string = '全カテゴリ'

const headers = ref<Header[]>([
{ text: 'ID', value: 'id' },
{ text: 'カテゴリ名', value: 'category_name', sortable: true },
{ text: '利用日', value: 'datetime', sortable: true },
{ text: '登録元', value: 'from' },
{ text: '金額', value: 'price', sortable: true },
{ text: 'メモ', value: 'memo' },
])

const options_yyyymm = ref<string[]>()
const options_categoryID = ref<Category[]>([])

const asyncHistoryData = await $fetch(`/api/getHistories`)
const historyData = asyncHistoryData as Record[]

// fetchデータを整形
if (historyData != undefined) { // 取得済の場合のみ
for (const d of historyData) {
d.datetime = d.datetime.slice(0, 19) // 2023-09-23T00:00:00+09:00 -> 2023-09-23T00:00:00
}
}

const items = ref<Item[]>(historyData)

const selected_yyyymm_value = ref<string | null>(null)
const selected_categoryID_value = ref<string | null>(null) // 実際に選択されている値が入る

onMounted(async () => {
const asyncHistoryData = await $fetch(`/api/getHistories`)
const historyData = asyncHistoryData as Record[]
// fetchデータを整形
if (historyData != undefined) { // 取得済の場合のみ
for (const d of historyData) {
d.datetime = d.datetime.slice(0, 19) // 2023-09-23T00:00:00+09:00 -> 2023-09-23T00:00:00
}
}

const asyncCategoryData = await $fetch(`/api/getCategories`)
options_categoryID.value = asyncCategoryData as Category[]
const allCategory: Category = {
category_id: 0,
category_name: allCategoryText,
}
options_categoryID.value.unshift(allCategory) // 全カテゴリをカテゴリの先頭に追加
if (options_categoryID.value.length > 0) {
await nextTick()
selected_categoryID_value.value = String(options_categoryID.value[0].category_id)
}

const asyncAvailableData = await $fetch(`/api/getAvailable`) as HistoryAvailable
options_yyyymm.value = asyncAvailableData.yyyymm as string[]
if (options_yyyymm.value.length > 0) {
await nextTick()
selected_yyyymm_value.value = String(options_yyyymm.value[0])
}
})

const fetchData = async (yyyymm: string, categoryID: string) => {
try {
if (yyyymm == null) {
// パラメータが不正なときは何もしない
return
}

let query = `?yyyymm=${yyyymm}`
// categoryID が null または undefined の場合、'-1' に置き換える
const validCategoryID = categoryID ? categoryID : '-1'
if (validCategoryID == '-1') {
// パラメータが不正なときは何もしない
return
}

if (categoryID != '0') {
// 0 = 全カテゴリ
query += `&category_id=${validCategoryID}`
}

const data = await $fetch(`/api/getHistories${query}`)
items.value = data as Record[]
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
catch (error) {
// ToDo: error handling
// console.error('Error fetching data:', error)
}
}

// 選択変更時に実行する処理
watch(
[selected_yyyymm_value, selected_categoryID_value],
([new_yyyymm_value, new_categoryID_value]) => {
fetchData(String(new_yyyymm_value), String(new_categoryID_value))
},
)
</script>

<template>
<div class='row justify-content-center'>
<h2>レコード</h2>

<div class='col-2 mb-2'>
<label for="dropdown" class="d-block">取得月:</label>
<select id="dropdown" v-model="selected_yyyymm_value">
<option v-for="option in options_yyyymm" :key="option" :value="option">
{{ option }}
</option>
</select>
</div>
<div class='col-2 mb-2'>
<label for="dropdown" class="d-block">カテゴリ名:</label>
<select id="dropdown" v-model="selected_categoryID_value">
<option v-for="option in options_categoryID" :key="option.category_id" :value="option.category_id">
{{ option.category_name }}
</option>
</select>
</div>

<EasyDataTable :headers="headers" :items="items" />
</div>
</template>
5 changes: 5 additions & 0 deletions interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ export interface Category {
category_name: string
}

export interface HistoryAvailable {
fy: string[]
yyyymm: string[]
}

export interface SummaryOne {
category_id: number
category_name: string
Expand Down
26 changes: 23 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"bootstrap": "^5.3.0",
"eslint-plugin-react": "^7.35.0",
"nuxt": "^3.12.4",
"vue": "latest"
"vue": "latest",
"vue3-easy-data-table": "^1.5.47"
},
"devDependencies": {
"@nuxt/eslint": "^0.5.6",
Expand Down
13 changes: 13 additions & 0 deletions pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ if (thisMonth <= 3) {
</NuxtLink>
</div>

<div class='search_link'>
<NuxtLink v-bind:to="{name: 'search'}">
履歴検索
</NuxtLink>
</div>

<h2>直近履歴</h2>
<ShowHistory />

Expand All @@ -42,4 +48,11 @@ h2 {
margin-left: auto;
margin-right: auto;
}

.search_link {
text-align: center;
margin-left: auto;
margin-right: auto;
}

</style>
24 changes: 24 additions & 0 deletions pages/search/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script setup lang='ts'>
</script>

<template>
<section>
<div class='container-sm text-center'>
<SearchHistory />
</div>
</section>
</template>

<style lang='css'>
h2 {
text-align: center;
margin-left: auto;
margin-right: auto;
}

.summary_link {
text-align: center;
margin-left: auto;
margin-right: auto;
}
</style>
6 changes: 6 additions & 0 deletions plugins/easy-data-table.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Vue3EasyDataTable from 'vue3-easy-data-table'
import 'vue3-easy-data-table/dist/style.css'

export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.component('EasyDataTable', Vue3EasyDataTable)
})
10 changes: 10 additions & 0 deletions server/api/getAvailable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default defineEventHandler(async () => {
const config = useRuntimeConfig()
const url = config.public.mawinterApi + '/v2/record/available'
const result = await $fetch(url,
{
method: 'GET',
},
)
return result
})
21 changes: 21 additions & 0 deletions server/api/getHistories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig()
const query = getQuery(event)
const params: { [key: string]: string } = {}
if (query.yyyymm != undefined) {
params.yyyymm = String(query.yyyymm)
}
if (query.category_id != undefined) {
params.category_id = String(query.category_id)
}
params.num = '1000' // default の取得限界数

const queryParams = new URLSearchParams(params)
const url = config.public.mawinterApi + '/v2/record?' + queryParams
const result = await $fetch(url,
{
method: 'GET',
},
)
return result
})
2 changes: 1 addition & 1 deletion server/api/history.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default defineEventHandler (async () => {
export default defineEventHandler(async () => {
const config = useRuntimeConfig()
const url = config.public.mawinterApi + '/v2/record'
const result = await $fetch(url,
Expand Down
Loading
Loading