From 6ddff597ec27e10e7caa9f3cdee39e2793c610ce Mon Sep 17 00:00:00 2001 From: Aditya Anand M C Date: Thu, 5 Sep 2019 13:26:34 +0530 Subject: [PATCH] feat: refactoring popover on bounty details --- app/assets/v2/css/base.css | 6 -- app/assets/v2/css/bounty.css | 31 -------- app/assets/v2/js/user_popover.js | 121 +++++++++++-------------------- app/dashboard/models.py | 20 +++++ app/dashboard/views.py | 54 +++++++++----- 5 files changed, 97 insertions(+), 135 deletions(-) diff --git a/app/assets/v2/css/base.css b/app/assets/v2/css/base.css index 20ca34474bf..8c2b6c4d1aa 100644 --- a/app/assets/v2/css/base.css +++ b/app/assets/v2/css/base.css @@ -1528,12 +1528,6 @@ div.busyOverlay { border-top-color: #F8F8F8; } -.popover-bounty__footer { - padding: 1.3em 1.3em 1.2em; - background-color: #F8F8F8; - border-radius: 0 0 .3rem .3rem; -} - .popover-bounty__content { padding: 1.4em 1.3em 1.3em; } diff --git a/app/assets/v2/css/bounty.css b/app/assets/v2/css/bounty.css index 13282147c89..6fa0e4e5cd4 100644 --- a/app/assets/v2/css/bounty.css +++ b/app/assets/v2/css/bounty.css @@ -490,35 +490,6 @@ a.btn { margin-bottom: 2em; } -.earned { - color: #8E2ABE; - font-size: 14px; - line-height: 13px; - font-weight: 600; -} - -.contributor-position, -.username, -.current_status, -.in-progress { - color: #0D0764; -} - -.specialty { - font-weight: 600; - font-size: 10px; - line-height: 11px; -} - -.completed-bounties { - color: #05B66A; -} - -.abandoned-bounties, -.removed-bounties { - color: #F5A623; -} - #funder_notif_info:empty { display: none; } @@ -540,7 +511,6 @@ a.btn { top: -2px; } - #bounty_details #issue_description img { max-height: 30rem; max-width: 30rem; @@ -860,7 +830,6 @@ a.btn { display: none; } - #title, #funder_notif_info { text-align: center; } diff --git a/app/assets/v2/js/user_popover.js b/app/assets/v2/js/user_popover.js index 6616e7afd71..4d8417ab287 100644 --- a/app/assets/v2/js/user_popover.js +++ b/app/assets/v2/js/user_popover.js @@ -1,62 +1,50 @@ let popoverData = []; -const renderPopOverData = json => { - let orgs = Object.keys(json.profile.organizations).map((org, index) => { +const renderPopOverData = profile => { + let contributed_to = Object.keys(profile.contributed_to).map((_organization, index) => { if (index < 3) { - return `${org}`; + return `${_organization}`; } - return `+${Object.keys(json.profile.organizations).length - 3}`; + return `+${Object.keys(profile.contributed_to).length - 3}`; }).join(' '); return `
-
- -

${json.profile.handle}

- Specialty: ${json.profile.keywords.slice(0, 3).toString()} - ${orgs.length ? 'Contributes to: ' + orgs : ''} +
+ +

${profile.handle}

+ ${contributed_to.length ? 'Contributes to: ' + contributed_to : ''}
- ~ ${Number(json.profile.total_earned).toFixed(4)} ETH earned -
-
- #${json.profile.position} -

Gitcoin Contributor

+ +
+
+

${profile.stats.position}

+

contributor

+
+
+

${profile.stats.success_rate}

+

success rate

-
-
- ${json.statistics.work_completed} -

Bounties Completed

-
-
- ${json.statistics.work_in_progress} -

Bounties In Progress

-
-
- ${json.statistics.work_abandoned} -

Bounties Abandoned

-
-
- ${json.statistics.work_removed} -

Bounties Removed

-
+
+

${profile.stats.earnings ? Number(profile.stats.earnings).toFixed(4) : 0} ETH

+

collected from ${profile.stats.completed_bounties} bounties

-
- `; }; -const openContributorPopOver = (contributor, element) => { - let contributorURL = `/api/v0.1/profile/${contributor}`; +function openContributorPopOver(contributor, element) { + const contributorURL = `/api/v0.1/profile/${contributor}`; if (popoverData.filter(index => index[contributor]).length === 0) { fetch(contributorURL, { method: 'GET' }) @@ -65,8 +53,12 @@ const openContributorPopOver = (contributor, element) => { element.popover({ placement: 'auto', trigger: 'hover', - template: - '', + template: ` + `, content: renderPopOverData(response), html: true }); @@ -80,8 +72,12 @@ const openContributorPopOver = (contributor, element) => { element.popover({ placement: 'auto', trigger: 'hover', - template: - '', + template: ` + `, content: renderPopOverData( popoverData.filter(item => item[contributor])[0][contributor] ), @@ -89,35 +85,4 @@ const openContributorPopOver = (contributor, element) => { }); $(element).popover('show'); } -}; - -const currentStatus = status => { - const activity_names = { - new_bounty: gettext('New Bounty'), - start_work: gettext('Work Started'), - stop_work: gettext('Work Stopped'), - work_submitted: gettext('Work Submitted'), - work_done: gettext('Work Done'), - worker_approved: gettext('Worker Approved'), - worker_rejected: gettext('Worker Rejected'), - worker_applied: gettext('Worker Applied'), - increased_bounty: gettext('Increased Funding'), - killed_bounty: gettext('Canceled Bounty'), - new_crowdfund: gettext('New Crowdfund Contribution'), - new_tip: gettext('New Tip'), - receive_tip: gettext('Tip Received'), - bounty_abandonment_escalation_to_mods: gettext( - 'Escalated for Abandonment of Bounty' - ), - bounty_abandonment_warning: gettext('Warned for Abandonment of Bounty'), - bounty_removed_slashed_by_staff: gettext( - 'Dinged and Removed from Bounty by Staff' - ), - bounty_removed_by_staff: gettext('Removed from Bounty by Staff'), - bounty_removed_by_funder: gettext('Removed from Bounty by Funder'), - bounty_changed: gettext('Bounty Details Changed'), - extend_expiration: gettext('Extended Bounty Expiration') - }; - - return activity_names[status] || 'Unknown activity '; -}; +} \ No newline at end of file diff --git a/app/dashboard/models.py b/app/dashboard/models.py index 29ed94f6428..afcb307c191 100644 --- a/app/dashboard/models.py +++ b/app/dashboard/models.py @@ -2364,8 +2364,28 @@ def is_staff(self): """ return self.user.is_staff if self.user else False + + @property + def completed_bounties(self): + """Returns bounties completed by user + + Returns: + number: number of bounties completed + + """ + network = self.get_network() + return self.bounties.filter( + idx_status__in=['done'], network=network).count() + + @property def success_rate(self): + """Returns success rate of user on the platform + + Returns: + number: sucess rate of user + + """ network = self.get_network() num_completed_bounties = self.bounties.filter( idx_status__in=['done'], network=network).count() diff --git a/app/dashboard/views.py b/app/dashboard/views.py index 9cdf6fa57e6..0eca5a500d6 100644 --- a/app/dashboard/views.py +++ b/app/dashboard/views.py @@ -1785,29 +1785,43 @@ def profile_details(request, handle): """ try: profile = profile_helper(handle, True) - activity = Activity.objects.filter(profile=profile).order_by('-created_on').first() - count_work_completed = Activity.objects.filter(profile=profile, activity_type='work_done').count() - count_work_in_progress = Activity.objects.filter(profile=profile, activity_type='start_work').count() - count_work_abandoned = Activity.objects.filter(profile=profile, activity_type='stop_work').count() - count_work_removed = Activity.objects.filter(profile=profile, activity_type='bounty_removed_by_funder').count() except (ProfileNotFoundException, ProfileHiddenException): raise Http404 + bounties = profile.bounties + for word in profile.keywords: + bounties = bounties.keyword(word) # TODO: Is this right + + _bounties = [] + if bounties : + for bounty in bounties: + _bounty = { + 'title': bounty.title, + 'url': bounty.get_absolute_url() + } + try: + # feedback = FeedbackEntry.objects.get(bounty=bounty.pk, receiver_profile=profile) + feedback = FeedbackEntry.objects.get() # TODO: remove after testing + if feedback: + _bounty['contibutor_rating'] = feedback.rating + except FeedbackEntry.DoesNotExist: + _bounty['contibutor_rating'] = None + _bounties.append(_bounty) + response = { - 'profile': ProfileSerializer(profile).data, - 'success_rate': profile.success_rate, - 'recent_activity': { - 'activity_metadata': activity.metadata, - 'activity_type': activity.activity_type, - 'created': activity.created - }, - 'statistics': { - 'work_completed': count_work_completed, - 'work_in_progress': count_work_in_progress, - 'work_abandoned': count_work_abandoned, - 'work_removed': count_work_removed + 'avatar': profile.avatar_url, + 'handle': profile.handle, + # 'contributed_to' : dic(profile.get_who_works_with()) # TODO: make into array + 'keywords': profile.keywords, + 'related_bounties' : _bounties, + 'stats': { + 'position': profile.get_contributor_leaderboard_index(), + 'completed_bounties': profile.completed_bounties, + 'success_rate': profile.success_rate, + 'earnings': profile.get_eth_sum() } } + return JsonResponse(response, safe=False) @@ -2003,15 +2017,15 @@ def profile(request, handle): currently_working_bounties_count = currently_working_bounties.count() if currently_working_bounties_count > 0: paginator = Paginator(currently_working_bounties, 10) - + if page > paginator.num_pages: return HttpResponse(status=204) context = {} - context['bounties'] = [bounty for bounty in paginator.get_page(page)] + context['bounties'] = [bounty for bounty in paginator.get_page(page)] return TemplateResponse(request, 'profiles/profile_bounties.html', context, status=status) - + else: all_activities = profile.get_various_activities()