You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
8.0 KiB
261 lines
8.0 KiB
<template>
|
|
<div v-if="visible" class="dialog-overlay">
|
|
<div class="dialog">
|
|
<h1 class="text-xl font-bold text-center mb-4 relative">
|
|
Here's one:
|
|
<div
|
|
class="text-lg text-center p-2 leading-none absolute right-0 -top-1"
|
|
@click="cancel"
|
|
>
|
|
<fa icon="xmark" class="w-[1em]"></fa>
|
|
</div>
|
|
</h1>
|
|
<span class="flex justify-between">
|
|
<span
|
|
class="rounded-l border border-slate-400 bg-slate-200 px-4 py-2 flex"
|
|
@click="prevIdea()"
|
|
>
|
|
<fa icon="chevron-left" class="m-auto" />
|
|
</span>
|
|
|
|
<div class="m-2">
|
|
<span v-if="currentCategory === CATEGORY_IDEAS">
|
|
<p class="text-center text-lg font-bold">
|
|
{{ IDEAS[currentIdeaIndex] }}
|
|
</p>
|
|
</span>
|
|
<div v-if="currentCategory === CATEGORY_CONTACTS">
|
|
<p class="text-center">
|
|
<span
|
|
v-if="currentContact == null"
|
|
class="text-orange-500 text-lg font-bold"
|
|
>
|
|
That's all your contacts.
|
|
</span>
|
|
<span v-else>
|
|
<span class="text-lg font-bold">
|
|
Did {{ currentContact.name || AppString.NO_CONTACT_NAME }}
|
|
<br />
|
|
or someone near them do anything – maybe a while ago?
|
|
</span>
|
|
<span class="flex justify-between">
|
|
<span />
|
|
<button
|
|
class="text-center bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mt-4"
|
|
@click="nextIdeaPastContacts()"
|
|
>
|
|
Skip Contacts <fa icon="forward" />
|
|
</button>
|
|
</span>
|
|
</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<span
|
|
class="rounded-r border border-slate-400 bg-slate-200 px-4 py-2 flex"
|
|
@click="nextIdea()"
|
|
>
|
|
<fa icon="chevron-right" class="m-auto" />
|
|
</span>
|
|
</span>
|
|
<button
|
|
class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mt-4"
|
|
@click="proceed"
|
|
>
|
|
That's it!
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { Vue, Component } from "vue-facing-decorator";
|
|
import { Router } from "vue-router";
|
|
|
|
import { AppString, NotificationIface } from "@/constants/app";
|
|
import { db } from "@/db/index";
|
|
import { Contact } from "@/db/tables/contacts";
|
|
import { GiverReceiverInputInfo } from "@/libs/util";
|
|
|
|
@Component
|
|
export default class GivenPrompts extends Vue {
|
|
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
|
|
|
CATEGORY_CONTACTS = 1;
|
|
CATEGORY_IDEAS = 0;
|
|
IDEAS = [
|
|
"What food did someone fix for you?",
|
|
"What did a family member do for you?",
|
|
"What compliment did someone give you?",
|
|
"Who is someone you can always rely on, and how did they demonstrate that?",
|
|
"What did you see someone give to someone else?",
|
|
"What is a way that someone helped you even though you have never met?",
|
|
"How did a musician or author or artist inspire you?",
|
|
"What inspiration did you get from someone who handled tragedy well?",
|
|
"What is something worth respect that an organization gave you?",
|
|
"Who last gave you a good laugh?",
|
|
"What do you recall someone giving you while you were young?",
|
|
"Who forgave you or overlooked a mistake?",
|
|
"What is a way an ancestor contributed to your life?",
|
|
"What kind of help did someone at work give you?",
|
|
"How did a teacher or mentor or great example help you?",
|
|
];
|
|
|
|
callbackOnFullGiftInfo?: (
|
|
contactInfo?: GiverReceiverInputInfo,
|
|
description?: string,
|
|
) => void;
|
|
currentCategory = this.CATEGORY_IDEAS; // 0 = IDEAS, 1 = CONTACTS
|
|
currentContact: Contact | undefined = undefined;
|
|
currentIdeaIndex = 0;
|
|
numContacts = 0;
|
|
shownContactDbIndices: Array<boolean> = [];
|
|
visible = false;
|
|
|
|
AppString = AppString;
|
|
|
|
async open(
|
|
callbackOnFullGiftInfo: (
|
|
contactInfo: GiverReceiverInputInfo,
|
|
description: string,
|
|
) => void,
|
|
) {
|
|
this.visible = true;
|
|
this.callbackOnFullGiftInfo = callbackOnFullGiftInfo;
|
|
|
|
await db.open();
|
|
this.numContacts = await db.contacts.count();
|
|
this.shownContactDbIndices = new Array<boolean>(this.numContacts); // all undefined to start
|
|
}
|
|
|
|
cancel() {
|
|
this.currentCategory = this.CATEGORY_IDEAS;
|
|
this.currentContact = undefined;
|
|
this.currentIdeaIndex = 0;
|
|
this.numContacts = 0;
|
|
this.shownContactDbIndices = [];
|
|
|
|
this.visible = false;
|
|
}
|
|
|
|
proceed() {
|
|
// proceed with logic but don't change values (just in case some actions are added later)
|
|
this.visible = false;
|
|
if (this.currentCategory === this.CATEGORY_IDEAS) {
|
|
(this.$router as Router).push({
|
|
name: "contact-gift",
|
|
query: {
|
|
prompt: this.IDEAS[this.currentIdeaIndex],
|
|
},
|
|
});
|
|
} else {
|
|
// must be this.CATEGORY_CONTACTS
|
|
this.callbackOnFullGiftInfo?.(
|
|
this.currentContact as GiverReceiverInputInfo,
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the next idea.
|
|
* If it is a contact prompt, loop through.
|
|
*/
|
|
async nextIdea() {
|
|
// check if the next one is an idea or a contact
|
|
if (this.currentCategory === this.CATEGORY_IDEAS) {
|
|
this.currentIdeaIndex++;
|
|
if (this.currentIdeaIndex === this.IDEAS.length) {
|
|
// must have just finished ideas so move to contacts
|
|
this.findNextUnshownContact();
|
|
}
|
|
} else {
|
|
// must be this.CATEGORY_CONTACTS
|
|
this.findNextUnshownContact();
|
|
// when that's finished, it'll reset to ideas
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the previous idea.
|
|
* If it is a contact prompt, loop through.
|
|
*/
|
|
async prevIdea() {
|
|
// check if the next one is an idea or a contact
|
|
if (this.currentCategory === this.CATEGORY_IDEAS) {
|
|
this.currentIdeaIndex--;
|
|
if (this.currentIdeaIndex < 0) {
|
|
// must have just finished ideas so move to contacts
|
|
this.findNextUnshownContact();
|
|
}
|
|
} else {
|
|
// must be this.CATEGORY_CONTACTS
|
|
this.findNextUnshownContact();
|
|
// when that's finished, it'll reset to ideas
|
|
}
|
|
}
|
|
|
|
nextIdeaPastContacts() {
|
|
this.currentContact = undefined;
|
|
this.shownContactDbIndices = new Array<boolean>(this.numContacts);
|
|
|
|
this.currentCategory = this.CATEGORY_IDEAS;
|
|
// look at the previous idea and switch to the other side of the list
|
|
this.currentIdeaIndex =
|
|
this.currentIdeaIndex >= this.IDEAS.length ? 0 : this.IDEAS.length - 1;
|
|
}
|
|
|
|
async findNextUnshownContact() {
|
|
if (this.currentCategory === this.CATEGORY_IDEAS) {
|
|
// we're not in the contact prompts, so reset index array
|
|
this.shownContactDbIndices = new Array<boolean>(this.numContacts);
|
|
}
|
|
this.currentCategory = this.CATEGORY_CONTACTS;
|
|
|
|
let someContactDbIndex = Math.floor(Math.random() * this.numContacts);
|
|
let count = 0;
|
|
// as long as the index has an entry, loop
|
|
while (
|
|
this.shownContactDbIndices[someContactDbIndex] != null &&
|
|
count++ < this.numContacts
|
|
) {
|
|
someContactDbIndex = (someContactDbIndex + 1) % this.numContacts;
|
|
}
|
|
if (count >= this.numContacts) {
|
|
// all contacts have been shown
|
|
this.nextIdeaPastContacts();
|
|
} else {
|
|
// get the contact at that offset
|
|
await db.open();
|
|
this.currentContact = await db.contacts
|
|
.offset(someContactDbIndex)
|
|
.first();
|
|
this.shownContactDbIndices[someContactDbIndex] = true;
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.dialog-overlay {
|
|
z-index: 50;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
padding: 1.5rem;
|
|
}
|
|
|
|
.dialog {
|
|
background-color: white;
|
|
padding: 1rem;
|
|
border-radius: 0.5rem;
|
|
width: 100%;
|
|
max-width: 500px;
|
|
}
|
|
</style>
|
|
|