Skip to content

Commit

Permalink
feat: teams challenge cta on teams page
Browse files Browse the repository at this point in the history
  • Loading branch information
eddieferrer committed Dec 18, 2023
1 parent 4e60e76 commit c7009bd
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 5 deletions.
17 changes: 17 additions & 0 deletions src/assets/icons/inline/two-hands-heart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
142 changes: 142 additions & 0 deletions src/components/Teams/TeamGoal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<template>
<div
class="tw-bg-primary tw-rounded tw-p-2 tw-drop-shadow-lg"
>
<!-- Loading template -->
<div v-if="isLoading">
<div class="tw-flex tw-flex-row">
<kv-loading-placeholder class="tw-mr-2" :style="{width: '64px', height: '64px'}" />
<kv-loading-placeholder :style="{width: 60 + (Math.random() * 40) + '%', height: '64px'}" />
</div>
<p class="tw-mt-1">
<kv-loading-placeholder :style="{width: 50 + (Math.random() * 50) + '%', height: '10px'}" />
</p>
<div class="tw-mt-1">
<kv-loading-placeholder :style="{width: '100%', height: '24px'}" />
</div>
<div class="tw-mt-1">
<kv-loading-placeholder :style="{width: '100%', height: '38px'}" />
</div>
</div>
<!-- Content template -->
<div v-else>
<div class="tw-flex tw-flex-row tw-items-center">
<img
class="tw-w-8 tw-h-8 tw-flex-none tw-rounded-sm tw-mr-2"
:src="teamImage"
>
<h3>{{ goal.name }}</h3>
</div>
<p class="tw-line-clamp-1 tw-mt-1">
{{ loanBecause }}
</p>
<div class="tw-mt-1 tw-flex tw-justify-between">
<strong>{{ daysRemaining }} days remaining</strong>
<strong>{{ loansFunded }}/{{ totalLoans }} loans funded</strong>
</div>
<div class="tw-mt-1">
<kv-progress-bar
:value="percentageFunded"
class="tw-w-full"
/>
</div>

<div class="tw-flex tw-flex-row tw-justify-between tw-mt-1 tw-items-center">
<span>{{ membersParticipating }} members participating</span>
<kv-button :to="`/team/challenge/${teamPublicId}`" variant="caution">
View
</kv-button>
</div>
</div>
</div>
</template>

<script>
import TeamInfoFromId from '@/graphql/query/teamInfoFromId.graphql';
import teamNoImage from '@/assets/images/team_s135.png';
import {
parseISO,
differenceInDays,
} from 'date-fns';
import KvProgressBar from '~/@kiva/kv-components/vue/KvProgressBar';
import KvButton from '~/@kiva/kv-components/vue/KvButton';
import KvLoadingPlaceholder from '~/@kiva/kv-components/vue/KvLoadingPlaceholder';
export default {
name: 'TeamGoal',
inject: ['apollo'],
components: {
KvButton,
KvLoadingPlaceholder,
KvProgressBar,
},
data() {
return {
isLoading: true,
loanBecause: '',
teamNoImage,
teamImageUrl: '',
teamPublicId: '',
};
},
props: {
goal: {
type: Object,
required: true,
default: () => ({}),
}
},
computed: {
challengeEndDate() {
return this.goal?.endDate ?? null;
},
// calculate days remaining between now and the challengeEndDate using the the datefns library
daysRemaining() {
// Get planned expiration time as Date
const plannedExpirationDate = parseISO(this.challengeEndDate);
const diffInDays = differenceInDays(plannedExpirationDate, new Date());
return diffInDays;
},
loansFunded() {
const loans = this.goal?.targets?.values ?? [];
// filter out loans where status is not complete
const completedLoans = loans.filter(loan => loan.status === 'COMPLETE');
return completedLoans.length ?? 0;
},
totalLoans() {
return this.goal?.targets?.totalCount ?? 0;
},
teamId() {
return this.goal?.teamId ?? null;
},
teamImage() {
return this.teamImageUrl || this.teamNoImage;
},
percentageFunded() {
return (this.loansFunded / this.totalLoans) * 100;
},
membersParticipating() {
return this.goal?.participation?.totalCount ?? 0;
},
},
methods: {
fetchTeamData() {
this.apollo.query({
query: TeamInfoFromId,
variables: {
team_id: this.teamId,
}
}).then(({ data }) => {
this.loanBecause = data.community?.team?.loanBecause ?? '';
this.teamImageUrl = data.community?.team?.image?.url ?? null;
this.teamPublicId = data.community?.team?.teamPublicId ?? '';
}).finally(() => {
this.isLoading = false;
});
},
},
mounted() {
this.fetchTeamData();
},
};
</script>
68 changes: 68 additions & 0 deletions src/components/Teams/TeamGoalsList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<template>
<div class="tw-bg-secondary tw-py-3" v-if="!isLoading && activeGoals.length > 0">
<kv-page-container>
<kv-grid
class="tw-grid-cols-12"
>
<div class="tw-col-span-12">
<div class="tw-flex tw-mb-2">
<div class="tw-flex-none tw-mr-1">
<TwoHands class="tw-w-10 tw-h-10 tw-text-primary" />
</div>
<div>
<h2>{{ activeGoals.length }} teams with active challenges!</h2>
<p>
Don’t see your team on this list? <a
href="lp/team-challenge-waitlist"
>Let us know if you’re interested!</a>
</p>
</div>
</div>

<div class="tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-2">
<team-goal
v-for="goal in activeGoals"
:key="goal.id"
:goal="goal"
/>
</div>
</div>
</kv-grid>
</kv-page-container>
</div>
</template>

<script>
import TwoHands from '@/assets/icons/inline/two-hands-heart.svg';
import TeamGoal from '@/components/Teams/TeamGoal';
import { fetchGoals } from '../../util/teamsUtil';
import KvPageContainer from '~/@kiva/kv-components/vue/KvPageContainer';
import KvGrid from '~/@kiva/kv-components/vue/KvGrid';
export default {
name: 'TeamGoalsList',
inject: ['apollo'],
components: {
KvPageContainer,
KvGrid,
TeamGoal,
TwoHands,
},
data() {
return {
activeGoals: [],
isLoading: true,
};
},
mounted() {
fetchGoals(this.apollo)
.then(response => {
this.activeGoals = response.values;
})
.finally(() => {
this.isLoading = false;
});
},
};
</script>
6 changes: 6 additions & 0 deletions src/graphql/query/teamInfoFromId.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ query teamInfoFromId($team_id: Int, $team_recruitment_id: Int, $team_ids: [Int])
id
name
membershipType
loanBecause
image{
id
url
}
teamPublicId
}
}
my {
Expand Down
30 changes: 30 additions & 0 deletions src/graphql/query/teamsGoals.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
query GetGoals {
getGoals(filters: { audienceType: TEAM, isActive: true}) {

Check warning on line 2 in src/graphql/query/teamsGoals.graphql

View workflow job for this annotation

GitHub Actions / build

Cannot query field "getGoals" on type "Query". Did you mean "general" or "getForm"?
totalCount
values {
id
description
name
participation {
totalCount
values {
lenderId
}
}
status
targets {
totalCount
values {
... on LoanTarget {
loanId
status
}
}
}
endDate
... on TeamGoal {
teamId
}
}
}
}
7 changes: 5 additions & 2 deletions src/pages/LendingTeams/LendingTeams.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<www-page>
<team-goals-list />
<kv-page-container>
<kv-grid
class="tw-grid-cols-12"
Expand Down Expand Up @@ -96,6 +97,7 @@

<script>
import WwwPage from '@/components/WwwFrame/WwwPage';
import TeamGoalsList from '@/components/Teams/TeamGoalsList';
import KvPageContainer from '~/@kiva/kv-components/vue/KvPageContainer';
import KvButton from '~/@kiva/kv-components/vue/KvButton';
import KvGrid from '~/@kiva/kv-components/vue/KvGrid';
Expand All @@ -109,8 +111,9 @@ export default {
KvPageContainer,
KvButton,
KvGrid,
TeamListing,
TeamLeaderboards
TeamGoalsList,
TeamLeaderboards,
TeamListing
},
};
</script>
10 changes: 7 additions & 3 deletions src/pages/LendingTeams/TeamLeaderboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
</template>
</h4>
<kv-tabs
class="tw-px-1"
:class="{ 'members-tabs' : isNewMembers, 'tw-pb-2' : isNewMembers && isLoading }"
class="tw-px-1 tw-pb-2 leaderboard-tabs"
:class="{ 'members-leaderboard' : isNewMembers}"
@tab-changed="handleTabChanged"
>
<template #tabNav>
Expand Down Expand Up @@ -216,7 +216,11 @@ export default {
</script>
<style scoped lang="postcss">
.members-tabs >>> div {
.leaderboard-tabs .members-leaderboard >>> div {
@apply tw-mb-0;
}
.leaderboard-tabs >>> div[role="tablist"] {
@apply tw-gap-x-1 md:tw-gap-x-2 lg:tw-gap-x-3 tw-mb-1;
}
</style>
12 changes: 12 additions & 0 deletions src/util/teamsUtil.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import teamsQuery from '@/graphql/query/teamsQuery.graphql';
import teamsGoals from '@/graphql/query/teamsGoals.graphql';
import leaderboardsQuery from '@/graphql/query/leaderboardsQuery.graphql';

export const teamCategories = [
Expand Down Expand Up @@ -116,3 +117,14 @@ export async function fetchLeaderboard(apollo, category) {
console.log('Loading leaderboards failed:', e.message);
}
}

export async function fetchGoals(apollo) {
try {
const result = await apollo.query({
query: teamsGoals,
});
return result.data?.getGoals;
} catch (e) {
console.log('Team Goals query failed:', e.message);
}
}

0 comments on commit c7009bd

Please sign in to comment.