populate events trough apicall and save active event in url
This commit is contained in:
		
							parent
							
								
									fbf6d9dc91
								
							
						
					
					
						commit
						cc9ba38dac
					
				
					 11 changed files with 137 additions and 61 deletions
				
			
		
							
								
								
									
										2
									
								
								.env.example
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.env.example
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
VUE_APP_CONFIG_API_USER=rest api user
 | 
			
		||||
VUE_APP_CONFIG_API_PASSWORD=rest api password
 | 
			
		||||
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -3,6 +3,7 @@ node_modules
 | 
			
		|||
/dist
 | 
			
		||||
 | 
			
		||||
# local env files
 | 
			
		||||
.env
 | 
			
		||||
.env.local
 | 
			
		||||
.env.*.local
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								API.md
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								API.md
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -55,4 +55,4 @@ returns a list of all tracked events
 | 
			
		|||
 | 
			
		||||
### Files/Images
 | 
			
		||||
 | 
			
		||||
#### ``GET /api/images/<file.hash>``
 | 
			
		||||
#### ``GET /api/<version.major>/images/<file.hash>``
 | 
			
		||||
| 
						 | 
				
			
			@ -11,15 +11,20 @@
 | 
			
		|||
    "@fortawesome/fontawesome-svg-core": "^1.2.25",
 | 
			
		||||
    "@fortawesome/free-solid-svg-icons": "^5.11.2",
 | 
			
		||||
    "@fortawesome/vue-fontawesome": "^0.1.8",
 | 
			
		||||
    "axios": "^0.19.0",
 | 
			
		||||
    "bootstrap": "^4.3.1",
 | 
			
		||||
    "core-js": "^3.3.2",
 | 
			
		||||
    "dotenv-webpack": "^1.7.0",
 | 
			
		||||
    "jquery": "^3.4.1",
 | 
			
		||||
    "lodash": "^4.17.15",
 | 
			
		||||
    "node-sass": "^4.13.0",
 | 
			
		||||
    "popper.js": "^1.16.0",
 | 
			
		||||
    "ramda": "^0.26.1",
 | 
			
		||||
    "sass-loader": "^8.0.0",
 | 
			
		||||
    "vue": "^2.6.10",
 | 
			
		||||
    "vuex": "^3.1.2"
 | 
			
		||||
    "vue-router": "^3.1.3",
 | 
			
		||||
    "vuex": "^3.1.2",
 | 
			
		||||
    "vuex-router-sync": "^5.0.0"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@vue/cli-plugin-babel": "^4.0.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										33
									
								
								src/App.vue
									
										
									
									
									
								
							
							
						
						
									
										33
									
								
								src/App.vue
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,46 +1,17 @@
 | 
			
		|||
<template>
 | 
			
		||||
    <div id="app">
 | 
			
		||||
        <Navbar/>
 | 
			
		||||
        <div class="container-fluid px-xl-5 mt-3">
 | 
			
		||||
            <div class="row" v-if="layout === 'table'">
 | 
			
		||||
                <div class="col-xl-8 offset-xl-2">
 | 
			
		||||
                    <Table
 | 
			
		||||
                        :columns="['uid', 'description', 'box', 'image']"
 | 
			
		||||
                        :items="loadedItems"
 | 
			
		||||
                        :keyName="'uid'"
 | 
			
		||||
                    />
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <Cards
 | 
			
		||||
                v-if="layout === 'cards'"
 | 
			
		||||
                :columns="['uid', 'description', 'box', 'image']"
 | 
			
		||||
                :items="loadedItems"
 | 
			
		||||
                :keyName="'uid'"
 | 
			
		||||
                v-slot="{ item }"
 | 
			
		||||
            >
 | 
			
		||||
                <img
 | 
			
		||||
                    :src="`https://picsum.photos/id/${item.image + 50}/200/200`"
 | 
			
		||||
                    alt="item"
 | 
			
		||||
                    class="card-img-top img-fluid"
 | 
			
		||||
                >
 | 
			
		||||
                <div class="card-body">
 | 
			
		||||
                    <h6 class="card-title">{{ item.description }}</h6>
 | 
			
		||||
                    <h6 class="card-subtitle text-secondary">uid: {{ item.uid }} box: {{ item.box }}</h6>
 | 
			
		||||
                </div>
 | 
			
		||||
            </Cards>
 | 
			
		||||
        </div>
 | 
			
		||||
        <router-view></router-view>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Table from '@/components/Table';
 | 
			
		||||
import Navbar from '@/components/Navbar';
 | 
			
		||||
import Cards from '@/components/Cards';
 | 
			
		||||
import { mapState } from 'vuex';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'app',
 | 
			
		||||
  components: { Navbar, Table, Cards },
 | 
			
		||||
  components: { Navbar },
 | 
			
		||||
  computed: mapState(['loadedItems', 'layout'])
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,11 +28,11 @@
 | 
			
		|||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="col-lg-9 col-xl-8">
 | 
			
		||||
            <transition-group name="card-list" tag="div" class="card-columns">
 | 
			
		||||
            <div class="card-columns">
 | 
			
		||||
                <div class="card-list-item card bg-dark text-light" v-for="item in internalItems" :key="item[keyName]">
 | 
			
		||||
                    <slot v-bind:item="item"/>
 | 
			
		||||
                </div>
 | 
			
		||||
            </transition-group>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			@ -48,14 +48,3 @@ export default {
 | 
			
		|||
  }
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
 | 
			
		||||
    .card-list-enter, .card-list-leave-to {
 | 
			
		||||
        opacity: 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .card-list-leave-active {
 | 
			
		||||
        position: absolute;
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -3,11 +3,11 @@
 | 
			
		|||
        <div class="dropdown">
 | 
			
		||||
            <button class="btn text-light dropdown-toggle btn-heading" type="button" id="dropdownMenuButton"
 | 
			
		||||
                    data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
 | 
			
		||||
                {{ activeEvent.slug }}
 | 
			
		||||
                {{getEventSlug}}
 | 
			
		||||
            </button>
 | 
			
		||||
            <div class="dropdown-menu bg-dark" aria-labelledby="dropdownMenuButton">
 | 
			
		||||
                <a class="dropdown-item text-light" href="#" v-for="(event, index) in events" v-bind:key="index"
 | 
			
		||||
                   :class="{ active: event === activeEvent }" @click="changeEvent(event)">{{ event.slug }}</a>
 | 
			
		||||
                   :class="{ active: event.slug === getEventSlug }" @click="changeEvent(event)">{{ event.slug }}</a>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +58,7 @@
 | 
			
		|||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { mapState, mapActions, mapMutations } from 'vuex';
 | 
			
		||||
import { mapState, mapActions, mapMutations, mapGetters} from 'vuex';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
| 
						 | 
				
			
			@ -79,6 +79,7 @@ export default {
 | 
			
		|||
  }),
 | 
			
		||||
  computed: {
 | 
			
		||||
    ...mapState(['events', 'activeEvent', 'layout']),
 | 
			
		||||
      ...mapGetters(['getEventSlug']),
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    ...mapActions(['changeEvent']),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
import Vue from 'vue';
 | 
			
		||||
import App from './App.vue';
 | 
			
		||||
import store from './store';
 | 
			
		||||
import router from './router';
 | 
			
		||||
import { sync } from 'vuex-router-sync';
 | 
			
		||||
 | 
			
		||||
// bootstrap
 | 
			
		||||
import 'jquery/dist/jquery.min.js';
 | 
			
		||||
| 
						 | 
				
			
			@ -12,12 +14,17 @@ import { library } from '@fortawesome/fontawesome-svg-core';
 | 
			
		|||
import { faPlus, faCheckCircle, faEdit, faTrash, faCat, faSyncAlt, faSort, faSortUp, faSortDown, faTh, faList, faWindowClose } from '@fortawesome/free-solid-svg-icons';
 | 
			
		||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
library.add(faPlus, faCheckCircle, faEdit, faTrash, faCat, faSyncAlt, faSort, faSortUp, faSortDown, faTh, faList, faWindowClose);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Vue.component('font-awesome-icon', FontAwesomeIcon);
 | 
			
		||||
 | 
			
		||||
sync(store, router);
 | 
			
		||||
 | 
			
		||||
new Vue({
 | 
			
		||||
  el: '#app',
 | 
			
		||||
  store,
 | 
			
		||||
  router,
 | 
			
		||||
  render: h => h(App),
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								src/router.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/router.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
import Items from './views/Items';
 | 
			
		||||
import VueRouter from 'vue-router';
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Vue.use(VueRouter);
 | 
			
		||||
 | 
			
		||||
const routes = [
 | 
			
		||||
  { path: '/:event', component: Items},
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
const router = new VueRouter({
 | 
			
		||||
  mode: 'history',
 | 
			
		||||
  routes
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default router;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,16 +1,14 @@
 | 
			
		|||
import Vue from 'vue';
 | 
			
		||||
import Vuex from 'vuex';
 | 
			
		||||
import axios from 'axios';
 | 
			
		||||
//import * as _ from 'lodash/fp';
 | 
			
		||||
import router from '../router';
 | 
			
		||||
 | 
			
		||||
Vue.use(Vuex);
 | 
			
		||||
 | 
			
		||||
export default new Vuex.Store({
 | 
			
		||||
const store = new Vuex.Store({
 | 
			
		||||
  state: {
 | 
			
		||||
    events: [
 | 
			
		||||
      {'slug': '35C3'},
 | 
			
		||||
      {'slug': 'camp19'},
 | 
			
		||||
      {'slug': '36C3'}
 | 
			
		||||
    ],
 | 
			
		||||
    activeEvent: {'slug': '36C3'},
 | 
			
		||||
    events: Array,
 | 
			
		||||
    layout: 'cards',
 | 
			
		||||
    loadedItems: [
 | 
			
		||||
      { uid: 1, description: 'sleeping bag', box: 7, image: 41 },
 | 
			
		||||
| 
						 | 
				
			
			@ -29,19 +27,55 @@ export default new Vuex.Store({
 | 
			
		|||
      { uid: 14, description: 'toy truck', box: 6, image: 51 }
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  getters: {
 | 
			
		||||
    getEventSlug: state => state.route.params.event,
 | 
			
		||||
  },
 | 
			
		||||
  mutations: {
 | 
			
		||||
    replaceEvents(state, events) {
 | 
			
		||||
      state.events = events;
 | 
			
		||||
      //if (!state.activeEvent || !events.includes(state.activeEvent))
 | 
			
		||||
      //  state.activeEvent = _.reverse(events)[0];
 | 
			
		||||
    },
 | 
			
		||||
    changeEvent(state, event) {
 | 
			
		||||
      state.activeEvent = event;
 | 
			
		||||
      router.push({path: `/${event.slug}`});
 | 
			
		||||
    },
 | 
			
		||||
    replaceLoadedItems(state, newItems) {
 | 
			
		||||
      state.loadedItems = newItems;
 | 
			
		||||
    },
 | 
			
		||||
    setLayout(state, layout) {
 | 
			
		||||
      state.layout = layout;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  actions: {
 | 
			
		||||
    changeEvent({ commit }, event) {
 | 
			
		||||
      // todo: load items from server
 | 
			
		||||
      // todo: load items from server
 | 
			
		||||
      commit('changeEvent', event);
 | 
			
		||||
    async loadEvents({ commit }) {
 | 
			
		||||
      const resp = await axios.get('https://c3lf.de/api/1/events',  {
 | 
			
		||||
        auth: {
 | 
			
		||||
          username: process.env.VUE_APP_CONFIG_API_USER,
 | 
			
		||||
          password: process.env.VUE_APP_CONFIG_API_PASSWORD
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      commit('replaceEvents', resp.data);
 | 
			
		||||
    },
 | 
			
		||||
    changeEvent({ commit, dispatch }, eventName) {
 | 
			
		||||
      commit('changeEvent', eventName);
 | 
			
		||||
      dispatch('loadEventItems', eventName);
 | 
			
		||||
    },
 | 
			
		||||
    async loadEventItems({ commit, state }) {
 | 
			
		||||
      const resp = await axios.get(`https://c3lf.de/api/1/${state.route.params.event}/items`,  {
 | 
			
		||||
        auth: {
 | 
			
		||||
          username: process.env.VUE_APP_CONFIG_API_USER,
 | 
			
		||||
          password: process.env.VUE_APP_CONFIG_API_PASSWORD
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      console.log(resp.data);
 | 
			
		||||
 | 
			
		||||
      commit('replaceLoadedItems', resp.data);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default store;
 | 
			
		||||
 | 
			
		||||
store.dispatch('loadEvents');
 | 
			
		||||
							
								
								
									
										48
									
								
								src/views/Items.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/views/Items.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
<template>
 | 
			
		||||
    <div class="container-fluid px-xl-5 mt-3">
 | 
			
		||||
        <div class="row" v-if="layout === 'table'">
 | 
			
		||||
            <div class="col-xl-8 offset-xl-2">
 | 
			
		||||
                <Table
 | 
			
		||||
                        :columns="['uid', 'description', 'box', 'image']"
 | 
			
		||||
                        :items="loadedItems"
 | 
			
		||||
                        :keyName="'uid'"
 | 
			
		||||
                />
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <Cards
 | 
			
		||||
                v-if="layout === 'cards'"
 | 
			
		||||
                :columns="['uid', 'description', 'box', 'image']"
 | 
			
		||||
                :items="loadedItems"
 | 
			
		||||
                :keyName="'uid'"
 | 
			
		||||
                v-slot="{ item }"
 | 
			
		||||
        >
 | 
			
		||||
            <img
 | 
			
		||||
                    :src="`https://picsum.photos/id/${item.image + 50}/200/200`"
 | 
			
		||||
                    alt="item"
 | 
			
		||||
                    class="card-img-top img-fluid"
 | 
			
		||||
            >
 | 
			
		||||
            <div class="card-body">
 | 
			
		||||
                <h6 class="card-title">{{ item.description }}</h6>
 | 
			
		||||
                <h6 class="card-subtitle text-secondary">uid: {{ item.uid }} box: {{ item.box }}</h6>
 | 
			
		||||
            </div>
 | 
			
		||||
        </Cards>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Table from '@/components/Table';
 | 
			
		||||
import Cards from '@/components/Cards';
 | 
			
		||||
import { mapState } from 'vuex';
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'Items',
 | 
			
		||||
  components: { Table, Cards },
 | 
			
		||||
  created() {
 | 
			
		||||
    console.log(this.$route.params.event);
 | 
			
		||||
  },
 | 
			
		||||
  computed: mapState(['loadedItems', 'layout']),
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue