sync
This commit is contained in:
parent
f079944a3e
commit
3d83b239bd
8 changed files with 169 additions and 54 deletions
31
src/App.vue
31
src/App.vue
|
@ -1,30 +1,47 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import MainMenu from './components/MainMenu.vue'
|
import MainMenu from './components/MainMenu.vue'
|
||||||
import Search from './components/Search.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 {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
MainMenu,
|
MainMenu,
|
||||||
Search,
|
Search,
|
||||||
Data,
|
Papers,
|
||||||
|
FooterMenu,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
applicationName: this.applicationName,
|
applicationName: this.applicationName,
|
||||||
|
cityName: this.cityName,
|
||||||
|
search: {
|
||||||
|
value: '',
|
||||||
|
type: '',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<header class="w-screen flex flex-row place-content-center">
|
<header class="w-screen flex flex-col place-content-center">
|
||||||
<h1 class="p-2 text-xl">{{ applicationName }}</h1>
|
<div class="flex flex-row place-content-center bg-amber-300 text-sky-700">
|
||||||
|
<h1 class="p-2 text-xl">{{ applicationName }} {{ cityName }}</h1>
|
||||||
<MainMenu />
|
<MainMenu />
|
||||||
<Search />
|
</div>
|
||||||
|
<Search
|
||||||
|
@searchSubmit="(type) => search.type = type"
|
||||||
|
@searchQuery="(query) => search.value = query"
|
||||||
|
/>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main>
|
<main class="max-w-5xl m-auto">
|
||||||
<Data />
|
<p>Ergebnisse für „{{ search.value }}/{{ search.type }}“</p>
|
||||||
|
<Papers :filterValue="search.value" />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<FooterMenu />
|
||||||
|
</footer>
|
||||||
</template>
|
</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 {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
menuEntries: this.menuEntries,
|
menuEntries: this.mainMenuEntries,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ export default {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ul class="flex flex-row place-content-center">
|
<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>
|
<a :href="entry.uri">{{ entry.name }}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</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">
|
<script lang="ts">
|
||||||
export default {
|
export default {
|
||||||
|
updated() {
|
||||||
|
this.$emit('searchQuery', this.search.value)
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchTerm: '',
|
search: {
|
||||||
|
value: '',
|
||||||
|
type: '',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit(type: string) {
|
||||||
|
this.search.type = type
|
||||||
|
this.$emit('searchSubmit', this.search.type)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<form>
|
<form class="sticky top-0 flex flex-row place-content-center bg-amber-200">
|
||||||
<input class="p-2" type="search" placeholder="Suche …">
|
<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>
|
</form>
|
||||||
</template>
|
</template>
|
13
src/main.ts
13
src/main.ts
|
@ -9,7 +9,8 @@ app.config.globalProperties = {
|
||||||
...app.config.globalProperties,
|
...app.config.globalProperties,
|
||||||
apiUri: 'https://joergreichert.de/srm/input.json',
|
apiUri: 'https://joergreichert.de/srm/input.json',
|
||||||
applicationName: 'Stadtratmonitor',
|
applicationName: 'Stadtratmonitor',
|
||||||
menuEntries: {
|
cityName: 'Leipzig',
|
||||||
|
mainMenuEntries: {
|
||||||
0: {
|
0: {
|
||||||
name: 'Startseite',
|
name: 'Startseite',
|
||||||
uri: '/',
|
uri: '/',
|
||||||
|
@ -23,6 +24,16 @@ app.config.globalProperties = {
|
||||||
uri: '/glossar'
|
uri: '/glossar'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
footerMenuEntries: {
|
||||||
|
0: {
|
||||||
|
name: 'Impressum',
|
||||||
|
uri: '/impressum',
|
||||||
|
},
|
||||||
|
1: {
|
||||||
|
name: 'Über diese Seite',
|
||||||
|
uri: '/über'
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|
Loading…
Reference in a new issue