sync
This commit is contained in:
parent
f079944a3e
commit
3d83b239bd
8 changed files with 169 additions and 54 deletions
33
src/App.vue
33
src/App.vue
|
@ -1,30 +1,47 @@
|
|||
<script lang="ts">
|
||||
import MainMenu from './components/MainMenu.vue'
|
||||
import Search from './components/Search.vue'
|
||||
import Data from './components/Data.vue'
|
||||
import Papers from './components/Papers.vue'
|
||||
import FooterMenu from './components/FooterMenu.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MainMenu,
|
||||
Search,
|
||||
Data,
|
||||
Papers,
|
||||
FooterMenu,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
applicationName: this.applicationName,
|
||||
cityName: this.cityName,
|
||||
search: {
|
||||
value: '',
|
||||
type: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header class="w-screen flex flex-row place-content-center">
|
||||
<h1 class="p-2 text-xl">{{ applicationName }}</h1>
|
||||
<MainMenu />
|
||||
<Search />
|
||||
<header class="w-screen flex flex-col place-content-center">
|
||||
<div class="flex flex-row place-content-center bg-amber-300 text-sky-700">
|
||||
<h1 class="p-2 text-xl">{{ applicationName }} {{ cityName }}</h1>
|
||||
<MainMenu />
|
||||
</div>
|
||||
<Search
|
||||
@searchSubmit="(type) => search.type = type"
|
||||
@searchQuery="(query) => search.value = query"
|
||||
/>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<Data />
|
||||
<main class="max-w-5xl m-auto">
|
||||
<p>Ergebnisse für „{{ search.value }}/{{ search.type }}“</p>
|
||||
<Papers :filterValue="search.value" />
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<FooterMenu />
|
||||
</footer>
|
||||
</template>
|
|
@ -1,39 +0,0 @@
|
|||
<script lang="ts">
|
||||
interface Paper {
|
||||
url: string
|
||||
}
|
||||
|
||||
export default {
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
apiUri: 'https://raw.githubusercontent.com/CodeforLeipzig/stadtratmonitor/master/input.json',
|
||||
papers: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async fetchData() {
|
||||
this.papers = await (await fetch(this.apiUri)).json()
|
||||
},
|
||||
filterData() {
|
||||
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ul>
|
||||
<li v-for="paper in papers">
|
||||
<article>
|
||||
<a :href="paper.url">
|
||||
<h4 class="text-xl">{{ paper.name }}</h4>
|
||||
<p>{{ paper.published_at }}: FIXME von {{ paper.originator }}</p>
|
||||
</a>
|
||||
</article>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
17
src/components/FooterMenu.vue
Normal file
17
src/components/FooterMenu.vue
Normal file
|
@ -0,0 +1,17 @@
|
|||
<script lang="ts">
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
menuEntries: this.footerMenuEntries,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ul class="flex flex-row place-content-center">
|
||||
<li class="p-2 place-content-center" v-for="entry of menuEntries">
|
||||
<a :href="entry.uri">{{ entry.name }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
|
@ -2,7 +2,7 @@
|
|||
export default {
|
||||
data() {
|
||||
return {
|
||||
menuEntries: this.menuEntries,
|
||||
menuEntries: this.mainMenuEntries,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<ul class="flex flex-row place-content-center">
|
||||
<li class="p-2 place-content-center" v-for="entry of menuEntries">
|
||||
<li class="p-2 place-content-center" v-for="(entry, i) of menuEntries" :key="i">
|
||||
<a :href="entry.uri">{{ entry.name }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
7
src/components/Paper.vue
Normal file
7
src/components/Paper.vue
Normal file
|
@ -0,0 +1,7 @@
|
|||
<script lang="ts">
|
||||
export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
</template>
|
66
src/components/Papers.vue
Normal file
66
src/components/Papers.vue
Normal file
|
@ -0,0 +1,66 @@
|
|||
<script lang="ts">
|
||||
type Papers = {
|
||||
body: string
|
||||
content: string
|
||||
name: string
|
||||
resolution: string
|
||||
originator: string
|
||||
paper_type: string
|
||||
published_at: string
|
||||
reference: string
|
||||
url: string
|
||||
}
|
||||
|
||||
export default {
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
apiUri: 'https://raw.githubusercontent.com/CodeforLeipzig/stadtratmonitor/master/input.json',
|
||||
papers: [] as Papers[],
|
||||
}
|
||||
},
|
||||
props: {
|
||||
filterValue: String,
|
||||
},
|
||||
computed: {
|
||||
filteredData() {
|
||||
const filterValue: string = this.filterValue
|
||||
let filteredPapers: Papers[] = []
|
||||
filteredPapers = this.papers.filter((paper) => paper.name.includes(filterValue))
|
||||
return filteredPapers
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async fetchData() {
|
||||
this.papers = await (await fetch(this.apiUri)).json()
|
||||
},
|
||||
openPaper() {}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ul v-if="filteredData.length">
|
||||
<li v-for="(paper, i) in filteredData" :key="i">
|
||||
<article
|
||||
class="my-4 p-2 border border-solid border-amber-300 rounded-md"
|
||||
@click.prevent="openPaper()"
|
||||
>
|
||||
<h4 class="text-xl">{{ paper.name }}</h4>
|
||||
<p>{{ paper.published_at }}: {{ paper.paper_type}} von {{ paper.originator }}</p>
|
||||
</article>
|
||||
</li>
|
||||
</ul>
|
||||
<p
|
||||
class="flex place-content-center my-60 text-lg"
|
||||
v-else-if="papers.length"
|
||||
>Für dieses Anfrage liegen uns keine Ergebnisse vor.
|
||||
</p>
|
||||
<p
|
||||
class="flex place-content-center my-60 text-lg"
|
||||
v-else
|
||||
>Da scheint etwas schief gelaufen zu sein.
|
||||
</p>
|
||||
</template>
|
|
@ -1,15 +1,51 @@
|
|||
<script lang="ts">
|
||||
export default {
|
||||
updated() {
|
||||
this.$emit('searchQuery', this.search.value)
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchTerm: '',
|
||||
search: {
|
||||
value: '',
|
||||
type: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit(type: string) {
|
||||
this.search.type = type
|
||||
this.$emit('searchSubmit', this.search.type)
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form>
|
||||
<input class="p-2" type="search" placeholder="Suche …">
|
||||
<form class="sticky top-0 flex flex-row place-content-center bg-amber-200">
|
||||
<div class="flex flex-row w-full max-w-5xl">
|
||||
<input
|
||||
class="p-6 grow bg-transparent placeholder:text-amber-400 text-sky-700 text-2xl text-center focus-visible:outline focus-visible:outline-current"
|
||||
type="search"
|
||||
placeholder="Suche z. B. nach XY"
|
||||
v-model="search.value"
|
||||
@keyup.alt.enter.exact="submit('assist')"
|
||||
@keyup.enter.exact="submit('filter')"
|
||||
/>
|
||||
<div class="flex flex-row p-4 place-content-center">
|
||||
<button
|
||||
class="py-2 px-4 bg-amber-400 hover:bg-amber-500 rounded-l-lg border-r-2 border-amber-500 text-white"
|
||||
@click.prevent="submit('filter')"
|
||||
aria-keyshortcuts="Enter"
|
||||
>Filter
|
||||
</button>
|
||||
<button
|
||||
class="py-2 px-4 bg-amber-400 hover:bg-amber-500 rounded-r-lg text-white"
|
||||
@click.prevent="submit('assist')"
|
||||
aria-keyshortcuts="Alt+Enter"
|
||||
title="Tastenkürzel: Alt + Enter"
|
||||
>Assistent
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
13
src/main.ts
13
src/main.ts
|
@ -9,7 +9,8 @@ app.config.globalProperties = {
|
|||
...app.config.globalProperties,
|
||||
apiUri: 'https://joergreichert.de/srm/input.json',
|
||||
applicationName: 'Stadtratmonitor',
|
||||
menuEntries: {
|
||||
cityName: 'Leipzig',
|
||||
mainMenuEntries: {
|
||||
0: {
|
||||
name: 'Startseite',
|
||||
uri: '/',
|
||||
|
@ -23,6 +24,16 @@ app.config.globalProperties = {
|
|||
uri: '/glossar'
|
||||
}
|
||||
},
|
||||
footerMenuEntries: {
|
||||
0: {
|
||||
name: 'Impressum',
|
||||
uri: '/impressum',
|
||||
},
|
||||
1: {
|
||||
name: 'Über diese Seite',
|
||||
uri: '/über'
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app.mount('#app')
|
||||
|
|
Loading…
Reference in a new issue