forked from jsnbuchanan/crowd-funder-for-time-pwa
- Restore runMigrations functionality for database schema migrations - Remove indexedDBMigrationService.ts (was for IndexedDB to SQLite migration) - Recreate migrationService.ts and db-sql/migration.ts for schema management - Add proper TypeScript error handling with type guards in AccountViewView - Fix CreateAndSubmitClaimResult property access in QuickActionBvcBeginView - Remove LeafletMouseEvent from Vue components array (it's a type, not component) - Add null check for UserNameDialog callback to prevent undefined assignment - Implement extractErrorMessage helper function for consistent error handling - Update router to remove database-migration route The migration system now properly handles database schema evolution across app versions, while the IndexedDB to SQLite migration service has been removed as it was specific to that one-time migration.
178 lines
5.7 KiB
Vue
178 lines
5.7 KiB
Vue
<template>
|
|
<QuickNav selected="Home"></QuickNav>
|
|
<!-- CONTENT -->
|
|
<section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
|
|
<!-- Breadcrumb -->
|
|
<div id="ViewBreadcrumb" class="mb-8">
|
|
<h1 class="text-lg text-center font-light relative px-7">
|
|
<!-- Back -->
|
|
<font-awesome
|
|
icon="chevron-left"
|
|
class="fa-fw text-lg text-center px-2 py-1 absolute -left-2 -top-1"
|
|
@click="$router.back()"
|
|
/>
|
|
Offers to Your Projects
|
|
</h1>
|
|
</div>
|
|
|
|
<div v-if="newOffersToUserProjects.length === 0">
|
|
<p>Nobody has given any offers to your projects.</p>
|
|
<p class="mt-2">
|
|
Maybe there are already some projects you can help on the
|
|
<router-link to="/discover" class="text-blue-500">
|
|
Discover page <font-awesome icon="search" />
|
|
</router-link>
|
|
</p>
|
|
<p class="mt-2">
|
|
You can announce more of your own on
|
|
<router-link to="/contacts" class="text-blue-500">
|
|
Your Ideas page <font-awesome icon="hand" />
|
|
</router-link>
|
|
</p>
|
|
</div>
|
|
|
|
<InfiniteScroll @reached-bottom="loadMoreOffersToUserProjects">
|
|
<ul
|
|
data-testId="listRecentOffersToUserProjects"
|
|
class="border-t border-slate-300"
|
|
>
|
|
<li
|
|
v-for="offer in newOffersToUserProjects"
|
|
:key="offer.jwtId"
|
|
class="mt-4 relative group"
|
|
>
|
|
<div
|
|
v-if="offer.jwtId == lastAckedOfferToUserProjectsJwtId"
|
|
class="border-b border-slate-300 text-orange-400 pb-2 mb-2 font-bold text-sm"
|
|
>
|
|
You've already seen all the following
|
|
</div>
|
|
|
|
<span>{{
|
|
didInfo(offer.offeredByDid, activeDid, allMyDids, allContacts)
|
|
}}</span>
|
|
offered
|
|
<span v-if="offer.objectDescription">{{
|
|
offer.objectDescription
|
|
}}</span
|
|
>{{ offer.objectDescription && offer.amount ? ", and " : "" }}
|
|
<span v-if="offer.amount">{{
|
|
displayAmount(offer.unit, offer.amount)
|
|
}}</span>
|
|
to
|
|
<span>{{ offer.planName }}</span>
|
|
<router-link
|
|
:to="{ path: '/claim/' + encodeURIComponent(offer.jwtId) }"
|
|
class="text-blue-500"
|
|
>
|
|
<font-awesome
|
|
icon="file-lines"
|
|
class="pl-2 text-blue-500 cursor-pointer"
|
|
/>
|
|
</router-link>
|
|
</li>
|
|
</ul>
|
|
</InfiniteScroll>
|
|
</section>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { Component, Vue } from "vue-facing-decorator";
|
|
|
|
import EntityIcon from "../components/EntityIcon.vue";
|
|
import GiftedDialog from "../components/GiftedDialog.vue";
|
|
import InfiniteScroll from "../components/InfiniteScroll.vue";
|
|
import QuickNav from "../components/QuickNav.vue";
|
|
import { NotificationIface } from "../constants/app";
|
|
import * as databaseUtil from "../db/databaseUtil";
|
|
import { Contact } from "../db/tables/contacts";
|
|
import { Router } from "vue-router";
|
|
import { OfferToPlanSummaryRecord } from "../interfaces";
|
|
import {
|
|
didInfo,
|
|
displayAmount,
|
|
getNewOffersToUserProjects,
|
|
} from "../libs/endorserServer";
|
|
import { retrieveAccountDids } from "../libs/util";
|
|
import { logger } from "../utils/logger";
|
|
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
|
|
@Component({
|
|
components: { EntityIcon, GiftedDialog, InfiniteScroll, QuickNav },
|
|
})
|
|
export default class RecentOffersToUserView extends Vue {
|
|
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
|
$router!: Router;
|
|
activeDid = "";
|
|
allContacts: Array<Contact> = [];
|
|
allMyDids: string[] = [];
|
|
apiServer = "";
|
|
lastAckedOfferToUserProjectsJwtId = "";
|
|
newOffersToUserProjects: Array<OfferToPlanSummaryRecord> = [];
|
|
newOffersToUserProjectsAtEnd = false;
|
|
|
|
showOffersDetails = false;
|
|
showOffersToUserProjectsDetails = false;
|
|
didInfo = didInfo;
|
|
displayAmount = displayAmount;
|
|
|
|
async created() {
|
|
try {
|
|
const settings = await databaseUtil.retrieveSettingsForActiveAccount();
|
|
this.apiServer = settings.apiServer || "";
|
|
this.activeDid = settings.activeDid || "";
|
|
this.lastAckedOfferToUserProjectsJwtId =
|
|
settings.lastAckedOfferToUserProjectsJwtId || "";
|
|
|
|
const contactQueryResult =
|
|
await PlatformServiceFactory.getInstance().dbQuery(
|
|
"SELECT * FROM contacts",
|
|
);
|
|
this.allContacts = databaseUtil.mapQueryResultToValues(
|
|
contactQueryResult,
|
|
) as unknown as Contact[];
|
|
|
|
this.allMyDids = await retrieveAccountDids();
|
|
|
|
const offersToUserProjectsData = await getNewOffersToUserProjects(
|
|
this.axios,
|
|
this.apiServer,
|
|
this.activeDid,
|
|
undefined,
|
|
undefined,
|
|
);
|
|
this.newOffersToUserProjects = offersToUserProjectsData.data;
|
|
this.newOffersToUserProjectsAtEnd = !offersToUserProjectsData.hitLimit;
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
} catch (err: any) {
|
|
logger.error("Error retrieving settings & contacts:", err);
|
|
this.$notify(
|
|
{
|
|
group: "alert",
|
|
type: "danger",
|
|
title: "Error",
|
|
text: err.message || "There was an error retrieving your activity.",
|
|
},
|
|
5000,
|
|
);
|
|
}
|
|
}
|
|
|
|
async loadMoreOffersToUserProjects() {
|
|
if (this.newOffersToUserProjectsAtEnd) {
|
|
return;
|
|
}
|
|
const offersToUserProjectsData = await getNewOffersToUserProjects(
|
|
this.axios,
|
|
this.apiServer,
|
|
this.activeDid,
|
|
undefined,
|
|
this.newOffersToUserProjects[this.newOffersToUserProjects.length - 1]
|
|
.jwtId,
|
|
);
|
|
this.newOffersToUserProjects.push(...offersToUserProjectsData.data);
|
|
this.newOffersToUserProjectsAtEnd = !offersToUserProjectsData.hitLimit;
|
|
}
|
|
}
|
|
</script>
|