Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions 2wr-app/src/api/hazard-hunt-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ export default {
async getDocuments() {
return (await baseApiInstance.getInstance()).get('hazardhunt-list');
},
async get(id) {
return (await baseApiInstance.getInstance()).get(`hazardhunt-by-id/${id}`);
}
};
2 changes: 1 addition & 1 deletion 2wr-app/src/api/hazard-info-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ export default {

async get(id) {
return (await baseApiInstance.getInstance()).get(`hazardinfo-by-id/${id}`);
},
}
};
49 changes: 25 additions & 24 deletions 2wr-app/src/components/prepare/hazards/hazard-hunt-list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,33 @@
<v-container class="py-0">
<v-app-bar app flat dense fixed color="background">
<v-icon class="mr-2" v-on:click="goBack()">mdi-arrow-left</v-icon>
<v-icon class="mr-2">mdi-shield-search</v-icon>
<v-icon class="mr-2">mdi-shield-alert-outline</v-icon>
<v-toolbar-title>Hazard Hunt</v-toolbar-title>
</v-app-bar>
<v-progress-linear
v-if="loading"
indeterminate
color="green"
></v-progress-linear>
<v-data-iterator v-if="!loading" :items="hunts" disable-pagination disable-sort hide-default-footer
:search="search">
<template v-slot:header>
<v-text-field
v-model="search"
clearable
label="Search"
append-icon="mdi-magnify">
</v-text-field>
</template>
<template v-slot:default="props">
<v-card v-for="item in props.items" :key="item.id" class="my-4" ripple dark>
<v-card-title class="white--text">
<v-col class="col-9">
<!-- <v-icon class="mr-2 white--text">{{item.icon}}</v-icon> -->{{ item.name }}
</v-col>
</v-card-title>
<v-card-text>{{ item.description }}</v-card-text>
</v-card>
</template>
</v-data-iterator>
<v-row dense>
<v-col
v-for="item in items"
:key="item.id"
cols="6"
>
<v-card
@click="viewItem(item.id)">
<v-img
:src="item.iconUrl"
class="white--text align-end"
gradient="to bottom, rgba(0,0,0,.1), rgba(0,0,0,.5)"
height="200px"
>
<v-card-title v-text="item.name"></v-card-title>
</v-img>
</v-card>
</v-col>
</v-row>
</v-container>
</template>

Expand All @@ -45,15 +43,18 @@ export default {
};
},
computed: mapState({
hunts: state => state.hazardHuntStore.list
items: state => state.hazardHuntStore.list
}),
async created() {
await this.$store.dispatch(`hazardHuntStore/getHazardHuntsAsync`);
this.loading = false;
},
methods: {
goBack() {
window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/');
window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/');
},
viewItem(id){
this.$router.push(`/prepare/hazardhunt/${id}`);
}
}
}
Expand Down
164 changes: 164 additions & 0 deletions 2wr-app/src/components/prepare/hazards/hazard-hunt.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<template>
<v-container class="py-0">
<v-app-bar app flat dense fixed color="background">
<v-icon class="mr-2" v-on:click="goBack()">mdi-arrow-left</v-icon>
<v-img :src="item.iconUrl" max-height="48" max-width="48" class="mr-2"></v-img>
<v-toolbar-title>{{item ? item.name : 'Hazard Information'}}</v-toolbar-title>
</v-app-bar>
<v-row dense>
<v-col cols="12">
<p class="pa-2 headline">{{item.description}}</p>
</v-col>
<v-col cols="12">
<v-img v-if="mediaUrlIsImage" :src="item.mediaUrl"></v-img>
<!--TODO: Add option for videos once we have some sample videos -->
</v-col>
<v-col cols="12" class="text-center">
<h2>{{item.name}} Safety</h2>
</v-col>
<v-col cols="12" class="text-center">
<v-btn x-large color="primary" width="80%" @click="beforeDialog = true">Before</v-btn>
</v-col>
<v-col cols="12" class="text-center">
<v-btn x-large color="primary" width="80%" @click="duringDialog = true">During</v-btn>
</v-col>
<v-col cols="12" class="text-center">
<v-btn x-large color="primary" width="80%" @click="afterDialog = true">After</v-btn>
</v-col>
<v-col cols="12" class="text-center">
<h2>{{item.name}} Resources</h2>
</v-col>
<v-col cols="12">
<ul class="mb-6">
<li v-for="link in item.externalLinks" :key={link} class="pa-1">
<a :href="link" target="_blank">{{link}}</a><v-icon small class="ml-2">mdi-open-in-new</v-icon></li>
</ul>
</v-col>
</v-row>
<v-dialog
v-model="beforeDialog"
fullscreen
hide-overlay
transition="dialog-bottom-transition"
scrollable
>
<v-card tile color="background">
<v-toolbar class="flex-grow-0 mb-3"
flat
dark
color="primary"
>
<v-btn
icon
dark
@click="beforeDialog = false"
>
<v-icon>mdi-close</v-icon>
</v-btn>
<v-toolbar-title>{{item.name}} Safety: Before</v-toolbar-title>
</v-toolbar>
<v-card-text v-html="item.beforeSafetyDetails">
</v-card-text>
</v-card>
</v-dialog>
<v-dialog
v-model="duringDialog"
fullscreen
hide-overlay
transition="dialog-bottom-transition"
scrollable
>
<v-card tile color="background">
<v-toolbar class="flex-grow-0 mb-3"
flat
dark
color="primary"
>
<v-btn
icon
dark
@click="duringDialog = false"
>
<v-icon>mdi-close</v-icon>
</v-btn>
<v-toolbar-title>{{item.name}} Safety: During</v-toolbar-title>
</v-toolbar>
<v-card-text v-html="item.duringSafetyDetails">
</v-card-text>
</v-card>
</v-dialog>
<v-dialog
v-model="afterDialog"
fullscreen
hide-overlay
transition="dialog-bottom-transition"
scrollable
>
<v-card tile color="background">
<v-toolbar class="flex-grow-0 mb-3"
flat
dark
color="primary"
>
<v-btn
icon
dark
@click="afterDialog = false"
>
<v-icon>mdi-close</v-icon>
</v-btn>
<v-toolbar-title>{{item.name}} Safety: After</v-toolbar-title>
</v-toolbar>
<v-card-text v-html="item.afterSafetyDetails">
</v-card-text>
</v-card>
</v-dialog>
</v-container>
</template>

<script>
import { mapState } from 'vuex';

export default {
data: () => {
return {
beforeDialog: false,
duringDialog: false,
afterDialog: false
};
},
computed: {
...mapState({
item: (state) => state.hazardHuntStore.item,
}),
mediaUrlIsImage: function() {
const mediaUrl = this.item?.mediaUrl?.toLowerCase();
if (!mediaUrl) return false;

return mediaUrl.endsWith(".png") ||
mediaUrl.endsWith(".jpg") ||
mediaUrl.endsWith(".jpeg") ||
mediaUrl.endsWith(".webp") ||
mediaUrl.endsWith(".pjpeg") ||
mediaUrl.endsWith(".svg") ||
mediaUrl.endsWith(".pjp");
}
},
mounted: function () {
// Load the thing
this.$store.dispatch(
`hazardHuntStore/getHazardHuntAsync`,
this.$route.params.id
);
},
methods: {
goBack() {
window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/');
}
}
}
</script>

<style>

</style>
6 changes: 3 additions & 3 deletions 2wr-app/src/components/prepare/prepare-landing.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@
</v-card-text>
</v-card>

<!-- Hiding for now. Requirements in progress
<v-card

<v-card
to="prepare/hazardhunt"
color="primary"
class="my-4"
Expand All @@ -72,7 +72,7 @@
<div class="text-subtitle-1">Observe your surroundings and identify common hazards that could
mean danger in certain situations.</div>
</v-card-text>
</v-card> -->
</v-card>

</v-col>
</v-row>
Expand Down
12 changes: 11 additions & 1 deletion 2wr-app/src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import EmergencyKitEditPage from '../views/prepare/emergency-kits/emergency-kit-
import HazardHuntListing from '../views/prepare/hazards/hazard-hunt-list-view.vue';
import HazardInfoListing from '../views/prepare/hazards/hazard-info-list-view.vue';
import HazardInfo from '../views/prepare/hazards/hazard-info-view.vue';
import HazardHunt from '../views/prepare/hazards/hazard-hunt-view.vue';
import Recent from '../views/recent/recent.vue';
import Settings from '../views/settings/settings.vue';

Expand Down Expand Up @@ -65,7 +66,16 @@ const routes = [{
meta: {
requiresAuth: true
}
}, {
},
{
path: '/prepare/hazardhunt/:id',
name: 'hazardhuntdetails',
component: HazardHunt,
meta: {
requiresAuth: true
}
},
{
path: '/prepare/hazardinfo',
name: 'hazardinfolist',
component: HazardInfoListing,
Expand Down
32 changes: 31 additions & 1 deletion 2wr-app/src/store/modules/prepare/hazards/hazard-hunt-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@ import localForage from 'localforage';

const CACHE_KEY = 'HazardHunts';
const SET_LIST = 'SET_LIST';
const SET_ITEM = 'SET_ITEM';

export default {
namespaced: true,
state: {
list: []
list: [],
item: null
},
mutations: {
[SET_LIST](state, payload) {
state.list = payload;
},
[SET_ITEM](state, payload) {
state.item = payload;
}
},
actions: {
async getHazardHuntsAsync({ commit, rootState }) {
Expand All @@ -30,6 +35,31 @@ export default {
}

}
},
async getHazardHuntAsync({ commit, rootState} , id) {

try {
commit("setBusy", null, { root: true });
commit("setError", "", { root: true });
const itemCacheKey = `${CACHE_KEY}/${id}`
if (rootState.globalStore.online) {
let response = await api.get(id);
commit(SET_ITEM, response.data);
await localForage.setItem(itemCacheKey, response.data);
} else {
var data = await localForage.getItem(itemCacheKey)
if (data) {
console.log("Serving from cache");
commit(SET_ITEM, data);
} else {
console.log("Offline without data");
}
}
} catch {
commit("setError", "Could not load hazard hunt.", { root: true });
} finally {
commit("clearBusy", null, { root: true });
}
}
}
};
14 changes: 14 additions & 0 deletions 2wr-app/src/views/prepare/hazards/hazard-hunt-view.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<HazardHuntComponent></HazardHuntComponent>
</template>

<script>
import HazardHuntComponent from '@/components/prepare/hazards/hazard-hunt.vue'

export default {
name: 'HazardHunt',
components: {
HazardHuntComponent
}
}
</script>