Skip to content

Commit

Permalink
Merge branch 'main' into update-copy-certificates
Browse files Browse the repository at this point in the history
  • Loading branch information
jschill authored Jan 15, 2024
2 parents 6244c8b + 4057361 commit a01b41f
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 153 deletions.
7 changes: 6 additions & 1 deletion cosmwasm/contracts/plastic-credit-marketplace/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use cosmwasm_std::{
entry_point, DepsMut, Env, MessageInfo, Response,
entry_point, DepsMut, Env, MessageInfo, Response, Empty,
};
use fee_splitter::instantiate_fee_splitter;
use msg::InstantiateMsg;
Expand Down Expand Up @@ -28,6 +28,11 @@ pub fn instantiate(
Ok(Response::new())
}

#[entry_point]
pub fn migrate(_deps: DepsMut, _env: Env, _msg: Empty) -> Result<Response, ContractError> {
Ok(Response::default())
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
44 changes: 24 additions & 20 deletions frontend/marketplace/src/components/CertificateCard.vue
Original file line number Diff line number Diff line change
@@ -1,49 +1,53 @@
<script setup lang="ts">
import { toast } from "vue3-toastify";
import { defineEmits } from 'vue';
import { defineEmits, computed } from "vue";
import CustomImage from "@/components/CustomImage.vue";
import { convertIPFStoHTTPS } from "@/utils/utils";
import auctionCard from "@/assets/auctionCard.png";
export interface CreditCardProps {
cardData: any;
}
// Define the expected properties from the parent component
const props = defineProps<CreditCardProps>();
const certificate = computed(() => {
return props.cardData[0];
});
const image = computed(() => {
return props.cardData[1];
});
// Define the events that this component can emit
const emit = defineEmits(['viewCertificate']);
const emit = defineEmits(["viewCertificate"]);
// Function to emit the 'viewCertificate' event
const viewCertificate = () => {
if (props.cardData?.id) {
emit('viewCertificate', props.cardData.id);
if (certificate.value.id) {
emit("viewCertificate", certificate.value.id);
} else {
toast.error('Certificate ID not found');
toast.error("Certificate ID not found");
}
};
</script>
<template>
<div
class="w-full rounded-lg bg-borderGray md:grid md:grid-cols-3 md:p-2 md:bg-lightBlack my-3"
>
<img
class="h-48 w-full rounded-lg max-w-sm"
src="../assets/auctionCard.png"
<CustomImage
v-if="image?.url"
image-class="h-48 w-full rounded-lg max-w-sm"
:src="convertIPFStoHTTPS(image?.url) || auctionCard"
/>
<!-- Desktop UI-->
<div class="hidden md:grid md:col-span-2">
<div class="grid-cols-4 grid gap-3 p-5">
<div class="grid-cols-3 grid gap-3 p-5">
<div class="col-span-1">
<p class="text-title14 font-light text-textGray">CREDIT type</p>
<p class="text-title18 font-bold">PCRD</p>
</div>
<div class="col-span-1">
<!-- <p class="text-title14 font-light text-textGray">Material</p>-->
<!-- <p class="text-title18 font-bold">{{cardData?.material}}</p>-->
</div>
<div class="col-span-2 flex flex-col justify-between text-right">
<p class="text-title32 font-bold">{{ cardData?.amount }} kg</p>
<p class="text-title24 text-subTextGray mb-1">
{{ cardData?.denom }}
<p class="text-title32 font-bold">{{ certificate?.amount }} kg</p>
<p class="text-title14 text-subTextGray mb-1">
{{ certificate?.denom }}
</p>
<div>
<button class="btn certificate-button" @click="viewCertificate">
Expand All @@ -61,8 +65,8 @@ const viewCertificate = () => {
<p class="text-title14 font-bold">PCRD</p>
</div>
<div class="text-right">
<p class="text-title24 font-bold">{{ cardData?.amount }}</p>
<p class="text-title14 font-light">{{ cardData?.denom }}</p>
<p class="text-title24 font-bold">{{ certificate?.amount }}</p>
<p class="text-title14 font-light">{{ certificate?.denom }}</p>
</div>
<!-- <div>-->
<!-- <p class="text-title14 font-light">Material</p>-->
Expand Down
131 changes: 87 additions & 44 deletions frontend/marketplace/src/components/CertificateTabContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,24 @@ import CertificateCard from "@/components/CertificateCard.vue";
import { useNotifyer } from "@/utils/notifyer";
import { useQuery } from "@vue/apollo-composable";
import CustomSpinner from "@/components/CustomSpinner.vue";
import gql from "graphql-tag";
import CustomAlert from "@/components/CustomAlert.vue";
import { useAuth } from "@/stores/auth";
import { useWallet } from "@/stores/wallet";
import {
GET_CREDIT_OFFSET_CERTIFICATES,
GET_CREDIT_COLLECTIONS,
} from "@/graphql/queries";
const pageNumber = ref(1);
const itemsPerPage = ref(5);
const searchTerm = ref("");
const data = ref();
const showSpinner = ref(true);
const certificatesData = ref();
const creditCollectionsData = ref();
const showSpinner = computed(() => {
return (
certificatesData.value?.loading?.value === true ||
creditCollectionsData.value?.loading?.value === true
);
});
const { notifyer } = useNotifyer();
const auth = useAuth();
const wallet = useWallet();
Expand All @@ -23,6 +31,42 @@ const viewCertificate = (certificateId: string) => {
window.open(url, "_blank");
};
const creditOffsetCertificates = computed(() => {
return certificatesData.value?.result?.creditOffsetCertificates ?? undefined;
});
// Looks complicated, but it returns an array where it merges the
// certificate data with the media files from the credit collection
const creditOffsetCertificatesAndCreditCollections = computed(() => {
const creditOffsetCertificates =
certificatesData.value?.result?.creditOffsetCertificates?.nodes ?? [];
if (certificatesData.value) {
return creditOffsetCertificates?.map((creditOffsetCertificate: any) => {
return [
creditOffsetCertificate,
getCreditCollectionMediaFiles(creditOffsetCertificate.denom)[0],
];
});
}
return [];
});
const getCreditCollection = (id: string) => {
const nodes =
creditCollectionsData.value?.result?.creditCollections?.nodes ?? [];
return nodes.find((creditCollection: any) => creditCollection.id === id);
};
const getCreditCollectionMediaFiles = (id: string) => {
const collection = getCreditCollection(id);
if (collection) {
console.log("collection", collection);
const collectionNodes = collection.creditData?.nodes ?? [];
return collectionNodes[0]?.mediaFiles?.nodes;
}
return [];
};
const hasEmailAddressOrWalletConnectedAddress = computed(() => {
// We need to use address values instead of the booleans because they are set after the "isAuthenticated" booleans.
// The auth logic should be moved out of the NavBar
Expand All @@ -33,7 +77,22 @@ const handlePageChange = () => {
getCertificatesData();
};
const getCertificatesData = async () => {
const getCreditCollectionData = async () => {
const nodes = creditOffsetCertificates.value?.nodes;
const denoms = nodes?.map((node: any) => node.denom);
const uniqueDenoms = [...new Set(denoms)];
if (uniqueDenoms.length < 1) {
return;
}
const { result, loading, error } = useQuery(GET_CREDIT_COLLECTIONS, {
denoms: uniqueDenoms,
});
creditCollectionsData.value = { result, loading, error };
};
const getCertificatesData = () => {
let walletAddress: string | undefined;
if (auth.walletAddress.value) {
walletAddress = auth.walletAddress.value;
Expand All @@ -46,47 +105,28 @@ const getCertificatesData = async () => {
}
try {
const query = `query {
creditOffsetCertificates(
first:${itemsPerPage.value},offset:${
(pageNumber.value - 1) * itemsPerPage.value
}
filter: {
wallet: {
address: { equalTo: "${walletAddress}" }
}
${searchTerm.value && `denom: { equalTo: "${searchTerm.value}" }`}
}
) {
totalCount
nodes {
amount
denom
id
}
}
}
`;
loadQueryData(query);
const { result, loading, error, onResult } = useQuery(
GET_CREDIT_OFFSET_CERTIFICATES,
{
walletAddress,
first: itemsPerPage.value,
offset: (pageNumber.value - 1) * itemsPerPage.value,
},
);
certificatesData.value = { result, loading, error };
onResult(() => {
getCreditCollectionData();
});
} catch (error) {
notifyer.error("Error fetching your certificates, error has been logged");
throw new Error("Error fetching certificates: " + error);
}
};
const loadQueryData = (query: string) => {
showSpinner.value = true;
const { result, loading, error } = useQuery(gql`
${query}
`);
data.value = { result, loading, error };
showSpinner.value = false;
};
let stopWatch: () => void;
let stopWatcher: () => void;
onMounted(() => {
stopWatch = watch(
stopWatcher = watch(
hasEmailAddressOrWalletConnectedAddress,
() => {
if (hasEmailAddressOrWalletConnectedAddress.value) {
Expand All @@ -98,23 +138,26 @@ onMounted(() => {
});
onUnmounted(() => {
stopWatch();
if (stopWatcher) {
stopWatcher();
}
});
</script>
<template>
<!-- TODO disabling search here for now. Not sure how it should work -->
<!-- <CustomSearchBar v-model="searchTerm" placeholder="Search Certificates" @search-click="handleSearch"/> -->
<div class="my-3">
{{ showSpinner }}
<CustomSpinner :visible="showSpinner" />
<template v-if="!showSpinner">
<CustomAlert
:visible="true"
:label="`${
data?.result?.creditOffsetCertificates?.totalCount || 0
creditOffsetCertificates?.totalCount || 0
} certificates found`"
/>
<div
v-for="certificate in data?.result?.creditOffsetCertificates?.nodes"
v-for="certificate in creditOffsetCertificatesAndCreditCollections"
:key="certificate.id"
>
<CertificateCard
Expand All @@ -124,8 +167,8 @@ onUnmounted(() => {
</div>
<div class="flex justify-center md:justify-end my-10">
<CustomPagination
v-if="data?.result?.creditOffsetCertificates?.totalCount > 0"
:total="data?.result?.creditOffsetCertificates?.totalCount"
v-if="creditOffsetCertificates?.totalCount > 0"
:total="creditOffsetCertificates?.totalCount"
:item-per-page="itemsPerPage"
v-model:current-page="pageNumber"
@page-change="handlePageChange"
Expand Down
4 changes: 3 additions & 1 deletion frontend/marketplace/src/components/NavBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ const selectWalletModal = ref(false);
const userDetails = ref(user);
onMounted(() => {
connect();
if (!isAuthenticated.value) {
connect();
}
});
const openSelectWalletModal = () => {
Expand Down
65 changes: 65 additions & 0 deletions frontend/marketplace/src/graphql/queries/creditCollections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import gql from "graphql-tag";

export const GET_CREDIT_COLLECTIONS = gql`
query GetCreditCollections($denoms: [String!]!) {
creditCollections(filter: { denom: { in: $denoms } }) {
totalCount
nodes {
projectId
id
denom
creditType
activeAmount
retiredAmount
issuanceDate
retiredCreditsEvents {
nodes {
amount
id
owner
creditCollectionId
}
}
creditData {
nodes {
id
mediaFiles {
nodes {
name
url
}
}
binaryFiles {
nodes {
name
url
}
}
eventData {
nodes {
material {
nodes {
value
key
}
}
latitude
longitude
amount
magnitude
country
registrationDate
}
}
applicantDataByCreditDataId {
nodes {
name
description
}
}
}
}
}
}
}
`;
Loading

0 comments on commit a01b41f

Please sign in to comment.