From 2bf8ed80ef32146f2ab4dc4a14acc4e66c505259 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Tue, 29 Oct 2024 20:38:10 +0530 Subject: [PATCH 01/30] feat: discord login page --- .../src/lib/external-user-auth.model.ts | 15 ++++++++ libs/shared/services/src/index.ts | 2 + .../services/src/lib/api-routes.constant.ts | 4 ++ .../lib/external-user-auth-handler.service.ts | 37 +++++++++++++++++++ .../src/lib/external-user-auth.service.ts | 18 +++++++++ 5 files changed, 76 insertions(+) create mode 100644 libs/shared/models/src/lib/external-user-auth.model.ts create mode 100644 libs/shared/services/src/lib/external-user-auth-handler.service.ts create mode 100644 libs/shared/services/src/lib/external-user-auth.service.ts diff --git a/libs/shared/models/src/lib/external-user-auth.model.ts b/libs/shared/models/src/lib/external-user-auth.model.ts new file mode 100644 index 000000000..bdc4fd829 --- /dev/null +++ b/libs/shared/models/src/lib/external-user-auth.model.ts @@ -0,0 +1,15 @@ +export interface IExternalUserAuth { + id: number; + platform: EExternalUserAuth; + token: string; + active: boolean; + data: Date; +} + +export enum EExternalUserAuth { + DISCORD = 'discord', + TWITTER = 'twitter', + INSTAGRAM = 'instagram', + FACEBOOK = 'facebook', + LINKEDIN = 'linkedin', +} diff --git a/libs/shared/services/src/index.ts b/libs/shared/services/src/index.ts index f3d175783..fbf7b50a8 100644 --- a/libs/shared/services/src/index.ts +++ b/libs/shared/services/src/index.ts @@ -22,3 +22,5 @@ export * from './lib/round.service'; export * from './lib/note.service'; export * from './lib/razorpay.service'; export * from './lib/help-dictionary.store'; +export * from './lib/external-user-auth-handler.service'; +export * from './lib/external-user-auth.service'; diff --git a/libs/shared/services/src/lib/api-routes.constant.ts b/libs/shared/services/src/lib/api-routes.constant.ts index 787c2e01c..3e29dd605 100644 --- a/libs/shared/services/src/lib/api-routes.constant.ts +++ b/libs/shared/services/src/lib/api-routes.constant.ts @@ -951,4 +951,8 @@ export const API_ROUTES = { INDEX_UPCOMING_HACKATHONS_EVENTS: 'api/v2/feed/events_hackathons/upcoming', ACTIVITY_FEED: 'api/v2/activity_feed', }, + + EXTERNAL_USER_AUTH: { + CREATE: 'api/v2/external_user_auth', //POST + }, }; diff --git a/libs/shared/services/src/lib/external-user-auth-handler.service.ts b/libs/shared/services/src/lib/external-user-auth-handler.service.ts new file mode 100644 index 000000000..53ac6b6cb --- /dev/null +++ b/libs/shared/services/src/lib/external-user-auth-handler.service.ts @@ -0,0 +1,37 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { ExternalUserAuthService } from './external-user-auth.service'; + +@Injectable({ + providedIn: 'root', +}) +export class ExternalUserAuthHandlerService { + private clientId = '1298505458629214218'; + + constructor(private activatedRoute: ActivatedRoute, private externalUserAuthService: ExternalUserAuthService) { + this.getTokenFromUrl(); + } + + loginToDiscord(): void { + const url = `https://discord.com/oauth2/authorize?client_id=${this.clientId}&response_type=token&redirect_uri=${window.location.href}&scope=identify`; + window.location.href = url; + } + + // Extract token from URL fragment after Discord login + getTokenFromUrl() { + const fragment = this.activatedRoute.snapshot.fragment; + if (fragment) { + const tokenMatch = fragment.match(/access_token=([^&]*)/); + if (tokenMatch && tokenMatch[1]) { + const token = tokenMatch[1]; + const external_user_auth = { + token: token, + platform: 'discord', + }; + this.externalUserAuthService.create(external_user_auth).subscribe((res) => { + console.log(res); + }); + } + } + } +} diff --git a/libs/shared/services/src/lib/external-user-auth.service.ts b/libs/shared/services/src/lib/external-user-auth.service.ts new file mode 100644 index 000000000..85f3418c0 --- /dev/null +++ b/libs/shared/services/src/lib/external-user-auth.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { API_ROUTES } from './api-routes.constant'; +import { BaseApiService } from './base-api.service'; +import { HttpClient } from '@angular/common/http'; +import { IExternalUserAuth } from '@commudle/shared-models'; +@Injectable({ + providedIn: 'root', +}) +export class ExternalUserAuthService { + constructor(private http: HttpClient, private baseApiService: BaseApiService) {} + + create(data): Observable { + return this.http.post(this.baseApiService.getRoute(API_ROUTES.EXTERNAL_USER_AUTH.CREATE), { + external_user_auth: data, + }); + } +} From 3a008564d6db36102b6459a741dae586493669c4 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Tue, 29 Oct 2024 21:51:41 +0530 Subject: [PATCH 02/30] feat: create quest tab in admin community pannel --- .../community-control-panel-routing.module.ts | 6 +++++ .../community-control-panel.module.ts | 3 +++ .../community-control-panel.component.html | 4 +++ .../community-quest.component.html | 1 + .../community-quest.component.scss | 0 .../community-quest.component.spec.ts | 27 +++++++++++++++++++ .../community-quest.component.ts | 17 ++++++++++++ libs/shared/models/src/index.ts | 1 + 8 files changed, 59 insertions(+) create mode 100644 apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html create mode 100644 apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss create mode 100644 apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.spec.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts b/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts index 861f5c68d..2b538f21f 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts @@ -1,3 +1,4 @@ +/* eslint-disable @nx/enforce-module-boundaries */ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { CommunityAdminNotificationsComponent } from 'apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-admin-notifications/community-admin-notifications.component'; @@ -24,6 +25,7 @@ import { AdminCommunityHackathonComponent } from './components/admin-community-h import { CommunityBankDetailsComponent } from 'apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-payments/community-bank-details/community-bank-details.component'; import { CommunityPaymentLogsComponent } from 'apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-payments/community-payment-logs/community-payment-logs.component'; import { PaymentLogEdfegComponent } from 'apps/shared-components/payment-detail/payment-log-edfeg/payment-log-edfeg.component'; +import { CommunityQuestComponent } from 'apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component'; const routes = [ { path: 'new', @@ -136,6 +138,10 @@ const routes = [ path: 'team', component: CommunityTeamComponent, }, + { + path: 'quest', + component: CommunityQuestComponent, + }, { path: 'channels', component: CommunityChannelsAndForumsComponent, diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel.module.ts b/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel.module.ts index 265e2ccc5..0c26d4a53 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel.module.ts +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel.module.ts @@ -1,3 +1,4 @@ +/* eslint-disable @nx/enforce-module-boundaries */ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @@ -58,6 +59,7 @@ import { CommunityChannelsModule } from 'apps/commudle-admin/src/app/feature-mod import { AdminCommunityHackathonComponent } from './components/admin-community-hackathon/admin-community-hackathon.component'; import { CommunityPaymentLogsComponent } from 'apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-payments/community-payment-logs/community-payment-logs.component'; import { CommunityBankDetailsComponent } from 'apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-payments/community-bank-details/community-bank-details.component'; +import { CommunityQuestComponent } from 'apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component'; @NgModule({ declarations: [ @@ -86,6 +88,7 @@ import { CommunityBankDetailsComponent } from 'apps/commudle-admin/src/app/featu AdminCommunityHackathonComponent, CommunityPaymentLogsComponent, CommunityBankDetailsComponent, + CommunityQuestComponent, ], imports: [ CommonModule, diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.html b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.html index e00b48cdd..8631cdeb5 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.html +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.html @@ -159,6 +159,10 @@

{{ community.name }}

Members + + + Quest + Forms diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html new file mode 100644 index 000000000..11ca6ff65 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html @@ -0,0 +1 @@ + diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.spec.ts b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.spec.ts new file mode 100644 index 000000000..a9d8287f5 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { CommunityQuestComponent } from './community-quest.component'; + +describe('CommunityQuestComponent', () => { + let component: CommunityQuestComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [CommunityQuestComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CommunityQuestComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts new file mode 100644 index 000000000..49d34da33 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts @@ -0,0 +1,17 @@ +import { Component, OnInit } from '@angular/core'; +import { ExternalUserAuthHandlerService } from '@commudle/shared-services'; + +@Component({ + selector: 'commudle-community-quest', + templateUrl: './community-quest.component.html', + styleUrls: ['./community-quest.component.scss'], +}) +export class CommunityQuestComponent implements OnInit { + constructor(private externalUserAuthHandlerService: ExternalUserAuthHandlerService) {} + + ngOnInit() {} + + loginToDiscord() { + this.externalUserAuthHandlerService.loginToDiscord(); + } +} diff --git a/libs/shared/models/src/index.ts b/libs/shared/models/src/index.ts index 33ae60fb9..dc07dc722 100644 --- a/libs/shared/models/src/index.ts +++ b/libs/shared/models/src/index.ts @@ -40,3 +40,4 @@ export * from './lib/help-dictionary.model'; export * from './lib/upcoming-event-hackathon.model'; export * from './lib/hackathon-user-response.model'; export * from './lib/activity-feed.model'; +export * from './lib/external-user-auth.model'; From 07098b7572ec5e221b8652dd7a723bc891c18ced Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Thu, 7 Nov 2024 12:45:16 +0530 Subject: [PATCH 03/30] feat: admin quest page --- .../src/app/app-routing.module.ts | 7 ++ .../community-control-panel-routing.module.ts | 11 ++++ .../community-quest.component.html | 7 +- .../community-quest.component.scss | 3 + .../community-quest.component.ts | 10 ++- .../public-quests/public-quests.module.ts | 8 +++ .../new-quest-form.component.html | 7 ++ .../new-quest-form.component.scss | 0 .../new-quest-form.component.spec.ts | 27 ++++++++ .../new-quest-form.component.ts | 8 +++ .../quests-control-panel.module.ts | 11 ++++ .../quests-control-panel.routing.ts | 11 ++++ .../quest-form/quest-form.component.html | 64 ++++++++++++++++++ .../quest-form/quest-form.component.scss | 25 +++++++ .../quest-form/quest-form.component.spec.ts | 27 ++++++++ .../quest-form/quest-form.component.ts | 60 +++++++++++++++++ .../shared-components.module.ts | 4 +- libs/shared/models/src/index.ts | 1 + libs/shared/models/src/lib/quest.model.ts | 13 ++++ libs/shared/services/src/index.ts | 1 + .../services/src/lib/api-routes.constant.ts | 11 ++++ libs/shared/services/src/lib/quest.service.ts | 65 +++++++++++++++++++ 22 files changed, 378 insertions(+), 3 deletions(-) create mode 100644 apps/commudle-admin/src/app/feature-modules/public-quests/public-quests.module.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.html create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.scss create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.spec.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.module.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.routing.ts create mode 100644 apps/shared-components/quest-form/quest-form.component.html create mode 100644 apps/shared-components/quest-form/quest-form.component.scss create mode 100644 apps/shared-components/quest-form/quest-form.component.spec.ts create mode 100644 apps/shared-components/quest-form/quest-form.component.ts create mode 100644 libs/shared/models/src/lib/quest.model.ts create mode 100644 libs/shared/services/src/lib/quest.service.ts diff --git a/apps/commudle-admin/src/app/app-routing.module.ts b/apps/commudle-admin/src/app/app-routing.module.ts index 8d26f8664..50c3d2485 100644 --- a/apps/commudle-admin/src/app/app-routing.module.ts +++ b/apps/commudle-admin/src/app/app-routing.module.ts @@ -264,6 +264,13 @@ const routes: Routes = [ path: 'communities/:community_id/event-dashboard', loadChildren: () => import('./feature-modules/events/events.module').then((m) => m.EventsModule), }, + { + path: 'communities/:community_id/quest-dashboard', + loadChildren: () => + import('./feature-modules/quests-control-panel/quests-control-panel.module').then( + (m) => m.QuestsControlPanelModule, + ), + }, { path: 'orgs', loadChildren: () => diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts b/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts index 2b538f21f..99209eb10 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts @@ -26,6 +26,7 @@ import { CommunityBankDetailsComponent } from 'apps/commudle-admin/src/app/featu import { CommunityPaymentLogsComponent } from 'apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-payments/community-payment-logs/community-payment-logs.component'; import { PaymentLogEdfegComponent } from 'apps/shared-components/payment-detail/payment-log-edfeg/payment-log-edfeg.component'; import { CommunityQuestComponent } from 'apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component'; +import { QuestFormComponent } from 'apps/shared-components/quest-form/quest-form.component'; const routes = [ { path: 'new', @@ -141,6 +142,16 @@ const routes = [ { path: 'quest', component: CommunityQuestComponent, + children: [ + { + path: 'new', + component: QuestFormComponent, + }, + { + path: ':quest_id/edit', + component: QuestFormComponent, + }, + ], }, { path: 'channels', diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html index 11ca6ff65..9befe69a5 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html @@ -1 +1,6 @@ - + +
+ +
diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss index e69de29bb..5b9ddfb78 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss @@ -0,0 +1,3 @@ +section { + @apply com-p-6; +} diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts index 49d34da33..3a05b58d6 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { ExternalUserAuthHandlerService } from '@commudle/shared-services'; +import { faPlus } from '@fortawesome/free-solid-svg-icons'; @Component({ selector: 'commudle-community-quest', @@ -7,11 +8,18 @@ import { ExternalUserAuthHandlerService } from '@commudle/shared-services'; styleUrls: ['./community-quest.component.scss'], }) export class CommunityQuestComponent implements OnInit { + icons = { + faPlus, + }; constructor(private externalUserAuthHandlerService: ExternalUserAuthHandlerService) {} - ngOnInit() {} + ngOnInit() { + this.getQuests(); + } loginToDiscord() { this.externalUserAuthHandlerService.loginToDiscord(); } + + getQuests() {} } diff --git a/apps/commudle-admin/src/app/feature-modules/public-quests/public-quests.module.ts b/apps/commudle-admin/src/app/feature-modules/public-quests/public-quests.module.ts new file mode 100644 index 000000000..f15a6a7ef --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/public-quests/public-quests.module.ts @@ -0,0 +1,8 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@NgModule({ + imports: [CommonModule], + declarations: [], +}) +export class PublicQuestsModule {} diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.html b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.html new file mode 100644 index 000000000..617054edf --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.html @@ -0,0 +1,7 @@ +
+
+
+ +
+
+
diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.scss b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.spec.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.spec.ts new file mode 100644 index 000000000..861cb9ddd --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { NewQuestFormComponent } from './new-quest-form.component'; + +describe('NewQuestFormComponent', () => { + let component: NewQuestFormComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [NewQuestFormComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NewQuestFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.ts new file mode 100644 index 000000000..3deb54715 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'commudle-new-quest-form', + templateUrl: './new-quest-form.component.html', + styleUrls: ['./new-quest-form.component.scss'], +}) +export class NewQuestFormComponent {} diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.module.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.module.ts new file mode 100644 index 000000000..60311190c --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { QuestsControlPanelRoutes } from './quests-control-panel.routing'; +import { SharedComponentsModule } from 'apps/shared-components/shared-components.module'; +import { NewQuestFormComponent } from 'apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component'; + +@NgModule({ + imports: [CommonModule, QuestsControlPanelRoutes, SharedComponentsModule], + declarations: [NewQuestFormComponent], +}) +export class QuestsControlPanelModule {} diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.routing.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.routing.ts new file mode 100644 index 000000000..3a7e248eb --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.routing.ts @@ -0,0 +1,11 @@ +import { Routes, RouterModule } from '@angular/router'; +import { NewQuestFormComponent } from 'apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component'; + +const routes: Routes = [ + { + path: 'new', + component: NewQuestFormComponent, + }, +]; + +export const QuestsControlPanelRoutes = RouterModule.forChild(routes); diff --git a/apps/shared-components/quest-form/quest-form.component.html b/apps/shared-components/quest-form/quest-form.component.html new file mode 100644 index 000000000..4b26a63c4 --- /dev/null +++ b/apps/shared-components/quest-form/quest-form.component.html @@ -0,0 +1,64 @@ + + New Quest + + +
+ +
+ + + + +
+ + +
+ + + + +
+ + +
+ +
+ + +
+ +
+ + +
+
+ + +
+ +
+
+   + +
+
+ +
+
+
+ + + + +
diff --git a/apps/shared-components/quest-form/quest-form.component.scss b/apps/shared-components/quest-form/quest-form.component.scss new file mode 100644 index 000000000..ed9dcf210 --- /dev/null +++ b/apps/shared-components/quest-form/quest-form.component.scss @@ -0,0 +1,25 @@ +nb-card { + nb-card-body { + form { + @apply com-flex com-flex-col com-gap-4; + .label-container { + @apply com-flex com-flex-col com-gap-0.5; + label { + @apply com-mb-2; + .required { + @apply com-text-red-500; + } + } + } + .date-container { + @apply com-flex com-gap-6 com-border-0 com-border-b com-border-t com-border-solid com-border-Bright-Gray com-py-3; + .label-container { + @apply com-w-full; + } + } + .radio-buttons { + @apply com-flex com-gap-5; + } + } + } +} diff --git a/apps/shared-components/quest-form/quest-form.component.spec.ts b/apps/shared-components/quest-form/quest-form.component.spec.ts new file mode 100644 index 000000000..63adfdbe5 --- /dev/null +++ b/apps/shared-components/quest-form/quest-form.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { QuestFormComponent } from './quest-form.component'; + +describe('QuestFormComponent', () => { + let component: QuestFormComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [QuestFormComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(QuestFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/shared-components/quest-form/quest-form.component.ts b/apps/shared-components/quest-form/quest-form.component.ts new file mode 100644 index 000000000..9337d82c6 --- /dev/null +++ b/apps/shared-components/quest-form/quest-form.component.ts @@ -0,0 +1,60 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; +import { EDbModels, IQuest, EQuestVisibility } from '@commudle/shared-models'; +import { QuestService } from '@commudle/shared-services'; + +@Component({ + selector: 'commudle-quest-form', + templateUrl: './quest-form.component.html', + styleUrls: ['./quest-form.component.scss'], +}) +export class QuestFormComponent implements OnInit { + @Input() buttonText: string = 'Save'; + parentId = ''; + questId = ''; + parentType: EDbModels; + EQuestVisibility = EQuestVisibility; + questForm: FormGroup; + quest: IQuest; + constructor(private activatedRoute: ActivatedRoute, private fb: FormBuilder, private questService: QuestService) { + this.questForm = this.fb.group({ + title: ['', Validators.required], + description: ['', Validators.required], + start_date: [''], + end_date: [''], + visibility: ['', Validators.required], + }); + } + + ngOnInit() { + this.activatedRoute.parent.paramMap.subscribe((params) => { + if (params.get('community_id')) { + this.parentId = params.get('community_id'); + this.parentType = EDbModels.KOMMUNITY; + } + if (params.get('community_group_id')) { + this.parentId = params.get('community_group_id'); + this.parentType = EDbModels.COMMUNITY_GROUP; + } + if (params.get('quest_id')) { + this.questId = params.get('community_group_id'); + this.fetchQuestDetails(); + } + }); + } + + createOrUpdateQuest() {} + fetchQuestDetails() { + this.questService.getQuest(Number(this.questId)).subscribe((quest: IQuest) => { + this.quest = quest; + this.questForm.patchValue({ + title: quest.title, + description: quest.description, + start_date: quest.start_date, + end_date: quest.end_date, + visibility: quest.visibility, + }); + }); + } +} diff --git a/apps/shared-components/shared-components.module.ts b/apps/shared-components/shared-components.module.ts index 13dc46ba7..b3f6fe6af 100644 --- a/apps/shared-components/shared-components.module.ts +++ b/apps/shared-components/shared-components.module.ts @@ -91,7 +91,7 @@ import { HelpSectionComponent } from 'apps/commudle-admin/src/app/app-shared-com import { UserDetailsCheckboxFormComponent } from './user-details-checkbox-form/user-details-checkbox-form.component'; import { UserDetailsFormComponent } from './user-details-form/user-details-form.component'; import { NewsletterCardComponent } from './newsletter-card/newsletter-card.component'; - +import { QuestFormComponent } from './quest-form/quest-form.component'; @NgModule({ declarations: [ WorkInProgressComponent, @@ -145,6 +145,7 @@ import { NewsletterCardComponent } from './newsletter-card/newsletter-card.compo UserDetailsCheckboxFormComponent, UserDetailsFormComponent, NewsletterCardComponent, + QuestFormComponent, ], imports: [ CommonModule, @@ -236,6 +237,7 @@ import { NewsletterCardComponent } from './newsletter-card/newsletter-card.compo UserDetailsCheckboxFormComponent, UserDetailsFormComponent, NewsletterCardComponent, + QuestFormComponent, ], providers: [{ provide: TINYMCE_SCRIPT_SRC, useValue: 'tinymce/tinymce.min.js' }], }) diff --git a/libs/shared/models/src/index.ts b/libs/shared/models/src/index.ts index dc07dc722..1cc528f10 100644 --- a/libs/shared/models/src/index.ts +++ b/libs/shared/models/src/index.ts @@ -41,3 +41,4 @@ export * from './lib/upcoming-event-hackathon.model'; export * from './lib/hackathon-user-response.model'; export * from './lib/activity-feed.model'; export * from './lib/external-user-auth.model'; +export * from './lib/quest.model'; diff --git a/libs/shared/models/src/lib/quest.model.ts b/libs/shared/models/src/lib/quest.model.ts new file mode 100644 index 000000000..7b6dd3b7d --- /dev/null +++ b/libs/shared/models/src/lib/quest.model.ts @@ -0,0 +1,13 @@ +export interface IQuest { + id: number; + title: string; + description: string; + start_date: Date; + end_date: Date; + visibility: EQuestVisibility; +} + +export enum EQuestVisibility { + PUBLIC = 'public', + PRIVATE = 'private', +} diff --git a/libs/shared/services/src/index.ts b/libs/shared/services/src/index.ts index fbf7b50a8..776a9722f 100644 --- a/libs/shared/services/src/index.ts +++ b/libs/shared/services/src/index.ts @@ -24,3 +24,4 @@ export * from './lib/razorpay.service'; export * from './lib/help-dictionary.store'; export * from './lib/external-user-auth-handler.service'; export * from './lib/external-user-auth.service'; +export * from './lib/quest.service'; diff --git a/libs/shared/services/src/lib/api-routes.constant.ts b/libs/shared/services/src/lib/api-routes.constant.ts index 3e29dd605..1303ef8ab 100644 --- a/libs/shared/services/src/lib/api-routes.constant.ts +++ b/libs/shared/services/src/lib/api-routes.constant.ts @@ -955,4 +955,15 @@ export const API_ROUTES = { EXTERNAL_USER_AUTH: { CREATE: 'api/v2/external_user_auth', //POST }, + + QUEST: { + CREATE: 'api/v2/quest', //POST + INDEX: 'api/v2/quest', //GET + SHOW: 'api/v2/quest/show', //GET + UPDATE: 'api/v2/quest', //PUT + PUBLIC: { + INDEX: 'api/v2/quest/public', //GET + SHOW: 'api/v2/quest/public/show', //GET + }, + }, }; diff --git a/libs/shared/services/src/lib/quest.service.ts b/libs/shared/services/src/lib/quest.service.ts new file mode 100644 index 000000000..fc0a5733b --- /dev/null +++ b/libs/shared/services/src/lib/quest.service.ts @@ -0,0 +1,65 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { API_ROUTES } from './api-routes.constant'; +import { BaseApiService } from './base-api.service'; +import { HttpClient, HttpParams } from '@angular/common/http'; +import { EDbModels, IQuest } from '@commudle/shared-models'; +@Injectable({ + providedIn: 'root', +}) +export class QuestService { + constructor(private http: HttpClient, private baseApiService: BaseApiService) {} + + create(formData: IQuest, parentType: EDbModels, parentId: number | string): Observable { + const params = new HttpParams().set('parent_id', parentId).set('parent_type', parentType); + return this.http.post( + this.baseApiService.getRoute(API_ROUTES.QUEST.CREATE), + { + quest: formData, + }, + { + params, + }, + ); + } + + update(questId: number, data: IQuest): Observable { + const params = new HttpParams().set('quest_id', questId); + return this.http.put( + this.baseApiService.getRoute(API_ROUTES.QUEST.UPDATE), + { + quest: data, + }, + { params }, + ); + } + + index(parentType: EDbModels, parentId: number | string): Observable { + const params = new HttpParams().set('parent_id', parentId).set('parent_type', parentType); + return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUEST.INDEX), { + params, + }); + } + + getQuest(questId: number): Observable { + const params = new HttpParams().set('quest_id', questId); + return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUEST.SHOW), { + params, + }); + } + + // PUBLIC API + publicIndex(parentType: EDbModels, parentId: number | string): Observable { + const params = new HttpParams().set('parent_id', parentId).set('parent_type', parentType); + return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUEST.PUBLIC.INDEX), { + params, + }); + } + + publicShow(questId: number): Observable { + const params = new HttpParams().set('quest_id', questId); + return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUEST.PUBLIC.SHOW), { + params, + }); + } +} From 8f979623520ad90782974763f44192ab5daa1a71 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Thu, 7 Nov 2024 20:46:02 +0530 Subject: [PATCH 04/30] refactor: add index table for quest list --- .../community-control-panel-routing.module.ts | 12 +------ .../community-control-panel.component.html | 4 +-- .../community-quest.component.html | 33 +++++++++++++++++++ .../community-quest.component.scss | 17 ++++++++++ .../community-quest.component.ts | 29 +++++++++++++--- .../quest-form/quest-form.component.html | 10 +++--- .../quest-form/quest-form.component.ts | 30 ++++++++++++++--- libs/shared/models/src/lib/quest.model.ts | 8 +++-- .../services/src/lib/api-routes.constant.ts | 14 ++++---- libs/shared/services/src/lib/quest.service.ts | 12 +++---- 10 files changed, 125 insertions(+), 44 deletions(-) diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts b/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts index 99209eb10..c27c33fff 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/community-control-panel-routing.module.ts @@ -140,18 +140,8 @@ const routes = [ component: CommunityTeamComponent, }, { - path: 'quest', + path: 'quests', component: CommunityQuestComponent, - children: [ - { - path: 'new', - component: QuestFormComponent, - }, - { - path: ':quest_id/edit', - component: QuestFormComponent, - }, - ], }, { path: 'channels', diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.html b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.html index 8631cdeb5..0f7488db8 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.html +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.html @@ -159,9 +159,9 @@

{{ community.name }}

Members
- + - Quest + Quests diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html index 9befe69a5..ecca05357 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html @@ -3,4 +3,37 @@ + + + + + + + + + + + + + + + + + + +
NameCreation dateDatesNo of tasksNo of participantsActions
{{ quest.name }}{{ moment(quest.created_at).format('dddd, MMM Do, YYYY') }} + Start at: {{ moment(quest.start_date).format('dddd, MMM Do, YYYY') }} +
+ End at: {{ moment(quest.end_date).format('dddd, MMM Do, YYYY') }} +
+ + + + + + +
diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss index 5b9ddfb78..89af2e2ca 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss @@ -1,3 +1,20 @@ section { @apply com-p-6; + + table { + @apply com-border-collapse com-w-full com-mt-4; + + td, + th { + @apply com-border com-border-solid com-border-Bright-Gray com-text-left com-p-2; + } + + tr:nth-child(even) { + @apply com-bg-Bright-Gray; + } + + .action-buttons { + @apply com-flex com-justify-evenly; + } + } } diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts index 3a05b58d6..549ea8065 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts @@ -1,6 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { ExternalUserAuthHandlerService } from '@commudle/shared-services'; -import { faPlus } from '@fortawesome/free-solid-svg-icons'; +import { ActivatedRoute } from '@angular/router'; +import { EDbModels, IQuest } from '@commudle/shared-models'; +import { ExternalUserAuthHandlerService, QuestService } from '@commudle/shared-services'; +import { faPlus, faArrowUpRightFromSquare } from '@fortawesome/free-solid-svg-icons'; +import moment from 'moment'; @Component({ selector: 'commudle-community-quest', @@ -8,18 +11,34 @@ import { faPlus } from '@fortawesome/free-solid-svg-icons'; styleUrls: ['./community-quest.component.scss'], }) export class CommunityQuestComponent implements OnInit { + communityId: number | string; + quests: IQuest[]; + moment = moment; icons = { faPlus, + faArrowUpRightFromSquare, }; - constructor(private externalUserAuthHandlerService: ExternalUserAuthHandlerService) {} + + constructor( + private externalUserAuthHandlerService: ExternalUserAuthHandlerService, + private questService: QuestService, + private activatedRoute: ActivatedRoute, + ) {} ngOnInit() { - this.getQuests(); + this.activatedRoute.parent.params.subscribe((params) => { + this.communityId = params.community_id; + this.getQuests(); + }); } loginToDiscord() { this.externalUserAuthHandlerService.loginToDiscord(); } - getQuests() {} + getQuests() { + this.questService.index(EDbModels.KOMMUNITY, this.communityId).subscribe((data) => { + this.quests = data; + }); + } } diff --git a/apps/shared-components/quest-form/quest-form.component.html b/apps/shared-components/quest-form/quest-form.component.html index 4b26a63c4..eff1ed8ff 100644 --- a/apps/shared-components/quest-form/quest-form.component.html +++ b/apps/shared-components/quest-form/quest-form.component.html @@ -5,12 +5,12 @@
- - + +
@@ -45,7 +45,7 @@
  - +
{}); + } + updateQuest() { + this.questService.update(Number(this.questId), this.questForm.value).subscribe((quest: IQuest) => {}); + } + fetchQuestDetails() { this.questService.getQuest(Number(this.questId)).subscribe((quest: IQuest) => { this.quest = quest; this.questForm.patchValue({ - title: quest.title, + name: quest.name, description: quest.description, start_date: quest.start_date, end_date: quest.end_date, diff --git a/libs/shared/models/src/lib/quest.model.ts b/libs/shared/models/src/lib/quest.model.ts index 7b6dd3b7d..0373ee876 100644 --- a/libs/shared/models/src/lib/quest.model.ts +++ b/libs/shared/models/src/lib/quest.model.ts @@ -1,13 +1,15 @@ export interface IQuest { id: number; - title: string; + name: string; description: string; start_date: Date; end_date: Date; visibility: EQuestVisibility; + created_at: Date; + slug: string; } export enum EQuestVisibility { - PUBLIC = 'public', - PRIVATE = 'private', + PUBLIC = 'is_public', + PRIVATE = 'is_private', } diff --git a/libs/shared/services/src/lib/api-routes.constant.ts b/libs/shared/services/src/lib/api-routes.constant.ts index 1303ef8ab..e9e08bca7 100644 --- a/libs/shared/services/src/lib/api-routes.constant.ts +++ b/libs/shared/services/src/lib/api-routes.constant.ts @@ -956,14 +956,14 @@ export const API_ROUTES = { CREATE: 'api/v2/external_user_auth', //POST }, - QUEST: { - CREATE: 'api/v2/quest', //POST - INDEX: 'api/v2/quest', //GET - SHOW: 'api/v2/quest/show', //GET - UPDATE: 'api/v2/quest', //PUT + QUESTS: { + CREATE: 'api/v2/quests', //POST + INDEX: 'api/v2/quests', //GET + SHOW: 'api/v2/quests/show', //GET + UPDATE: 'api/v2/quests', //PUT PUBLIC: { - INDEX: 'api/v2/quest/public', //GET - SHOW: 'api/v2/quest/public/show', //GET + INDEX: 'api/v2/quests/public', //GET + SHOW: 'api/v2/quests/public/show', //GET }, }, }; diff --git a/libs/shared/services/src/lib/quest.service.ts b/libs/shared/services/src/lib/quest.service.ts index fc0a5733b..1d3f1b016 100644 --- a/libs/shared/services/src/lib/quest.service.ts +++ b/libs/shared/services/src/lib/quest.service.ts @@ -13,7 +13,7 @@ export class QuestService { create(formData: IQuest, parentType: EDbModels, parentId: number | string): Observable { const params = new HttpParams().set('parent_id', parentId).set('parent_type', parentType); return this.http.post( - this.baseApiService.getRoute(API_ROUTES.QUEST.CREATE), + this.baseApiService.getRoute(API_ROUTES.QUESTS.CREATE), { quest: formData, }, @@ -26,7 +26,7 @@ export class QuestService { update(questId: number, data: IQuest): Observable { const params = new HttpParams().set('quest_id', questId); return this.http.put( - this.baseApiService.getRoute(API_ROUTES.QUEST.UPDATE), + this.baseApiService.getRoute(API_ROUTES.QUESTS.UPDATE), { quest: data, }, @@ -36,14 +36,14 @@ export class QuestService { index(parentType: EDbModels, parentId: number | string): Observable { const params = new HttpParams().set('parent_id', parentId).set('parent_type', parentType); - return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUEST.INDEX), { + return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUESTS.INDEX), { params, }); } getQuest(questId: number): Observable { const params = new HttpParams().set('quest_id', questId); - return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUEST.SHOW), { + return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUESTS.SHOW), { params, }); } @@ -51,14 +51,14 @@ export class QuestService { // PUBLIC API publicIndex(parentType: EDbModels, parentId: number | string): Observable { const params = new HttpParams().set('parent_id', parentId).set('parent_type', parentType); - return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUEST.PUBLIC.INDEX), { + return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUESTS.PUBLIC.INDEX), { params, }); } publicShow(questId: number): Observable { const params = new HttpParams().set('quest_id', questId); - return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUEST.PUBLIC.SHOW), { + return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUESTS.PUBLIC.SHOW), { params, }); } From 5b8ee7a1f11f505c203d524e7a8253efee20fdff Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Thu, 7 Nov 2024 21:13:15 +0530 Subject: [PATCH 05/30] feat: add pagination in quest list --- .../community-quest.component.html | 11 +++++++++++ .../community-quest.component.scss | 4 ++++ .../community-quest.component.ts | 9 +++++++-- libs/shared/services/src/lib/quest.service.ts | 18 ++++++++++++------ 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html index ecca05357..86d3443dd 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html @@ -36,4 +36,15 @@ + diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss index 89af2e2ca..f2e51c368 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss @@ -17,4 +17,8 @@ section { @apply com-flex com-justify-evenly; } } + + .pagination { + @apply com-mt-4; + } } diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts index 549ea8065..a391e1432 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts @@ -14,6 +14,9 @@ export class CommunityQuestComponent implements OnInit { communityId: number | string; quests: IQuest[]; moment = moment; + page = 1; + total = 0; + count = 10; icons = { faPlus, faArrowUpRightFromSquare, @@ -37,8 +40,10 @@ export class CommunityQuestComponent implements OnInit { } getQuests() { - this.questService.index(EDbModels.KOMMUNITY, this.communityId).subscribe((data) => { - this.quests = data; + this.questService.index(EDbModels.KOMMUNITY, this.communityId, this.page, this.count).subscribe((data) => { + this.quests = data.values; + this.page = data.page; + this.total = data.total; }); } } diff --git a/libs/shared/services/src/lib/quest.service.ts b/libs/shared/services/src/lib/quest.service.ts index 1d3f1b016..a9a5da746 100644 --- a/libs/shared/services/src/lib/quest.service.ts +++ b/libs/shared/services/src/lib/quest.service.ts @@ -3,7 +3,7 @@ import { Observable } from 'rxjs'; import { API_ROUTES } from './api-routes.constant'; import { BaseApiService } from './base-api.service'; import { HttpClient, HttpParams } from '@angular/common/http'; -import { EDbModels, IQuest } from '@commudle/shared-models'; +import { EDbModels, IPaginationCount, IQuest } from '@commudle/shared-models'; @Injectable({ providedIn: 'root', }) @@ -34,9 +34,15 @@ export class QuestService { ); } - index(parentType: EDbModels, parentId: number | string): Observable { - const params = new HttpParams().set('parent_id', parentId).set('parent_type', parentType); - return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUESTS.INDEX), { + index(parentType: EDbModels, parentId: number | string, page = 1, count = 10): Observable> { + let params = new HttpParams().set('parent_id', parentId).set('parent_type', parentType); + if (page) { + params = params.set('page', page); + } + if (count) { + params = params.set('count', count); + } + return this.http.get>(this.baseApiService.getRoute(API_ROUTES.QUESTS.INDEX), { params, }); } @@ -49,9 +55,9 @@ export class QuestService { } // PUBLIC API - publicIndex(parentType: EDbModels, parentId: number | string): Observable { + publicIndex(parentType: EDbModels, parentId: number | string): Observable> { const params = new HttpParams().set('parent_id', parentId).set('parent_type', parentType); - return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUESTS.PUBLIC.INDEX), { + return this.http.get>(this.baseApiService.getRoute(API_ROUTES.QUESTS.PUBLIC.INDEX), { params, }); } From fc9c6ee5b28ffb713e6c0374ad5ce7a9d014d437 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Fri, 8 Nov 2024 17:02:14 +0530 Subject: [PATCH 06/30] refactor: revamp table for quest list --- .../community-quest.component.html | 37 +++++++++++-------- libs/shared/models/src/lib/quest.model.ts | 2 + 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html index 86d3443dd..8b24321eb 100644 --- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html +++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html @@ -17,22 +17,29 @@ {{ quest.name }} {{ moment(quest.created_at).format('dddd, MMM Do, YYYY') }} - Start at: {{ moment(quest.start_date).format('dddd, MMM Do, YYYY') }} -
- End at: {{ moment(quest.end_date).format('dddd, MMM Do, YYYY') }} +
+ Start at: {{ moment(quest.start_date).format('dddd, MMM Do, YYYY') }} +
+ End at: {{ moment(quest.end_date).format('dddd, MMM Do, YYYY') }} +
+ + No Date selected yet! + - - - -
- - - - - + {{ quest.tasks_count }} + {{ quest.participants_count }} + + diff --git a/libs/shared/models/src/lib/quest.model.ts b/libs/shared/models/src/lib/quest.model.ts index 0373ee876..264a2f853 100644 --- a/libs/shared/models/src/lib/quest.model.ts +++ b/libs/shared/models/src/lib/quest.model.ts @@ -7,6 +7,8 @@ export interface IQuest { visibility: EQuestVisibility; created_at: Date; slug: string; + tasks_count: number; + participants_count: number; } export enum EQuestVisibility { From d7bf95fd0cbd9321b5d78a8a6f6527ad6b5f1ea6 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Fri, 8 Nov 2024 18:40:37 +0530 Subject: [PATCH 07/30] feat: edit, create, tasks --- .../edit-quest/edit-quest.component.html | 1 + .../edit-quest/edit-quest.component.scss | 0 .../edit-quest/edit-quest.component.spec.ts | 27 ++++++ .../edit-quest/edit-quest.component.ts | 19 +++++ .../quest-control-panel-tasks.component.html | 1 + .../quest-control-panel-tasks.component.scss | 0 ...uest-control-panel-tasks.component.spec.ts | 27 ++++++ .../quest-control-panel-tasks.component.ts | 12 +++ .../quest-control-panel.component.html | 68 +++++++++++++++ .../quest-control-panel.component.scss | 82 +++++++++++++++++++ .../quest-control-panel.component.spec.ts | 27 ++++++ .../quest-control-panel.component.ts | 58 +++++++++++++ .../quest-dashboard.component.html | 1 + .../quest-dashboard.component.scss | 0 .../quest-dashboard.component.spec.ts | 27 ++++++ .../quest-dashboard.component.ts | 12 +++ .../quests-control-panel.module.ts | 26 +++++- .../quests-control-panel.routing.ts | 26 +++++- .../resolver/quest-details.resolver.ts | 20 +++++ .../src/app/services/communities.service.ts | 2 +- .../quest-form/quest-form.component.html | 14 +++- .../quest-form/quest-form.component.ts | 70 +++++++++++----- libs/shared/services/src/lib/quest.service.ts | 2 +- 23 files changed, 493 insertions(+), 29 deletions(-) create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.html create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.scss create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.spec.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.html create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.scss create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.spec.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.html create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.scss create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.spec.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.html create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.scss create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.spec.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/quests-control-panel/resolver/quest-details.resolver.ts diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.html b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.html new file mode 100644 index 000000000..6878893fc --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.html @@ -0,0 +1 @@ + diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.scss b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.spec.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.spec.ts new file mode 100644 index 000000000..6e311425e --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { EditQuestComponent } from './edit-quest.component'; + +describe('EditQuestComponent', () => { + let component: EditQuestComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [EditQuestComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EditQuestComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.ts new file mode 100644 index 000000000..0f56a924a --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/edit-quest/edit-quest.component.ts @@ -0,0 +1,19 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { IQuest } from '@commudle/shared-models'; + +@Component({ + selector: 'commudle-edit-quest', + templateUrl: './edit-quest.component.html', + styleUrls: ['./edit-quest.component.scss'], +}) +export class EditQuestComponent implements OnInit { + quest: IQuest; + constructor(private activatedRoute: ActivatedRoute) {} + + ngOnInit() { + this.activatedRoute.parent.data.subscribe((data: { quest: IQuest }) => { + this.quest = data.quest; + }); + } +} diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.html b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.html new file mode 100644 index 000000000..42790655f --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.html @@ -0,0 +1 @@ +

quest-control-panel-tasks works!

diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.scss b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.spec.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.spec.ts new file mode 100644 index 000000000..ac69648cd --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { QuestControlPanelTasksComponent } from './quest-control-panel-tasks.component'; + +describe('QuestControlPanelTasksComponent', () => { + let component: QuestControlPanelTasksComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [QuestControlPanelTasksComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(QuestControlPanelTasksComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.ts new file mode 100644 index 000000000..e52b8db14 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.ts @@ -0,0 +1,12 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'commudle-quest-control-panel-tasks', + templateUrl: './quest-control-panel-tasks.component.html', + styleUrls: ['./quest-control-panel-tasks.component.scss'], +}) +export class QuestControlPanelTasksComponent implements OnInit { + constructor() {} + + ngOnInit() {} +} diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.html b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.html new file mode 100644 index 000000000..3dee83b0d --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.html @@ -0,0 +1,68 @@ +
+ +
+

{{ quest.name }}

+
+

Quest

+
+
+
+ +
+ +
+ +
+
diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.scss b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.scss new file mode 100644 index 000000000..f04e83ed4 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.scss @@ -0,0 +1,82 @@ +.hackathon-details { + @apply com-p-8 com-bg-white com-border-0 com-border-b com-border-solid com-border-Bright-Gray; + > div { + @apply com-flex com-gap-4 com-items-center com-mt-2; + h1 { + @apply com-text-3xl com-m-0; + } + .badge { + @apply com-py-2 com-px-3 com-rounded-[32px] com-border com-border-solid com-border-purple-700 com-bg-purple-50; + p { + @apply com-m-0 com-text-purple-700 com-text-base; + } + } + } +} + +.sidebar { + @apply com-w-80 com-sticky com-top-16 com-h-[calc(100vh-70px)]; + + a { + @apply com-text-inherit com-no-underline; + } + .action-buttons { + @apply com-py-3; + + .back-admin { + @apply com-px-4; + .icon { + @apply com-text-Cadet-Grey; + } + .heading { + @apply com-text-xs com-text-Cadet-Grey; + } + } + + .status-buttons { + @apply com-flex com-flex-col com-justify-center; + .border { + @apply com-border com-border-Bright-Gray com-border-solid com-rounded-md; + } + + section { + @apply com-flex com-justify-center com-mb-5; + } + } + .category { + @apply com-flex com-flex-col; + } + .category-heading { + @apply com-text-sm com-font-semibold com-my-2 com-px-4; + } + .divided-line { + @apply com-border com-border-solid com-border-Bright-Gray; + } + .action-button { + @apply com-px-5 com-my-1 com-flex com-gap-2 com-items-center com-cursor-pointer; + &.active { + @apply com-bg-Bright-Gray-Light com-text-tYankees-Blue; + } + .icon { + fa-icon { + @apply com-text-lg com-text-Cadet-Grey; + } + } + .action-button-name { + @apply com-text-sm com-font-light; + } + } + + .action-button:hover { + @apply com-bg-Bright-Gray-Light com-text-tYankees-Blue; + } + } +} + +a { + @apply com-flex com-gap-2 com-items-center com-py-1; +} + +.router { + @apply com-w-full com-my-2 com-mx-4; +} diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.spec.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.spec.ts new file mode 100644 index 000000000..3830dad70 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { QuestControlPanelComponent } from './quest-control-panel.component'; + +describe('QuestControlPanelComponent', () => { + let component: QuestControlPanelComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [QuestControlPanelComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(QuestControlPanelComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.ts new file mode 100644 index 000000000..90857e9a8 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel/quest-control-panel.component.ts @@ -0,0 +1,58 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { ICommunity, IQuest } from '@commudle/shared-models'; +import { QuestService } from '@commudle/shared-services'; +import { + faArrowLeft, + faArrowUpRightFromSquare, + faChartPie, + faListCheck, + faInfoCircle, + faGear, +} from '@fortawesome/free-solid-svg-icons'; +import { CommunitiesService } from 'apps/commudle-admin/src/app/services/communities.service'; +import { FooterService } from 'apps/commudle-admin/src/app/services/footer.service'; +import { ESidebarWidth } from 'apps/shared-components/sidebar/enum/sidebar.enum'; + +@Component({ + selector: 'commudle-quest-control-panel', + templateUrl: './quest-control-panel.component.html', + styleUrls: ['./quest-control-panel.component.scss'], +}) +export class QuestControlPanelComponent implements OnInit { + questSlug: string; + quest: IQuest; + communitySlug: string; + community: ICommunity; + ESidebarWidth = ESidebarWidth; + icons = { faArrowLeft, faArrowUpRightFromSquare, faChartPie, faListCheck, faInfoCircle, faGear }; + constructor( + private questService: QuestService, + private activatedRoute: ActivatedRoute, + private communityService: CommunitiesService, + private footerService: FooterService, + ) {} + + ngOnInit() { + this.footerService.changeMiniFooterStatus(false); + this.activatedRoute.params.subscribe((params) => { + this.questSlug = params['quest_id']; + this.communitySlug = params['community_id']; + this.getCommunity(); + this.getQuest(); + }); + } + + // TODO: get data from resolver + getQuest() { + this.questService.getQuest(this.questSlug).subscribe((quest) => { + this.quest = quest; + }); + } + + getCommunity() { + this.communityService.getCommunityDetails(this.communitySlug).subscribe((data) => { + this.community = data; + }); + } +} diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.html b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.html new file mode 100644 index 000000000..464f78bbf --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.html @@ -0,0 +1 @@ +

Dashboard

diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.scss b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.spec.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.spec.ts new file mode 100644 index 000000000..524f1b522 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { QuestDashboardComponent } from './quest-dashboard.component'; + +describe('QuestDashboardComponent', () => { + let component: QuestDashboardComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [QuestDashboardComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(QuestDashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.ts new file mode 100644 index 000000000..ac6909f05 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-dashboard/quest-dashboard.component.ts @@ -0,0 +1,12 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'commudle-quest-dashboard', + templateUrl: './quest-dashboard.component.html', + styleUrls: ['./quest-dashboard.component.scss'], +}) +export class QuestDashboardComponent implements OnInit { + constructor() {} + + ngOnInit() {} +} diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.module.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.module.ts index 60311190c..4ed3326a5 100644 --- a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.module.ts +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.module.ts @@ -2,10 +2,30 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { QuestsControlPanelRoutes } from './quests-control-panel.routing'; import { SharedComponentsModule } from 'apps/shared-components/shared-components.module'; -import { NewQuestFormComponent } from 'apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component'; +import { NewQuestFormComponent } from './components/new-quest-form/new-quest-form.component'; +import { QuestDashboardComponent } from './components/quest-dashboard/quest-dashboard.component'; +import { SidebarComponent } from 'apps/shared-components/sidebar/sidebar.component'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { QuestControlPanelComponent } from './components/quest-control-panel/quest-control-panel.component'; +import { QuestControlPanelTasksComponent } from './components/quest-control-panel-tasks/quest-control-panel-tasks.component'; +import { EditQuestComponent } from './components/edit-quest/edit-quest.component'; @NgModule({ - imports: [CommonModule, QuestsControlPanelRoutes, SharedComponentsModule], - declarations: [NewQuestFormComponent], + imports: [ + CommonModule, + QuestsControlPanelRoutes, + SharedComponentsModule, + FontAwesomeModule, + + // standalone + SidebarComponent, + ], + declarations: [ + NewQuestFormComponent, + QuestDashboardComponent, + QuestControlPanelTasksComponent, + QuestControlPanelComponent, + EditQuestComponent, + ], }) export class QuestsControlPanelModule {} diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.routing.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.routing.ts index 3a7e248eb..abcb1a892 100644 --- a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.routing.ts +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.routing.ts @@ -1,11 +1,35 @@ import { Routes, RouterModule } from '@angular/router'; -import { NewQuestFormComponent } from 'apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/new-quest-form/new-quest-form.component'; +import { NewQuestFormComponent } from './components/new-quest-form/new-quest-form.component'; +import { QuestDashboardComponent } from './components/quest-dashboard/quest-dashboard.component'; +import { QuestControlPanelTasksComponent } from './components/quest-control-panel-tasks/quest-control-panel-tasks.component'; +import { QuestControlPanelComponent } from './components/quest-control-panel/quest-control-panel.component'; +import { EditQuestComponent } from './components/edit-quest/edit-quest.component'; +import { QuestDetailsResolver } from './resolver/quest-details.resolver'; const routes: Routes = [ { path: 'new', component: NewQuestFormComponent, }, + { + path: ':quest_id', + component: QuestControlPanelComponent, + resolve: { quest: QuestDetailsResolver }, + children: [ + { + path: '', + component: QuestDashboardComponent, + }, + { + path: 'tasks', + component: QuestControlPanelTasksComponent, + }, + { + path: 'edit', + component: EditQuestComponent, + }, + ], + }, ]; export const QuestsControlPanelRoutes = RouterModule.forChild(routes); diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/resolver/quest-details.resolver.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/resolver/quest-details.resolver.ts new file mode 100644 index 000000000..653d1feec --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/resolver/quest-details.resolver.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@angular/core'; +import { Resolve, ActivatedRouteSnapshot } from '@angular/router'; +import { Observable } from 'rxjs'; +import { HttpClient, HttpParams } from '@angular/common/http'; +import { ApiRoutesService } from 'apps/shared-services/api-routes.service'; +import { API_ROUTES } from 'apps/shared-services/api-routes.constants'; +import { IQuest } from '@commudle/shared-models'; + +@Injectable({ + providedIn: 'root', +}) +export class QuestDetailsResolver implements Resolve { + constructor(private http: HttpClient, private apiRoutesService: ApiRoutesService) {} + + resolve(route: ActivatedRouteSnapshot): Observable { + const questId = route.parent.params.quest_id || route.params.quest_id; + const params = new HttpParams().set('quest_id', questId); + return this.http.get(this.apiRoutesService.getRoute(API_ROUTES.QUESTS.SHOW), { params }); + } +} diff --git a/apps/commudle-admin/src/app/services/communities.service.ts b/apps/commudle-admin/src/app/services/communities.service.ts index a7798ceb0..38ef49a29 100644 --- a/apps/commudle-admin/src/app/services/communities.service.ts +++ b/apps/commudle-admin/src/app/services/communities.service.ts @@ -44,7 +44,7 @@ export class CommunitiesService { } // get the details of a community - getCommunityDetails(communityId: number): Observable { + getCommunityDetails(communityId: number | string): Observable { const params = new HttpParams().set('community_id', String(communityId)); return this.http.get(this.apiRoutesService.getRoute(API_ROUTES.COMMUNITIES.DETAILS), { params }); } diff --git a/apps/shared-components/quest-form/quest-form.component.html b/apps/shared-components/quest-form/quest-form.component.html index eff1ed8ff..ed0ac43c7 100644 --- a/apps/shared-components/quest-form/quest-form.component.html +++ b/apps/shared-components/quest-form/quest-form.component.html @@ -1,6 +1,5 @@ - New Quest - + {{ quest ? 'Edit quest' : 'New quest' }} @@ -17,7 +16,7 @@
- + - diff --git a/apps/shared-components/quest-form/quest-form.component.ts b/apps/shared-components/quest-form/quest-form.component.ts index 7b2b2e304..1d9f1c794 100644 --- a/apps/shared-components/quest-form/quest-form.component.ts +++ b/apps/shared-components/quest-form/quest-form.component.ts @@ -1,6 +1,7 @@ +import { DatePipe } from '@angular/common'; import { Component, Input, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { EDbModels, IQuest, EQuestVisibility } from '@commudle/shared-models'; import { QuestService } from '@commudle/shared-services'; @@ -11,18 +12,53 @@ import { QuestService } from '@commudle/shared-services'; }) export class QuestFormComponent implements OnInit { @Input() buttonText: string = 'Save'; + @Input() quest: IQuest; parentId = ''; - questId = ''; parentType: EDbModels; EQuestVisibility = EQuestVisibility; questForm: FormGroup; - quest: IQuest; + + tinyMCE = { + min_height: 300, + menubar: false, + convert_urls: false, + placeholder: 'Write description for hackathon', + content_style: + "@import url('https://fonts.googleapis.com/css?family=Inter'); body {font-family: 'Inter'; font-size: 16px !important;}", + plugins: [ + 'emoticons', + 'advlist', + 'lists', + 'autolink', + 'link', + 'charmap', + 'preview', + 'anchor', + 'image', + 'visualblocks', + 'code', + 'charmap', + 'codesample', + 'insertdatetime', + 'table', + 'code', + 'help', + 'wordcount', + 'autoresize', + 'media', + ], + toolbar: + 'bold italic backcolor | codesample emoticons | link | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | media code | removeformat | table', + default_link_target: '_blank', + branding: false, + license_key: 'gpl', + }; constructor( private activatedRoute: ActivatedRoute, private fb: FormBuilder, private questService: QuestService, - private router: Router, + private datePipe: DatePipe, ) { this.questForm = this.fb.group({ name: ['', Validators.required], @@ -34,6 +70,9 @@ export class QuestFormComponent implements OnInit { } ngOnInit() { + if (this.quest) { + this.fetchQuestDetails(); + } this.activatedRoute.parent.paramMap.subscribe((params) => { if (params.get('community_id')) { this.parentId = params.get('community_id'); @@ -43,15 +82,11 @@ export class QuestFormComponent implements OnInit { this.parentId = params.get('community_group_id'); this.parentType = EDbModels.COMMUNITY_GROUP; } - if (params.get('quest_id')) { - this.questId = params.get('community_group_id'); - this.fetchQuestDetails(); - } }); } createOrUpdateQuest() { - if (this.questId) { + if (this.quest) { this.updateQuest(); } else { this.createQuest(); @@ -62,19 +97,16 @@ export class QuestFormComponent implements OnInit { this.questService.create(this.questForm.value, this.parentType, this.parentId).subscribe((quest: IQuest) => {}); } updateQuest() { - this.questService.update(Number(this.questId), this.questForm.value).subscribe((quest: IQuest) => {}); + this.questService.update(this.quest.id, this.questForm.value).subscribe((quest: IQuest) => {}); } fetchQuestDetails() { - this.questService.getQuest(Number(this.questId)).subscribe((quest: IQuest) => { - this.quest = quest; - this.questForm.patchValue({ - name: quest.name, - description: quest.description, - start_date: quest.start_date, - end_date: quest.end_date, - visibility: quest.visibility, - }); + this.questForm.patchValue({ + name: this.quest.name, + description: this.quest.description, + start_date: this.datePipe.transform(this.quest.start_date, 'yyyy-MM-ddTHH:mm:ss'), + end_date: this.datePipe.transform(this.quest.end_date, 'yyyy-MM-ddTHH:mm:ss'), + visibility: this.quest.visibility, }); } } diff --git a/libs/shared/services/src/lib/quest.service.ts b/libs/shared/services/src/lib/quest.service.ts index a9a5da746..e7f64a5ad 100644 --- a/libs/shared/services/src/lib/quest.service.ts +++ b/libs/shared/services/src/lib/quest.service.ts @@ -47,7 +47,7 @@ export class QuestService { }); } - getQuest(questId: number): Observable { + getQuest(questId: number | string): Observable { const params = new HttpParams().set('quest_id', questId); return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUESTS.SHOW), { params, From 6063bd3f33cdc9a81cc09abf19b70a90fa3a1dc7 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Sat, 9 Nov 2024 12:56:34 +0530 Subject: [PATCH 08/30] fix: update quest details --- .../quest-form/quest-form.component.html | 2 +- .../quest-form/quest-form.component.ts | 30 +++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/apps/shared-components/quest-form/quest-form.component.html b/apps/shared-components/quest-form/quest-form.component.html index ed0ac43c7..0d29bc597 100644 --- a/apps/shared-components/quest-form/quest-form.component.html +++ b/apps/shared-components/quest-form/quest-form.component.html @@ -59,7 +59,7 @@
diff --git a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.scss b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.scss index 4806ffa37..ce0b6a333 100644 --- a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.scss +++ b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.scss @@ -17,3 +17,7 @@ @apply com-text-gray-500; } } + +.task-cards { + @apply com-grid com-grid-cols-2; +} diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.html b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.html index 8b7b465db..4574db864 100644 --- a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.html +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.html @@ -36,18 +36,9 @@
- - -
- -

{{ task.name }}

-
-

{{ task.description }}

-
- {{ task.reward_points }} Reward Points -
-
-
+
+ +
diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.scss b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.scss index 46684ca5f..97231b76f 100644 --- a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.scss +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.scss @@ -31,21 +31,8 @@ .tasks { @apply com-grid com-grid-cols-1 md:com-grid-cols-3; - .task { - .title-container { - @apply com-flex com-gap-2 com-items-center; - img { - @apply com-h-6; - } - .title { - @apply com-text-base com-font-medium com-my-0; - } - } - .rewards { - @apply com-w-full com-border com-border-solid com-border-Bright-Gray com-rounded-lg com-bg-gray-50 com-text-center com-text-fuchsia-600 com-py-1; - } - } } + .task-form { @apply com-w-full md:com-w-[40dvw] com-max-h-[90dvh]; nb-card-header, diff --git a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.ts b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.ts index f63176f5b..88b44f81c 100644 --- a/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.ts +++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.ts @@ -62,10 +62,12 @@ export class QuestControlPanelTasksComponent implements OnInit { name: task.name, description: task.description, url: task.url, - rewards_points: task.reward_points, + reward_points: task.reward_points, other_rewards: task.other_rewards, quest_task_type_id: task.quest_task_type.id, }); + } else { + this.resetForm(); } this.dialogService.open(dialog, { context: { @@ -76,6 +78,17 @@ export class QuestControlPanelTasksComponent implements OnInit { }); } + resetForm() { + this.taskForm.patchValue({ + name: '', + description: '', + url: '', + reward_points: 0, + other_rewards: '', + quest_task_type_id: 0, + }); + } + createTask() { this.taskService.createTask(this.quest.id, this.taskForm.value).subscribe((res: ITask) => { this.tasks.unshift(res); diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.html b/apps/shared-components/quest-task-card/quest-task-card.component.html new file mode 100644 index 000000000..bebd5e9f4 --- /dev/null +++ b/apps/shared-components/quest-task-card/quest-task-card.component.html @@ -0,0 +1,31 @@ + + +
+ +

{{ task.name }}

+
+

{{ task.description }}

+
+ {{ task.reward_points }} Reward Points +
+
+
+ + + + +
Discord
+ +
+ +
Are you sure you want to delete this page?
+ This action can not be undone +
+ + + + +
+
diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.scss b/apps/shared-components/quest-task-card/quest-task-card.component.scss new file mode 100644 index 000000000..97cb1952c --- /dev/null +++ b/apps/shared-components/quest-task-card/quest-task-card.component.scss @@ -0,0 +1,22 @@ +.task { + @apply com-cursor-pointer; + .title-container { + @apply com-flex com-gap-2 com-items-center; + img { + @apply com-h-6; + } + .title { + @apply com-text-base com-font-medium com-my-0; + } + } + .description { + @apply com-h-10 com-line-clamp-2; + } + .rewards { + @apply com-w-full com-border com-border-solid com-border-Bright-Gray com-rounded-lg com-bg-gray-50 com-text-center com-text-fuchsia-600 com-py-1; + } + + &.admin-properties { + @apply com-cursor-text com-pointer-events-none; + } +} diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.spec.ts b/apps/shared-components/quest-task-card/quest-task-card.component.spec.ts new file mode 100644 index 000000000..f7b2449ac --- /dev/null +++ b/apps/shared-components/quest-task-card/quest-task-card.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { QuestTaskCardComponent } from './quest-task-card.component'; + +describe('QuestTaskCardComponent', () => { + let component: QuestTaskCardComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [QuestTaskCardComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(QuestTaskCardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.ts b/apps/shared-components/quest-task-card/quest-task-card.component.ts new file mode 100644 index 000000000..beab18565 --- /dev/null +++ b/apps/shared-components/quest-task-card/quest-task-card.component.ts @@ -0,0 +1,24 @@ +import { Component, Input, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { ITask } from '@commudle/shared-models'; +import { NbDialogService } from '@commudle/theme'; + +@Component({ + selector: 'commudle-quest-task-card', + templateUrl: './quest-task-card.component.html', + styleUrls: ['./quest-task-card.component.scss'], +}) +export class QuestTaskCardComponent implements OnInit { + @Input() task: ITask; + @Input() adminPage: boolean = false; + @ViewChild('discordDialog') discordDialogBox: TemplateRef; + + constructor(private dialogBoxService: NbDialogService) {} + + ngOnInit() {} + + openTaskPopup() { + if (!this.adminPage) { + this.dialogBoxService.open(this.discordDialogBox, { context: this.task }); + } + } +} diff --git a/apps/shared-components/shared-components.module.ts b/apps/shared-components/shared-components.module.ts index b3f6fe6af..17f7ffd09 100644 --- a/apps/shared-components/shared-components.module.ts +++ b/apps/shared-components/shared-components.module.ts @@ -28,6 +28,7 @@ import { NbToggleModule, NbTooltipModule, NbWindowModule, + NbDialogModule, } from '@commudle/theme'; import { PickerModule } from '@ctrl/ngx-emoji-mart'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; @@ -92,6 +93,7 @@ import { UserDetailsCheckboxFormComponent } from './user-details-checkbox-form/u import { UserDetailsFormComponent } from './user-details-form/user-details-form.component'; import { NewsletterCardComponent } from './newsletter-card/newsletter-card.component'; import { QuestFormComponent } from './quest-form/quest-form.component'; +import { QuestTaskCardComponent } from 'apps/shared-components/quest-task-card/quest-task-card.component'; @NgModule({ declarations: [ WorkInProgressComponent, @@ -146,6 +148,7 @@ import { QuestFormComponent } from './quest-form/quest-form.component'; UserDetailsFormComponent, NewsletterCardComponent, QuestFormComponent, + QuestTaskCardComponent, ], imports: [ CommonModule, @@ -189,6 +192,7 @@ import { QuestFormComponent } from './quest-form/quest-form.component'; NbToggleModule, NbContextMenuModule, NbSpinnerModule, + NbDialogModule, //cdk DragDropModule, @@ -238,6 +242,7 @@ import { QuestFormComponent } from './quest-form/quest-form.component'; UserDetailsFormComponent, NewsletterCardComponent, QuestFormComponent, + QuestTaskCardComponent, ], providers: [{ provide: TINYMCE_SCRIPT_SRC, useValue: 'tinymce/tinymce.min.js' }], }) From 95aa4512a63f2ad746b3f46ff96c78f64e110370 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Thu, 21 Nov 2024 22:52:12 +0530 Subject: [PATCH 15/30] feat: external user token index --- .../quest-task-card.component.html | 20 +++++++++------ .../quest-task-card.component.scss | 18 +++++++++++-- .../quest-task-card.component.ts | 25 +++++++++++++++++-- .../src/lib/external-user-auth.model.ts | 1 + .../services/src/lib/api-routes.constant.ts | 1 + .../lib/external-user-auth-handler.service.ts | 16 ++++++------ .../src/lib/external-user-auth.service.ts | 9 ++++++- 7 files changed, 69 insertions(+), 21 deletions(-) diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.html b/apps/shared-components/quest-task-card/quest-task-card.component.html index bebd5e9f4..3a087d7fb 100644 --- a/apps/shared-components/quest-task-card/quest-task-card.component.html +++ b/apps/shared-components/quest-task-card/quest-task-card.component.html @@ -12,7 +12,7 @@ - +
Discord
-
Are you sure you want to delete this page?
- This action can not be undone +
+ +
+
- - - -
diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.scss b/apps/shared-components/quest-task-card/quest-task-card.component.scss index 97cb1952c..b55172773 100644 --- a/apps/shared-components/quest-task-card/quest-task-card.component.scss +++ b/apps/shared-components/quest-task-card/quest-task-card.component.scss @@ -1,5 +1,5 @@ .task { - @apply com-cursor-pointer; + @apply com-cursor-pointer hover:com-shadow; .title-container { @apply com-flex com-gap-2 com-items-center; img { @@ -17,6 +17,20 @@ } &.admin-properties { - @apply com-cursor-text com-pointer-events-none; + @apply com-cursor-text com-pointer-events-none hover:com-shadow-none; + } +} + +.discord-dialog { + nb-card-header, + nb-card-footer { + @apply com-flex com-justify-between com-items-center; + } + + .select { + @apply com-flex com-items-center com-gap-1 com-h-8 com-p-1 com-text-sm com-rounded-[4px] com-cursor-pointer com-bg-[#F6F9FC] hover:com-bg-[#eef2f7]/50 com-border com-border-solid com-border-[#E4E9F2] com-w-full; + select { + @apply com-bg-[#F6F9FC] hover:com-bg-[#eef2f7]/50 com-cursor-pointer com-border-0 com-w-full; + } } } diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.ts b/apps/shared-components/quest-task-card/quest-task-card.component.ts index beab18565..f892d2393 100644 --- a/apps/shared-components/quest-task-card/quest-task-card.component.ts +++ b/apps/shared-components/quest-task-card/quest-task-card.component.ts @@ -1,5 +1,6 @@ import { Component, Input, OnInit, TemplateRef, ViewChild } from '@angular/core'; -import { ITask } from '@commudle/shared-models'; +import { IExternalUserAuth, ITask } from '@commudle/shared-models'; +import { ExternalUserAuthHandlerService, ExternalUserAuthService } from '@commudle/shared-services'; import { NbDialogService } from '@commudle/theme'; @Component({ @@ -10,15 +11,35 @@ import { NbDialogService } from '@commudle/theme'; export class QuestTaskCardComponent implements OnInit { @Input() task: ITask; @Input() adminPage: boolean = false; + userAuthTokens: IExternalUserAuth[]; @ViewChild('discordDialog') discordDialogBox: TemplateRef; - constructor(private dialogBoxService: NbDialogService) {} + constructor( + private dialogBoxService: NbDialogService, + private externalUserAuthHandlerService: ExternalUserAuthHandlerService, + private externalUserAuthService: ExternalUserAuthService, + ) {} ngOnInit() {} openTaskPopup() { if (!this.adminPage) { + this.getExternalUsers('discord'); this.dialogBoxService.open(this.discordDialogBox, { context: this.task }); } } + + getExternalUsers(platformName) { + this.externalUserAuthService.userAuthTokenIndex(platformName).subscribe((res) => { + this.userAuthTokens = res; + }); + } + + loginAccount() { + switch (this.task.quest_task_type.platform_name) { + case 'Discord': + this.externalUserAuthHandlerService.loginToDiscord(); + return; + } + } } diff --git a/libs/shared/models/src/lib/external-user-auth.model.ts b/libs/shared/models/src/lib/external-user-auth.model.ts index bdc4fd829..1624ca3c5 100644 --- a/libs/shared/models/src/lib/external-user-auth.model.ts +++ b/libs/shared/models/src/lib/external-user-auth.model.ts @@ -4,6 +4,7 @@ export interface IExternalUserAuth { token: string; active: boolean; data: Date; + username: string; } export enum EExternalUserAuth { diff --git a/libs/shared/services/src/lib/api-routes.constant.ts b/libs/shared/services/src/lib/api-routes.constant.ts index 43b71624e..05aba34b2 100644 --- a/libs/shared/services/src/lib/api-routes.constant.ts +++ b/libs/shared/services/src/lib/api-routes.constant.ts @@ -954,6 +954,7 @@ export const API_ROUTES = { EXTERNAL_USER_AUTH: { CREATE: 'api/v2/external_user_auth', //POST + INDEX: 'api/v2/external_user_auth', //GET }, QUESTS: { diff --git a/libs/shared/services/src/lib/external-user-auth-handler.service.ts b/libs/shared/services/src/lib/external-user-auth-handler.service.ts index 53ac6b6cb..bb16847aa 100644 --- a/libs/shared/services/src/lib/external-user-auth-handler.service.ts +++ b/libs/shared/services/src/lib/external-user-auth-handler.service.ts @@ -13,25 +13,23 @@ export class ExternalUserAuthHandlerService { } loginToDiscord(): void { - const url = `https://discord.com/oauth2/authorize?client_id=${this.clientId}&response_type=token&redirect_uri=${window.location.href}&scope=identify`; + const url = `https://discord.com/oauth2/authorize?client_id=${this.clientId}&response_type=code&redirect_uri=${window.location.href}&scope=identify`; window.location.href = url; } - // Extract token from URL fragment after Discord login + // Extract token from URL after Discord login getTokenFromUrl() { - const fragment = this.activatedRoute.snapshot.fragment; - if (fragment) { - const tokenMatch = fragment.match(/access_token=([^&]*)/); - if (tokenMatch && tokenMatch[1]) { - const token = tokenMatch[1]; + this.activatedRoute.queryParamMap.subscribe((params) => { + const code = params.get('code'); // Retrieve the 'code' parameter + if (code) { const external_user_auth = { - token: token, + token: code, platform: 'discord', }; this.externalUserAuthService.create(external_user_auth).subscribe((res) => { console.log(res); }); } - } + }); } } diff --git a/libs/shared/services/src/lib/external-user-auth.service.ts b/libs/shared/services/src/lib/external-user-auth.service.ts index 85f3418c0..6abae51ca 100644 --- a/libs/shared/services/src/lib/external-user-auth.service.ts +++ b/libs/shared/services/src/lib/external-user-auth.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { API_ROUTES } from './api-routes.constant'; import { BaseApiService } from './base-api.service'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { IExternalUserAuth } from '@commudle/shared-models'; @Injectable({ providedIn: 'root', @@ -15,4 +15,11 @@ export class ExternalUserAuthService { external_user_auth: data, }); } + + userAuthTokenIndex(platformName: string): Observable { + const params = new HttpParams().set('platform_name', platformName); + return this.http.get(this.baseApiService.getRoute(API_ROUTES.EXTERNAL_USER_AUTH.CREATE), { + params, + }); + } } From 1d1af74e2b72e4b73d665876db38213d7d397e00 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Mon, 25 Nov 2024 16:20:44 +0530 Subject: [PATCH 16/30] refactor: redirect path for quest --- .../services/src/lib/external-user-auth-handler.service.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libs/shared/services/src/lib/external-user-auth-handler.service.ts b/libs/shared/services/src/lib/external-user-auth-handler.service.ts index bb16847aa..d2a8c672e 100644 --- a/libs/shared/services/src/lib/external-user-auth-handler.service.ts +++ b/libs/shared/services/src/lib/external-user-auth-handler.service.ts @@ -13,7 +13,11 @@ export class ExternalUserAuthHandlerService { } loginToDiscord(): void { - const url = `https://discord.com/oauth2/authorize?client_id=${this.clientId}&response_type=code&redirect_uri=${window.location.href}&scope=identify`; + const state = { + redirectTo: window.location.href, + }; + const encodedState = encodeURIComponent(JSON.stringify(state)); + const url = `https://discord.com/oauth2/authorize?client_id=${this.clientId}&response_type=code&redirect_uri=${window.location.href}&scope=identify+email+guilds+guilds.members.read&state=${encodedState}`; window.location.href = url; } From 7500195c4ec872088849fdbd6ba42b3ecd78404b Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Tue, 26 Nov 2024 11:30:45 +0530 Subject: [PATCH 17/30] feat: redirect to discord page --- .../src/app/app-routing.module.ts | 4 ++ .../public-quest-homepage.component.html | 4 ++ .../public-quest-homepage.component.ts | 37 +++++++++++++++++-- .../components/discord/discord.component.html | 8 ++++ .../components/discord/discord.component.scss | 9 +++++ .../discord/discord.component.spec.ts | 27 ++++++++++++++ .../components/discord/discord.component.ts | 24 ++++++++++++ .../user-oauth/user-oauth.module.ts | 11 ++++++ .../user-oauth/user-oauth.routing.ts | 11 ++++++ .../src/assets/static-assets.ts | 3 ++ .../quest-task-card.component.html | 11 +++++- .../quest-task-card.component.ts | 12 +++--- .../lib/external-user-auth-handler.service.ts | 13 ++++--- .../src/lib/external-user-auth.service.ts | 7 ++++ 14 files changed, 165 insertions(+), 16 deletions(-) create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.html create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.scss create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.spec.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.module.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.routing.ts diff --git a/apps/commudle-admin/src/app/app-routing.module.ts b/apps/commudle-admin/src/app/app-routing.module.ts index ab2e24a50..b5c287e10 100644 --- a/apps/commudle-admin/src/app/app-routing.module.ts +++ b/apps/commudle-admin/src/app/app-routing.module.ts @@ -132,6 +132,10 @@ const routes: Routes = [ loadChildren: () => import('./feature-modules/public-community/public-community.module').then((m) => m.PublicCommunityModule), }, + { + path: 'auth/users', + loadChildren: () => import('./feature-modules/user-oauth/user-oauth.module').then((m) => m.UserOauthModule), + }, { path: 'communities/:community_id/events/:event_id', loadChildren: () => diff --git a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.html b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.html index e874a7a38..ecf525e79 100644 --- a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.html +++ b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.html @@ -35,3 +35,7 @@

{{ quest.name }}

+ + + + diff --git a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts index 15205efaf..26e9a5f3d 100644 --- a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts +++ b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts @@ -1,8 +1,10 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { IQuest, ITask } from '@commudle/shared-models'; import { TaskService } from '@commudle/shared-services'; +import { NbDialogService } from '@commudle/theme'; import { faArrowRight } from '@fortawesome/free-solid-svg-icons'; +import { QuestTaskCardComponent } from 'apps/shared-components/quest-task-card/quest-task-card.component'; import moment from 'moment'; @Component({ @@ -17,8 +19,14 @@ export class PublicQuestHomepageComponent implements OnInit { icons = { faArrowRight, }; + @ViewChild(QuestTaskCardComponent) questTaskCardComponent: QuestTaskCardComponent; + @ViewChild('loadingScreen') LoadingDialogBox: TemplateRef; - constructor(private activatedRoute: ActivatedRoute, private taskService: TaskService) {} + constructor( + private activatedRoute: ActivatedRoute, + private taskService: TaskService, + private dialogService: NbDialogService, + ) {} ngOnInit() { this.activatedRoute.data.subscribe((data) => { @@ -28,8 +36,29 @@ export class PublicQuestHomepageComponent implements OnInit { } getTask() { - this.taskService.pIndex(this.quest.id).subscribe((task) => { - this.tasks = task; + this.taskService.pIndex(this.quest.id).subscribe((data) => { + this.tasks = data; + this.processTaskFromQueryParams(); + }); + } + + processTaskFromQueryParams() { + this.activatedRoute.queryParamMap.subscribe((params) => { + const taskId = Number(params.get('task_id')); + if (taskId) { + const task = this.tasks.find((task) => task.id === taskId); + if (task) { + const dialogRef = this.dialogService.open(this.LoadingDialogBox, { + closeOnBackdropClick: false, + closeOnEsc: false, + hasScroll: true, + }); + setTimeout(() => { + dialogRef.close(); + this.questTaskCardComponent.openTaskPopup(task); + }, 2000); + } + } }); } } diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.html b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.html new file mode 100644 index 000000000..1767f5c33 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.html @@ -0,0 +1,8 @@ +
+ + Discord Logo + +
diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.scss b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.scss new file mode 100644 index 000000000..9ebeb1b17 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.scss @@ -0,0 +1,9 @@ +section { + @apply com-flex com-justify-center com-flex-col com-h-[80dvh] com-gap-14; + img { + @apply com-h-40; + } + div { + @apply com-text-center; + } +} diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.spec.ts b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.spec.ts new file mode 100644 index 000000000..590fdc8f8 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { DiscordComponent } from './discord.component'; + +describe('DiscordComponent', () => { + let component: DiscordComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [DiscordComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DiscordComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.ts b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.ts new file mode 100644 index 000000000..b766967a1 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.ts @@ -0,0 +1,24 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { staticAssets } from 'apps/commudle-admin/src/assets/static-assets'; + +@Component({ + selector: 'commudle-discord', + templateUrl: './discord.component.html', + styleUrls: ['./discord.component.scss'], +}) +export class DiscordComponent implements OnInit { + redirectTo: string; + staticAssets = staticAssets; + constructor(private activatedRoute: ActivatedRoute) {} + + ngOnInit() { + this.activatedRoute.queryParamMap.subscribe((params) => { + const encodedState = params.get('state'); + const state = JSON.parse(decodeURIComponent(encodedState)); + const baseUrl = state.redirectTo; + this.redirectTo = `${baseUrl}?task_id=${state.task_id}`; + window.location.href = this.redirectTo; + }); + } +} diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.module.ts b/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.module.ts new file mode 100644 index 000000000..0e115066d --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { UserOauthRoutes } from './user-oauth.routing'; +import { DiscordComponent } from './components/discord/discord.component'; +import { SharedComponentsModule } from '@commudle/shared-components'; + +@NgModule({ + imports: [CommonModule, UserOauthRoutes, SharedComponentsModule], + declarations: [DiscordComponent], +}) +export class UserOauthModule {} diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.routing.ts b/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.routing.ts new file mode 100644 index 000000000..df9fe67ce --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.routing.ts @@ -0,0 +1,11 @@ +import { Routes, RouterModule } from '@angular/router'; +import { DiscordComponent } from './components/discord/discord.component'; + +const routes: Routes = [ + { + path: 'discord/callback', + component: DiscordComponent, + }, +]; + +export const UserOauthRoutes = RouterModule.forChild(routes); diff --git a/apps/commudle-admin/src/assets/static-assets.ts b/apps/commudle-admin/src/assets/static-assets.ts index 81ae1ef5d..228e9e72c 100644 --- a/apps/commudle-admin/src/assets/static-assets.ts +++ b/apps/commudle-admin/src/assets/static-assets.ts @@ -178,4 +178,7 @@ export const staticAssets = { //id: 158 call_for_speaker_empty_state: 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBL0N1QWc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--3d0e4b9c60c0f63c0272e41a6ea79608454cc379/CFP-Empty%20State.png', + + discord_logo: + 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBeTAvQXc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--d01625bde4293ef3b7d8de196a73f603114eed05/Discord.svg', }; diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.html b/apps/shared-components/quest-task-card/quest-task-card.component.html index 3a087d7fb..852dadd7f 100644 --- a/apps/shared-components/quest-task-card/quest-task-card.component.html +++ b/apps/shared-components/quest-task-card/quest-task-card.component.html @@ -1,4 +1,4 @@ - +
@@ -27,6 +27,15 @@
+ + +
+ Follow +
+ + -
- +
+
- -
- Follow +
+
+ +
+
- - +
+
+ Follow +
+ +
diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.ts b/apps/shared-components/quest-task-card/quest-task-card.component.ts index 125a05316..ec15234bb 100644 --- a/apps/shared-components/quest-task-card/quest-task-card.component.ts +++ b/apps/shared-components/quest-task-card/quest-task-card.component.ts @@ -1,6 +1,11 @@ import { Component, Input, OnInit, TemplateRef, ViewChild } from '@angular/core'; -import { IExternalUserAuth, ITask } from '@commudle/shared-models'; -import { ExternalUserAuthHandlerService, ExternalUserAuthService } from '@commudle/shared-services'; +import { EExternalUserAuth, IExternalUserAuth, ITask } from '@commudle/shared-models'; +import { + ExternalUserAuthHandlerService, + ExternalUserAuthService, + TaskService, + ToastrService, +} from '@commudle/shared-services'; import { NbDialogService } from '@commudle/theme'; @Component({ @@ -12,34 +17,60 @@ export class QuestTaskCardComponent implements OnInit { @Input() task: ITask; @Input() adminPage: boolean = false; userAuthTokens: IExternalUserAuth[]; + selectedExternalUserAuthId: number; + stepOne = true; + stepTwo = false; + stepThree = false; @ViewChild('discordDialog') discordDialogBox: TemplateRef; constructor( private dialogBoxService: NbDialogService, private externalUserAuthHandlerService: ExternalUserAuthHandlerService, private externalUserAuthService: ExternalUserAuthService, + private taskService: TaskService, + private toasterService: ToastrService, ) {} ngOnInit() {} openTaskPopup(task) { - this.getExternalUsers('discord'); - this.dialogBoxService.open(this.discordDialogBox, { context: task }); + this.stepOne = true; + this.stepTwo = false; + this.stepThree = false; + switch (task.quest_task_type.platform_name) { + case EExternalUserAuth.DISCORD: + this.getExternalUsers(EExternalUserAuth.DISCORD); + this.dialogBoxService.open(this.discordDialogBox, { context: task }); + return; + } } getExternalUsers(platformName) { this.externalUserAuthService.userAuthTokenIndex(platformName).subscribe((res) => { this.userAuthTokens = res; + if (this.userAuthTokens.length > 0) { + this.stepOne = false; + this.stepTwo = true; + this.selectedExternalUserAuthId = this.userAuthTokens[0].id; + } }); } loginAccount() { switch (this.task.quest_task_type.platform_name) { - case 'Discord': + case EExternalUserAuth.DISCORD: this.externalUserAuthHandlerService.loginToDiscord(this.task.id); return; } } - verifyDiscordServer() {} + verifyDiscordServer() { + this.taskService.verifyDiscord(this.task.id, this.selectedExternalUserAuthId).subscribe((res) => { + if (res) { + this.toasterService.successDialog('Verified'); + } else { + this.toasterService.warningDialog('Not Verified'); + } + }); + } } diff --git a/libs/shared/services/src/lib/api-routes.constant.ts b/libs/shared/services/src/lib/api-routes.constant.ts index 05aba34b2..1e97cea70 100644 --- a/libs/shared/services/src/lib/api-routes.constant.ts +++ b/libs/shared/services/src/lib/api-routes.constant.ts @@ -974,6 +974,7 @@ export const API_ROUTES = { SHOW: 'api/v2/tasks/show', //GET UPDATE: 'api/v2/tasks', //PUT TASK_TYPES_INDEX: 'api/v2/tasks/task_types_index', //GET + VERIFY_DISCORD: 'api/v2/tasks/verify_discord', //GET PUBLIC: { INDEX: 'api/v2/tasks/public', //GET SHOW: 'api/v2/tasks/public/show', //GET diff --git a/libs/shared/services/src/lib/external-user-auth-handler.service.ts b/libs/shared/services/src/lib/external-user-auth-handler.service.ts index 3622e3dc3..8ff9d0d75 100644 --- a/libs/shared/services/src/lib/external-user-auth-handler.service.ts +++ b/libs/shared/services/src/lib/external-user-auth-handler.service.ts @@ -7,11 +7,7 @@ import { environment } from '@commudle/shared-environments'; providedIn: 'root', }) export class ExternalUserAuthHandlerService { - private clientId = '1298505458629214218'; - - constructor(private activatedRoute: ActivatedRoute, private externalUserAuthService: ExternalUserAuthService) { - this.getTokenFromUrl(); - } + constructor(private activatedRoute: ActivatedRoute, private externalUserAuthService: ExternalUserAuthService) {} loginToDiscord(task_id?: number): void { const state = { @@ -22,7 +18,7 @@ export class ExternalUserAuthHandlerService { state['task_id'] = task_id; } const encodedState = encodeURIComponent(JSON.stringify(state)); - const url = `https://discord.com/oauth2/authorize?client_id=${this.clientId}&response_type=code&redirect_uri=${redirectUrl}&scope=identify+email+guilds+guilds.members.read&state=${encodedState}`; + const url = `https://discord.com/oauth2/authorize?client_id=${environment.discord_client_id}&response_type=code&redirect_uri=${redirectUrl}&scope=identify+email+guilds+guilds.members.read&state=${encodedState}`; window.location.href = url; } diff --git a/libs/shared/services/src/lib/task.service.ts b/libs/shared/services/src/lib/task.service.ts index 7d7249957..2ce5db09d 100644 --- a/libs/shared/services/src/lib/task.service.ts +++ b/libs/shared/services/src/lib/task.service.ts @@ -34,8 +34,12 @@ export class TaskService { return this.http.get(this.baseApiService.getRoute(API_ROUTES.TASKS.TASK_TYPES_INDEX)); } - // PUBLIC API + verifyDiscord(taskId: number, externalUserAuthTokenId: number): Observable { + const params = new HttpParams().set('task_id', taskId).set('external_user_auth_token_id', externalUserAuthTokenId); + return this.http.get(this.baseApiService.getRoute(API_ROUTES.TASKS.VERIFY_DISCORD), { params }); + } + // PUBLIC API pIndex(questId: number): Observable { const params = new HttpParams().set('quest_id', questId); return this.http.get(this.baseApiService.getRoute(API_ROUTES.TASKS.PUBLIC.INDEX), { From 6e50e016aa8589e6407aff3de629f62b7bbe0b67 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Thu, 28 Nov 2024 13:43:01 +0530 Subject: [PATCH 19/30] feat: add quest task types --- .../admin-static-assets-list.component.html | 43 +++++- .../admin-static-assets-list.component.scss | 24 +++ .../admin-static-assets-list.component.ts | 61 ++++++-- .../quest-task-types.component.html | 139 ++++++++++++++++++ .../quest-task-types.component.scss | 42 ++++++ .../quest-task-types.component.spec.ts | 27 ++++ .../quest-task-types.component.ts | 59 ++++++++ .../services/admin-static-assets.service.ts | 7 +- .../sys-admin/sys-admin-routing.module.ts | 5 + .../sys-admin/sys-admin.module.ts | 2 + .../quest-task-card.component.html | 4 +- .../quest-task-card.component.scss | 2 +- .../quest-task-card.component.ts | 10 +- .../environments/src/lib/environments.ts | 5 + libs/shared/models/src/lib/task.model.ts | 16 ++ .../services/src/lib/api-routes.constant.ts | 10 +- libs/shared/services/src/lib/task.service.ts | 31 ++++ 17 files changed, 470 insertions(+), 17 deletions(-) create mode 100644 apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.html create mode 100644 apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.scss create mode 100644 apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.spec.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.ts diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.html b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.html index 43f57c09d..6b4e36b60 100644 --- a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.html +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.html @@ -6,10 +6,28 @@ Create Assets +
+
+ +

No Result found....

+
+
+ +
@@ -28,7 +46,30 @@
- +
+ + + + +
Delete Page
+ +
+ + + +
+
{{ searchedById | json }}
+
+ + + + +
+
diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.scss b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.scss index 6a1b04466..5797a4f19 100644 --- a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.scss +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.scss @@ -11,6 +11,12 @@ @apply com-p-0; .assets-list-container { + .search-container { + @apply com-mx-6; + h3 { + @apply com-text-center; + } + } nb-list { nb-list-item { &:first-of-type { @@ -66,3 +72,21 @@ .asset-image img { @apply com-h-[200px]; } + +.loading-spinner { + @apply com-my-6; +} + +.get-by-id { + @apply com-w-[40dvw]; + nb-card-header, + nb-card-footer { + @apply com-flex com-justify-between com-items-center; + } + .json-content { + white-space: pre-wrap; /* Preserve formatting and allow wrapping */ + word-wrap: break-word; /* Break long words like URLs */ + overflow-wrap: break-word; /* Compatibility for modern browsers */ + max-width: 100%; /* Optional: Limit the width */ + } +} diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.ts b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.ts index 0ed12d86a..4994389c2 100644 --- a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.ts +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-static-assets/admin-static-assets-list/admin-static-assets-list.component.ts @@ -1,7 +1,10 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, TemplateRef } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { NbDialogService } from '@commudle/theme'; +import { AdminStaticAssetsService } from 'apps/commudle-admin/src/app/feature-modules/sys-admin/services/admin-static-assets.service'; import { IStaticAsset } from 'apps/shared-models/assets.model'; -import { AdminStaticAssetsService } from '../../../services/admin-static-assets.service'; import { Subscription } from 'rxjs'; +import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; @Component({ selector: 'app-admin-static-assets-list', @@ -9,27 +12,65 @@ import { Subscription } from 'rxjs'; styleUrls: ['./admin-static-assets-list.component.scss'], }) export class AdminStaticAssetsListComponent implements OnInit { - constructor(private adminStaticAssetsService: AdminStaticAssetsService) {} + constructor(private adminStaticAssetsService: AdminStaticAssetsService, private dialogService: NbDialogService) {} assets: IStaticAsset[] = []; page = 1; count = 5; total = -1; subscriptions: Subscription[] = []; + searchControl = new FormControl(''); + searchById = new FormControl(''); + isLoading = true; + searchedById; ngOnInit(): void { + this.setupSearch(); this.getAsset(); } - getAsset(): void { + setupSearch(): void { + this.subscriptions.push( + this.searchControl.valueChanges + .pipe( + debounceTime(2000), // Wait for 2 seconds + distinctUntilChanged(), // Prevent duplicate requests for the same value + ) + .subscribe((searchTerm) => { + this.isLoading = true; + this.assets = []; // Clear current assets + this.page = 1; // Reset pagination + this.getAsset(searchTerm); // Fetch filtered assets + }), + ); + } + + getAsset(query = ''): void { if (this.assets.length !== this.total) { this.subscriptions.push( - this.adminStaticAssetsService.getAssets(this.page, this.count).subscribe((value) => { - this.assets = this.assets.concat(value.static_assets); - this.page = +value.page; - this.total = +value.total; - this.page += 1; - }), + this.adminStaticAssetsService.getAssets(this.page, this.count, query).subscribe( + (value) => { + this.assets = this.assets.concat(value.static_assets); + this.page = +value.page; + this.total = +value.total; + this.page += 1; + this.isLoading = false; + }, + (error) => { + console.error('Error fetching assets:', error); + this.isLoading = false; + }, + ), ); } } + + getAssetById() { + this.adminStaticAssetsService.getAssetById(Number(this.searchById.value)).subscribe((data) => { + this.searchedById = data; + }); + } + + openDialogBox(templateRef: TemplateRef) { + this.dialogService.open(templateRef, { closeOnBackdropClick: false }); + } } diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.html b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.html new file mode 100644 index 000000000..f720168af --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.html @@ -0,0 +1,139 @@ +
+
+
+

List of Quest Task types platform

+ + + + + + + + + + + + + + + + +
LogoPlatform NameDescriptionPlatform TypesActions
{{ taskType.platform_name | titlecase }}{{ taskType.description ?? '--' }}{{ taskType.platform_type | capitalizeAndRemoveUnderscore }} + +       + +
+ + + + +
{{ data.taskType ? 'Edit Task type' : 'Create new task type' }}
+ +
+ +
+
+
+ + +
+ +
+
+ +
+ + +
+ +
+
+ +
+ + +
+ +
+
+ +
+ + +
+ +
+
+
+
+
+ + + + +
+
+
+
+
diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.scss b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.scss new file mode 100644 index 000000000..c80cb0a80 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.scss @@ -0,0 +1,42 @@ +table { + font-family: arial, sans-serif; + border-collapse: collapse; + width: 100%; +} + +td, +th { + border: 1px solid #dddddd; + text-align: left; + padding: 8px; +} + +tr:nth-child(even) { + background-color: #dddddd; +} + +img { + @apply com-h-6 com-w-6; +} + +ul { + @apply com-my-0; +} +nb-card { + @apply md:com-w-[40dvw] com-w-full; + nb-card-header, + nb-card-footer { + @apply com-flex com-justify-between; + } + + nb-card-body { + .quest-task-type-form { + .form-group { + @apply com-mb-4; + } + .required { + @apply com-text-red-500; + } + } + } +} diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.spec.ts b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.spec.ts new file mode 100644 index 000000000..3e1b6a12a --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { QuestTaskTypesComponent } from './quest-task-types.component'; + +describe('QuestTaskTypesComponent', () => { + let component: QuestTaskTypesComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [QuestTaskTypesComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(QuestTaskTypesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.ts b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.ts new file mode 100644 index 000000000..6f52cf9ba --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.ts @@ -0,0 +1,59 @@ +import { Component, OnInit } from '@angular/core'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { IQuestTaskType } from '@commudle/shared-models'; +import { TaskService } from '@commudle/shared-services'; +import { NbDialogService } from '@commudle/theme'; + +@Component({ + selector: 'commudle-quest-task-types', + templateUrl: './quest-task-types.component.html', + styleUrls: ['./quest-task-types.component.scss'], +}) +export class QuestTaskTypesComponent implements OnInit { + taskTypes: IQuestTaskType[]; + questTaskTypeForm: FormGroup; + + constructor(private taskService: TaskService, private nbDialogService: NbDialogService, private fb: FormBuilder) { + this.questTaskTypeForm = this.fb.group({ + platform_name: ['', [Validators.required, Validators.maxLength(100)]], + platform_type: ['', [Validators.required]], + logo_url: ['', [Validators.required, Validators.pattern('https?://.+')]], // URL validation + description: ['', [Validators.required, Validators.maxLength(255)]], + }); + } + + ngOnInit() { + this.taskService.getQuestTaskTypeIndex().subscribe((res) => { + this.taskTypes = res; + }); + } + + openDialog(templateRef, taskType?) { + if (taskType) { + this.questTaskTypeForm.patchValue(taskType); + } + this.nbDialogService.open(templateRef, { + context: { + taskType: taskType, + }, + }); + } + createOrUpdate(taskType?) { + if (taskType) { + this.taskService.updateQuestTaskType(taskType.id, this.questTaskTypeForm.value).subscribe((res) => { + const index = this.taskTypes.findIndex((t) => t.id === taskType.id); + this.taskTypes[index] = res; + }); + } else { + this.taskService.createQuestTaskType(this.questTaskTypeForm.value).subscribe((res) => { + this.taskTypes.unshift(res); + }); + } + } + + destroy(taskType, index) { + this.taskService.destroyQuestTaskType(taskType.id).subscribe((res) => { + this.taskTypes.splice(index, 1); + }); + } +} diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/services/admin-static-assets.service.ts b/apps/commudle-admin/src/app/feature-modules/sys-admin/services/admin-static-assets.service.ts index 4ca2278de..02bb41545 100644 --- a/apps/commudle-admin/src/app/feature-modules/sys-admin/services/admin-static-assets.service.ts +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/services/admin-static-assets.service.ts @@ -12,7 +12,7 @@ import { Observable } from 'rxjs'; export class AdminStaticAssetsService { constructor(private http: HttpClient, private apiRoutesService: ApiRoutesService) {} - getAssets(page?: number, count?: number): Observable { + getAssets(page?: number, count?: number, q?): Observable { let params = new HttpParams(); if (page) { params = params.append('page', String(page)); @@ -20,7 +20,10 @@ export class AdminStaticAssetsService { if (count) { params = params.append('count', String(count)); } - return this.http.get(this.apiRoutesService.getRoute(API_ROUTES.STATIC_ASSETS.SHOW), { params }); + if (q) { + params = params.append('q', q); + } + return this.http.get(this.apiRoutesService.getRoute(API_ROUTES.STATIC_ASSETS.INDEX), { params }); } createAsset(formData): Observable { diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/sys-admin-routing.module.ts b/apps/commudle-admin/src/app/feature-modules/sys-admin/sys-admin-routing.module.ts index 04450cc08..32f07dab3 100644 --- a/apps/commudle-admin/src/app/feature-modules/sys-admin/sys-admin-routing.module.ts +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/sys-admin-routing.module.ts @@ -24,6 +24,7 @@ import { AdminFeaturedUsersComponent } from 'apps/commudle-admin/src/app/feature import { AdminFeaturedCommunitiesChannelsComponent } from 'apps/commudle-admin/src/app/feature-modules/sys-admin/components/admin-featured/admin-featured-communities-channels/admin-featured-communities-channels.component'; import { PaymentLogsComponent } from 'apps/commudle-admin/src/app/feature-modules/sys-admin/components/payment-logs/payment-logs.component'; import { PaymentDetailComponent } from 'apps/shared-components/payment-detail/payment-detail.component'; +import { QuestTaskTypesComponent } from 'apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component'; const routes = [ { @@ -34,6 +35,10 @@ const routes = [ path: '', component: CommunityControlsComponent, }, + { + path: 'quest-task-types', + component: QuestTaskTypesComponent, + }, { path: 'pa', component: AdminPageAdsComponent, diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/sys-admin.module.ts b/apps/commudle-admin/src/app/feature-modules/sys-admin/sys-admin.module.ts index 422f1f546..bea199875 100644 --- a/apps/commudle-admin/src/app/feature-modules/sys-admin/sys-admin.module.ts +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/sys-admin.module.ts @@ -48,6 +48,7 @@ import { AdminFeaturedEventsComponent } from './components/admin-featured/admin- import { AdminFeaturedUsersComponent } from './components/admin-featured/admin-featured-users/admin-featured-users.component'; import { AdminFeaturedCommunitiesChannelsComponent } from './components/admin-featured/admin-featured-communities-channels/admin-featured-communities-channels.component'; import { PaymentLogsComponent } from 'apps/commudle-admin/src/app/feature-modules/sys-admin/components/payment-logs/payment-logs.component'; +import { QuestTaskTypesComponent } from 'apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component'; @NgModule({ declarations: [ SysAdminComponent, @@ -75,6 +76,7 @@ import { PaymentLogsComponent } from 'apps/commudle-admin/src/app/feature-module AdminFeaturedUsersComponent, AdminFeaturedCommunitiesChannelsComponent, PaymentLogsComponent, + QuestTaskTypesComponent, ], imports: [ CommonModule, diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.html b/apps/shared-components/quest-task-card/quest-task-card.component.html index 6960b4616..02dac3c9c 100644 --- a/apps/shared-components/quest-task-card/quest-task-card.component.html +++ b/apps/shared-components/quest-task-card/quest-task-card.component.html @@ -6,7 +6,8 @@

{{ task.description }}

- {{ task.reward_points }} Reward Points + + {{ task.reward_points }} Reward Points
@@ -39,6 +40,7 @@ + Connect with Account
diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.scss b/apps/shared-components/quest-task-card/quest-task-card.component.scss index b55172773..e9832b196 100644 --- a/apps/shared-components/quest-task-card/quest-task-card.component.scss +++ b/apps/shared-components/quest-task-card/quest-task-card.component.scss @@ -13,7 +13,7 @@ @apply com-h-10 com-line-clamp-2; } .rewards { - @apply com-w-full com-border com-border-solid com-border-Bright-Gray com-rounded-lg com-bg-gray-50 com-text-center com-text-fuchsia-600 com-py-1; + @apply com-flex com-items-center com-gap-2 com-w-full com-border com-border-solid com-border-Bright-Gray com-rounded-lg com-bg-gray-50 com-text-fuchsia-600 com-py-1 com-justify-center; } &.admin-properties { diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.ts b/apps/shared-components/quest-task-card/quest-task-card.component.ts index ec15234bb..2ac9a1182 100644 --- a/apps/shared-components/quest-task-card/quest-task-card.component.ts +++ b/apps/shared-components/quest-task-card/quest-task-card.component.ts @@ -1,5 +1,11 @@ import { Component, Input, OnInit, TemplateRef, ViewChild } from '@angular/core'; -import { EExternalUserAuth, IExternalUserAuth, ITask } from '@commudle/shared-models'; +import { + EExternalUserAuth, + IExternalUserAuth, + ITask, + ERewardPointsColors, + ERewardPointsLogo, +} from '@commudle/shared-models'; import { ExternalUserAuthHandlerService, ExternalUserAuthService, @@ -21,6 +27,8 @@ export class QuestTaskCardComponent implements OnInit { stepOne = true; stepTwo = false; stepThree = false; + ERewardPointsColors = ERewardPointsColors; + ERewardPointsLogo = ERewardPointsLogo; @ViewChild('discordDialog') discordDialogBox: TemplateRef; constructor( diff --git a/libs/shared/environments/src/lib/environments.ts b/libs/shared/environments/src/lib/environments.ts index 8a0e33f84..0c3a7216f 100644 --- a/libs/shared/environments/src/lib/environments.ts +++ b/libs/shared/environments/src/lib/environments.ts @@ -12,6 +12,7 @@ type Environment = { stripe: string; sentry_dsn: string; razorpay_key: string; + discord_client_id: string; }; const environments: { [type: string]: Environment } = { @@ -30,6 +31,7 @@ const environments: { [type: string]: Environment } = { 'pk_live_51NIQahSAaAm97Wzm6Nthh2SsbFH123ckuvoO9P4fEghH2IeC5laeiJmYSBHbOt9bFE1fHY1Hwig5lqiHko0bn7Yi00EWLt1AuB', sentry_dsn: 'https://008ea5f833883ac6e933856b26757b7e@o566989.ingest.sentry.io/4506098297405440', razorpay_key: 'rzp_test_AQ8emxZcsJoKdl', + discord_client_id: '1298505458629214218', }, test: { production: false, @@ -46,6 +48,7 @@ const environments: { [type: string]: Environment } = { 'pk_test_51NIQahSAaAm97WzmtpZtqYAuI1cCfN7LAJPoy8SmBpJqXQ5c7gnmOXXS9VtXa1b6YvCa1Uc9bX3Ra9ZLjm4AQBSs00en3kVojH', sentry_dsn: 'https://008ea5f833883ac6e933856b26757b7e@o566989.ingest.sentry.io/4506098297405440', razorpay_key: 'rzp_test_AQ8emxZcsJoKdl', + discord_client_id: '1298505458629214218', }, staging: { production: false, @@ -62,6 +65,7 @@ const environments: { [type: string]: Environment } = { 'pk_live_51NIQahSAaAm97Wzm6Nthh2SsbFH123ckuvoO9P4fEghH2IeC5laeiJmYSBHbOt9bFE1fHY1Hwig5lqiHko0bn7Yi00EWLt1AuB', sentry_dsn: 'https://008ea5f833883ac6e933856b26757b7e@o566989.ingest.sentry.io/4506098297405440', razorpay_key: 'rzp_live_nqGSJl7Jt6bsZx', + discord_client_id: '1298505458629214218', }, production: { production: true, @@ -78,6 +82,7 @@ const environments: { [type: string]: Environment } = { 'pk_live_51NIQahSAaAm97Wzm6Nthh2SsbFH123ckuvoO9P4fEghH2IeC5laeiJmYSBHbOt9bFE1fHY1Hwig5lqiHko0bn7Yi00EWLt1AuB', sentry_dsn: 'https://008ea5f833883ac6e933856b26757b7e@o566989.ingest.sentry.io/4506098297405440', razorpay_key: 'rzp_live_nqGSJl7Jt6bsZx', + discord_client_id: '1298505458629214218', }, }; diff --git a/libs/shared/models/src/lib/task.model.ts b/libs/shared/models/src/lib/task.model.ts index 8e07645d4..a9204da56 100644 --- a/libs/shared/models/src/lib/task.model.ts +++ b/libs/shared/models/src/lib/task.model.ts @@ -9,3 +9,19 @@ export interface ITask { url: string; quest_task_type: IQuestTaskType; } + +export const ERewardPointsColors = { + 1: 'com-text-yellow-700', + 2: 'com-text-slate-500', + 3: 'com-text-yellow-600', + 4: 'com-text-blue-500', + 5: 'com-text-fuchsia-600', +}; + +export const ERewardPointsLogo = { + 1: 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBOXBhQXc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--9b2974c3f3b141442f7a4385a2844074bdd8cbac/1.svg', + 2: 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBOXRhQXc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--9893d9a6abbba504f0ee8552d9a9014b3ca753b8/2.svg', + 3: 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBOXhhQXc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--038531b272cf14887b398b734da6d046fe5456d2/3.svg', + 4: 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBOTFhQXc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--5d1935fdb21c170d2239ff2f883bf75bc2e8aa21/4.svg', + 5: 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBOTVhQXc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--af928159fd59e68004390eb9f73ca3b1755fa84b/5.svg', +}; diff --git a/libs/shared/services/src/lib/api-routes.constant.ts b/libs/shared/services/src/lib/api-routes.constant.ts index 1e97cea70..8bafaf366 100644 --- a/libs/shared/services/src/lib/api-routes.constant.ts +++ b/libs/shared/services/src/lib/api-routes.constant.ts @@ -390,9 +390,11 @@ export const API_ROUTES = { DELETE: 'api/v2/badges', }, STATIC_ASSETS: { - SHOW: 'api/v2/static_assets', + INDEX: 'api/v2/static_assets', CREATE: 'api/v2/static_assets', + SHOW: 'api/v2/static_assets/show', }, + USER_BADGES: { INDEX: 'api/v2/user_badges', CREATE: 'api/v2/user_badges', @@ -979,5 +981,11 @@ export const API_ROUTES = { INDEX: 'api/v2/tasks/public', //GET SHOW: 'api/v2/tasks/public/show', //GET }, + QUEST_TASK_TYPE: { + INDEX: 'api/v2/tasks/quest_task_type', //GET + UPDATE: 'api/v2/tasks/quest_task_type', //PUT + CREATE: 'api/v2/tasks/quest_task_type', //POST + DESTROY: 'api/v2/tasks/quest_task_type', //DELETE + }, }, }; diff --git a/libs/shared/services/src/lib/task.service.ts b/libs/shared/services/src/lib/task.service.ts index 2ce5db09d..6f452512c 100644 --- a/libs/shared/services/src/lib/task.service.ts +++ b/libs/shared/services/src/lib/task.service.ts @@ -46,4 +46,35 @@ export class TaskService { params, }); } + + // Quest Task Type + getQuestTaskTypeIndex(): Observable { + return this.http.get(this.baseApiService.getRoute(API_ROUTES.TASKS.QUEST_TASK_TYPE.INDEX)); + } + + createQuestTaskType(formData): Observable { + return this.http.post(this.baseApiService.getRoute(API_ROUTES.TASKS.QUEST_TASK_TYPE.CREATE), { + quest_task_type: formData, + }); + } + + destroyQuestTaskType(questTaskTypeId): Observable { + const params = new HttpParams().set('quest_task_type_id', questTaskTypeId); + return this.http.delete(this.baseApiService.getRoute(API_ROUTES.TASKS.QUEST_TASK_TYPE.DESTROY), { + params, + }); + } + + updateQuestTaskType(questTaskTypeId, formData): Observable { + const params = new HttpParams().set('quest_task_type_id', questTaskTypeId); + return this.http.put( + this.baseApiService.getRoute(API_ROUTES.TASKS.QUEST_TASK_TYPE.UPDATE), + { + quest_task_type: formData, + }, + { + params, + }, + ); + } } From 4bceadd27dc3f7147424d39e4802ee24d04be55e Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Fri, 29 Nov 2024 14:37:43 +0530 Subject: [PATCH 20/30] style: quest task creation --- .../community-controls.component.html | 2 + .../quest-task-types.component.html | 58 ++++++++++--------- .../quest-task-types.component.scss | 2 +- .../quest-task-card.component.ts | 4 ++ .../lib/external-user-auth-handler.service.ts | 6 ++ 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/community-controls.component.html b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/community-controls.component.html index 89427f2c4..ad6b39c07 100644 --- a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/community-controls.component.html +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/community-controls.component.html @@ -11,6 +11,8 @@ Create Community + +
diff --git a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.html b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.html index f720168af..455dd92ee 100644 --- a/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.html +++ b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/quest-task-types/quest-task-types.component.html @@ -1,35 +1,39 @@
-

List of Quest Task types platform

- - - - - - - - - - - - - - - - -
LogoPlatform NameDescriptionPlatform TypesActions
{{ taskType.platform_name | titlecase }}{{ taskType.description ?? '--' }}{{ taskType.platform_type | capitalizeAndRemoveUnderscore }} - -       - -
+ + +

List of Quest Task types platform

+ + + + + + + + + + + + + + + + +
LogoPlatform NameDescriptionPlatform TypesActions
{{ taskType.platform_name | titlecase }}{{ taskType.description ?? '--' }}{{ taskType.platform_type | capitalizeAndRemoveUnderscore }} + +       + +
+
+
- +
{{ data.taskType ? 'Edit Task type' : 'Create new task type' }}

{{ quest.name }}

-
-
-
+
+
+
+ + Active +
+
+ + Inactive +
+
+
{{ quest.start_date | date : "d'th' MMM" }} | @@ -24,13 +33,35 @@

{{ quest.name }}

+
-
+
+
+
+ + Tasks +
+ + Total Task Completed + 0/{{ quest.tasks_count }} + +
+
+
+ + Rewards +
+ + Reward Points Collected + 0/{{ quest.total_rewards_points }} + +
+
diff --git a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.scss b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.scss index ce0b6a333..caadcd2a5 100644 --- a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.scss +++ b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.scss @@ -1,23 +1,82 @@ -.community-badge { - @apply com-mt-4; -} +.main-column { + @apply com-border-0 com-border-r com-border-solid com-border-Bright-Gray; -.dates { - @apply com-flex com-gap-2 com-items-center; - .start-date { - @apply com-border-2 com-border-solid com-border-Bright-Gray com-rounded-tl-2xl com-rounded-bl-2xl com-rounded-tr-lg com-rounded-br-lg com-w-max com-px-2 com-py-1; + .community-badge { + @apply com-mt-4; } - .end-date { - @apply com-border-2 com-border-solid com-border-Bright-Gray com-rounded-tl-lg com-rounded-bl-lg com-rounded-tr-2xl com-rounded-br-2xl com-w-max com-px-2 com-py-1; + + .status-dates { + @apply com-flex com-gap-2 com-items-center; + .status { + @apply com-border-2 com-border-solid com-border-Bright-Gray com-rounded-2xl com-w-max com-px-2 com-py-1; + .active { + fa-icon { + @apply com-text-green-500; + } + } + .inactive { + fa-icon { + @apply com-text-red-500; + } + } + .active, + .inactive { + @apply com-flex com-gap-2; + } + } + .dates { + @apply com-flex com-gap-2 com-items-center; + .start-date { + @apply com-border-2 com-border-solid com-border-Bright-Gray com-rounded-tl-2xl com-rounded-bl-2xl com-rounded-tr-lg com-rounded-br-lg com-w-max com-px-2 com-py-1; + } + .end-date { + @apply com-border-2 com-border-solid com-border-Bright-Gray com-rounded-tl-lg com-rounded-bl-lg com-rounded-tr-2xl com-rounded-br-2xl com-w-max com-px-2 com-py-1; + } + .date { + @apply com-font-semibold; + } + .time { + @apply com-text-gray-500; + } + } } - .date { - @apply com-font-semibold; + .divided-line-horizontal { + @apply com-border com-border-solid com-border-Bright-Gray com-mt-4 com-mb-1; } - .time { - @apply com-text-gray-500; + + .task-cards { + @apply com-grid com-grid-cols-2 com-mr-3; } } -.task-cards { - @apply com-grid com-grid-cols-2; +.right-column { + @apply com-ml-3 com-mt-4; + .user-task-container, + .user-rewards-container { + .heading { + @apply com-flex com-items-center com-gap-2; + span { + @apply com-font-semibold com-text-base; + } + &.task { + fa-icon { + @apply com-text-primary-400; + } + } + &.rewards { + fa-icon { + @apply com-text-red-500; + } + } + } + nb-card { + @apply com-mx-0; + nb-card-header { + @apply com-bg-gray-50 com-text-sm com-text-gray-500; + } + nb-card-body { + @apply com-text-base com-font-bold; + } + } + } } diff --git a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts index 26e9a5f3d..79a74da76 100644 --- a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts +++ b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts @@ -3,7 +3,7 @@ import { ActivatedRoute } from '@angular/router'; import { IQuest, ITask } from '@commudle/shared-models'; import { TaskService } from '@commudle/shared-services'; import { NbDialogService } from '@commudle/theme'; -import { faArrowRight } from '@fortawesome/free-solid-svg-icons'; +import { faArrowRight, faCircle, faGift, faListCheck } from '@fortawesome/free-solid-svg-icons'; import { QuestTaskCardComponent } from 'apps/shared-components/quest-task-card/quest-task-card.component'; import moment from 'moment'; @@ -18,6 +18,9 @@ export class PublicQuestHomepageComponent implements OnInit { tasks: ITask[]; icons = { faArrowRight, + faCircle, + faListCheck, + faGift, }; @ViewChild(QuestTaskCardComponent) questTaskCardComponent: QuestTaskCardComponent; @ViewChild('loadingScreen') LoadingDialogBox: TemplateRef; diff --git a/apps/commudle-admin/src/app/feature-modules/public-quests/public-quests.module.ts b/apps/commudle-admin/src/app/feature-modules/public-quests/public-quests.module.ts index fcdb86f04..d64e38cbd 100644 --- a/apps/commudle-admin/src/app/feature-modules/public-quests/public-quests.module.ts +++ b/apps/commudle-admin/src/app/feature-modules/public-quests/public-quests.module.ts @@ -4,9 +4,10 @@ import { PublicQuestHomepageComponent } from './components/public-quest-homepage import { PublicQuestsRoutes } from './public-quests.routing'; import { SharedComponentsModule } from 'apps/shared-components/shared-components.module'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { NbCardModule } from '@commudle/theme'; @NgModule({ - imports: [CommonModule, PublicQuestsRoutes, SharedComponentsModule, FontAwesomeModule], + imports: [CommonModule, PublicQuestsRoutes, SharedComponentsModule, FontAwesomeModule, NbCardModule], declarations: [PublicQuestHomepageComponent], }) export class PublicQuestsModule {} diff --git a/libs/shared/models/src/lib/quest.model.ts b/libs/shared/models/src/lib/quest.model.ts index 30b9cde7b..0849f49b7 100644 --- a/libs/shared/models/src/lib/quest.model.ts +++ b/libs/shared/models/src/lib/quest.model.ts @@ -12,6 +12,8 @@ export interface IQuest { tasks_count: number; participants_count: number; community: ICommunity; + is_active: boolean; + total_rewards_points: number; } export enum EQuestVisibility { From 8f09c0b37dc7733cf649aef5ad43cc4a5d2a56d0 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Sat, 30 Nov 2024 12:54:55 +0530 Subject: [PATCH 22/30] feat: instagram and telegram callback components --- .../components/discord/discord.component.ts | 3 +- .../instagram/instagram.component.html | 8 +++++ .../instagram/instagram.component.scss | 9 ++++++ .../instagram/instagram.component.spec.ts | 27 +++++++++++++++++ .../instagram/instagram.component.ts | 29 +++++++++++++++++++ .../telegram/telegram.component.html | 8 +++++ .../telegram/telegram.component.scss | 9 ++++++ .../telegram/telegram.component.spec.ts | 27 +++++++++++++++++ .../components/telegram/telegram.component.ts | 29 +++++++++++++++++++ .../user-oauth/user-oauth.module.ts | 4 ++- .../user-oauth/user-oauth.routing.ts | 10 +++++++ .../src/assets/static-assets.ts | 9 ++++++ .../quest-task-card.component.ts | 11 +++++++ .../src/lib/external-user-auth.model.ts | 3 ++ .../lib/external-user-auth-handler.service.ts | 21 ++++++++++++-- 15 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.html create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.scss create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.spec.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.html create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.scss create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.spec.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.ts diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.ts b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.ts index 39c3b75b5..976f9e363 100644 --- a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.ts +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { EExternalUserAuth } from '@commudle/shared-models'; import { ExternalUserAuthHandlerService } from '@commudle/shared-services'; import { staticAssets } from 'apps/commudle-admin/src/assets/static-assets'; @@ -22,7 +23,7 @@ export class DiscordComponent implements OnInit { const state = JSON.parse(decodeURIComponent(encodedState)); const baseUrl = state.redirectTo; this.redirectTo = `${baseUrl}?task_id=${state.task_id}`; - this.externalUserAuthHandlerService.getTokenFromUrl(); + this.externalUserAuthHandlerService.getTokenFromUrl(EExternalUserAuth.DISCORD); window.location.href = this.redirectTo; }); } diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.html b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.html new file mode 100644 index 000000000..981c0eb63 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.html @@ -0,0 +1,8 @@ +
+ + Instagram Logo +
+ Redirect To: + {{ redirectTo }} +
+
diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.scss b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.scss new file mode 100644 index 000000000..9ebeb1b17 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.scss @@ -0,0 +1,9 @@ +section { + @apply com-flex com-justify-center com-flex-col com-h-[80dvh] com-gap-14; + img { + @apply com-h-40; + } + div { + @apply com-text-center; + } +} diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.spec.ts b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.spec.ts new file mode 100644 index 000000000..dc5af66ca --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { InstagramComponent } from './instagram.component'; + +describe('InstagramComponent', () => { + let component: InstagramComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [InstagramComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(InstagramComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.ts b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.ts new file mode 100644 index 000000000..9fa713124 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.ts @@ -0,0 +1,29 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { EExternalUserAuth } from '@commudle/shared-models'; +import { ExternalUserAuthHandlerService } from '@commudle/shared-services'; +import { staticAssets } from 'apps/commudle-admin/src/assets/static-assets'; + +@Component({ + selector: 'commudle-instagram', + templateUrl: './instagram.component.html', + styleUrls: ['./instagram.component.scss'], +}) +export class InstagramComponent implements OnInit { + redirectTo: string; + staticAssets = staticAssets; + constructor( + private activatedRoute: ActivatedRoute, + private externalUserAuthHandlerService: ExternalUserAuthHandlerService, + ) {} + + ngOnInit() { + this.activatedRoute.queryParamMap.subscribe((params) => { + const encodedState = params.get('state'); + const state = JSON.parse(decodeURIComponent(encodedState)); + this.redirectTo = state.redirectTo; + this.externalUserAuthHandlerService.getTokenFromUrl(EExternalUserAuth.INSTAGRAM); + window.location.href = this.redirectTo; + }); + } +} diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.html b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.html new file mode 100644 index 000000000..4db73de8c --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.html @@ -0,0 +1,8 @@ +
+ + Telegram Logo +
+ Redirect To: + {{ redirectTo }} +
+
diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.scss b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.scss new file mode 100644 index 000000000..9ebeb1b17 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.scss @@ -0,0 +1,9 @@ +section { + @apply com-flex com-justify-center com-flex-col com-h-[80dvh] com-gap-14; + img { + @apply com-h-40; + } + div { + @apply com-text-center; + } +} diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.spec.ts b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.spec.ts new file mode 100644 index 000000000..6d860fe62 --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.spec.ts @@ -0,0 +1,27 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { TelegramComponent } from './telegram.component'; + +describe('TelegramComponent', () => { + let component: TelegramComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [TelegramComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TelegramComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.ts b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.ts new file mode 100644 index 000000000..276a5f6dc --- /dev/null +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.ts @@ -0,0 +1,29 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { EExternalUserAuth } from '@commudle/shared-models'; +import { ExternalUserAuthHandlerService } from '@commudle/shared-services'; +import { staticAssets } from 'apps/commudle-admin/src/assets/static-assets'; + +@Component({ + selector: 'commudle-telegram', + templateUrl: './telegram.component.html', + styleUrls: ['./telegram.component.scss'], +}) +export class TelegramComponent implements OnInit { + redirectTo: string; + staticAssets = staticAssets; + constructor( + private activatedRoute: ActivatedRoute, + private externalUserAuthHandlerService: ExternalUserAuthHandlerService, + ) {} + + ngOnInit() { + this.activatedRoute.queryParamMap.subscribe((params) => { + const encodedState = params.get('state'); + const state = JSON.parse(decodeURIComponent(encodedState)); + this.redirectTo = state.redirectTo; + this.externalUserAuthHandlerService.getTokenFromUrl(EExternalUserAuth.TELEGRAM); + window.location.href = this.redirectTo; + }); + } +} diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.module.ts b/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.module.ts index 0e115066d..8a2796c80 100644 --- a/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.module.ts +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.module.ts @@ -3,9 +3,11 @@ import { CommonModule } from '@angular/common'; import { UserOauthRoutes } from './user-oauth.routing'; import { DiscordComponent } from './components/discord/discord.component'; import { SharedComponentsModule } from '@commudle/shared-components'; +import { InstagramComponent } from './components/instagram/instagram.component'; +import { TelegramComponent } from './components/telegram/telegram.component'; @NgModule({ imports: [CommonModule, UserOauthRoutes, SharedComponentsModule], - declarations: [DiscordComponent], + declarations: [DiscordComponent, TelegramComponent, InstagramComponent], }) export class UserOauthModule {} diff --git a/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.routing.ts b/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.routing.ts index df9fe67ce..1e5fb2ade 100644 --- a/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.routing.ts +++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.routing.ts @@ -1,11 +1,21 @@ import { Routes, RouterModule } from '@angular/router'; import { DiscordComponent } from './components/discord/discord.component'; +import { TelegramComponent } from './components/telegram/telegram.component'; +import { InstagramComponent } from './components/instagram/instagram.component'; const routes: Routes = [ { path: 'discord/callback', component: DiscordComponent, }, + { + path: 'instagram/callback', + component: InstagramComponent, + }, + { + path: 'telegram/callback', + component: TelegramComponent, + }, ]; export const UserOauthRoutes = RouterModule.forChild(routes); diff --git a/apps/commudle-admin/src/assets/static-assets.ts b/apps/commudle-admin/src/assets/static-assets.ts index 228e9e72c..b76347ac3 100644 --- a/apps/commudle-admin/src/assets/static-assets.ts +++ b/apps/commudle-admin/src/assets/static-assets.ts @@ -179,6 +179,15 @@ export const staticAssets = { call_for_speaker_empty_state: 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBL0N1QWc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--3d0e4b9c60c0f63c0272e41a6ea79608454cc379/CFP-Empty%20State.png', + // id: 161 + instagram_logo: + 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBeXcvQXc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--46e0fcd32ed6e38bf0439c81d04bf730fd392b7d/Instagram.svg', + + // id: 162 discord_logo: 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBeTAvQXc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--d01625bde4293ef3b7d8de196a73f603114eed05/Discord.svg', + + // id: 163 + telegram_logo: + 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBeTQvQXc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--1e096d1892f9cb80c35bc962b86956429681e00a/Telegram.svg', }; diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.ts b/apps/shared-components/quest-task-card/quest-task-card.component.ts index fc17ba066..8db969525 100644 --- a/apps/shared-components/quest-task-card/quest-task-card.component.ts +++ b/apps/shared-components/quest-task-card/quest-task-card.component.ts @@ -51,6 +51,14 @@ export class QuestTaskCardComponent implements OnInit { this.getExternalUsers(EExternalUserAuth.DISCORD); this.dialogBoxService.open(this.discordDialogBox, { context: task }); return; + case EExternalUserAuth.INSTAGRAM: + this.getExternalUsers(EExternalUserAuth.INSTAGRAM); + this.dialogBoxService.open(this.discordDialogBox, { context: task }); + return; + case EExternalUserAuth.TELEGRAM: + this.getExternalUsers(EExternalUserAuth.TELEGRAM); + this.dialogBoxService.open(this.discordDialogBox, { context: task }); + return; } } @@ -73,6 +81,9 @@ export class QuestTaskCardComponent implements OnInit { case EExternalUserAuth.INSTAGRAM: this.externalUserAuthHandlerService.loginToInstagram(); return; + case EExternalUserAuth.TELEGRAM: + this.externalUserAuthHandlerService.loginToTelegram(); + return; } } diff --git a/libs/shared/models/src/lib/external-user-auth.model.ts b/libs/shared/models/src/lib/external-user-auth.model.ts index 1624ca3c5..f2d7b9025 100644 --- a/libs/shared/models/src/lib/external-user-auth.model.ts +++ b/libs/shared/models/src/lib/external-user-auth.model.ts @@ -13,4 +13,7 @@ export enum EExternalUserAuth { INSTAGRAM = 'instagram', FACEBOOK = 'facebook', LINKEDIN = 'linkedin', + TELEGRAM = 'telegram', + YOUTUBE = 'youtube', + GITHUB = 'github', } diff --git a/libs/shared/services/src/lib/external-user-auth-handler.service.ts b/libs/shared/services/src/lib/external-user-auth-handler.service.ts index 6fbebad02..0b1b0f34b 100644 --- a/libs/shared/services/src/lib/external-user-auth-handler.service.ts +++ b/libs/shared/services/src/lib/external-user-auth-handler.service.ts @@ -2,6 +2,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ExternalUserAuthService } from './external-user-auth.service'; import { environment } from '@commudle/shared-environments'; +import { EExternalUserAuth } from '@commudle/shared-models'; @Injectable({ providedIn: 'root', @@ -25,17 +26,31 @@ export class ExternalUserAuthHandlerService { loginToInstagram() { const YOUR_INSTAGRAM_CLIENT_ID = '989280999691182'; const redirectUrl = 'https://www.commudle.com/'; - const instagramLoginUrl = `https://api.instagram.com/oauth/authorize?client_id=${YOUR_INSTAGRAM_CLIENT_ID}&redirect_uri=${redirectUrl}&scope=user_profile,user_media&response_type=code`; + const state = { + redirectTo: window.location.href, + }; + const encodedState = encodeURIComponent(JSON.stringify(state)); + const instagramLoginUrl = `https://api.instagram.com/oauth/authorize?client_id=${YOUR_INSTAGRAM_CLIENT_ID}&redirect_uri=${redirectUrl}&scope=user_profile,user_media&response_type=code&state=${encodedState}`; window.location.href = instagramLoginUrl; } + + loginToTelegram() { + const YOUR_BOT_USERNAME = 'GroupixArshbot'; + const state = { + redirectTo: window.location.href, + }; + const encodedState = encodeURIComponent(JSON.stringify(state)); + const redirectUrl = `https://telegram.me/${YOUR_BOT_USERNAME}?start=auth&state=${encodedState}`; + window.location.href = redirectUrl; + } // Extract token from URL after Discord login - getTokenFromUrl() { + getTokenFromUrl(platformName: EExternalUserAuth) { this.activatedRoute.queryParamMap.subscribe((params) => { const code = params.get('code'); // Retrieve the 'code' parameter if (code) { const external_user_auth = { token: code, - platform: 'discord', + platform: platformName, }; this.externalUserAuthService.create(external_user_auth).subscribe(); } From 4bd72b150bb88ee0b60d69ba903d65256d226c44 Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Sat, 30 Nov 2024 20:11:19 +0530 Subject: [PATCH 23/30] feat: create quest user response --- .../public-quest-homepage.component.html | 5 +- .../public-quest-homepage.component.ts | 13 ++++- .../quest-task-card.component.ts | 22 +++++++ libs/shared/models/src/index.ts | 1 + .../src/lib/quest-user-response.model.ts | 3 + libs/shared/models/src/lib/task.model.ts | 1 + libs/shared/services/src/index.ts | 1 + .../services/src/lib/api-routes.constant.ts | 11 ++++ .../src/lib/quest-user-responses.service.ts | 57 +++++++++++++++++++ 9 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 libs/shared/models/src/lib/quest-user-response.model.ts create mode 100644 libs/shared/services/src/lib/quest-user-responses.service.ts diff --git a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.html b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.html index fb2db6b7e..02d433360 100644 --- a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.html +++ b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.html @@ -36,7 +36,10 @@

{{ quest.name }}

- +
diff --git a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts index 79a74da76..0305e5ee3 100644 --- a/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts +++ b/apps/commudle-admin/src/app/feature-modules/public-quests/components/public-quest-homepage/public-quest-homepage.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { IQuest, ITask } from '@commudle/shared-models'; -import { TaskService } from '@commudle/shared-services'; +import { IQuest, IQuestUserResponse, ITask } from '@commudle/shared-models'; +import { QuestUserResponsesService, TaskService } from '@commudle/shared-services'; import { NbDialogService } from '@commudle/theme'; import { faArrowRight, faCircle, faGift, faListCheck } from '@fortawesome/free-solid-svg-icons'; import { QuestTaskCardComponent } from 'apps/shared-components/quest-task-card/quest-task-card.component'; @@ -22,6 +22,7 @@ export class PublicQuestHomepageComponent implements OnInit { faListCheck, faGift, }; + questUserResponse: IQuestUserResponse; @ViewChild(QuestTaskCardComponent) questTaskCardComponent: QuestTaskCardComponent; @ViewChild('loadingScreen') LoadingDialogBox: TemplateRef; @@ -29,11 +30,13 @@ export class PublicQuestHomepageComponent implements OnInit { private activatedRoute: ActivatedRoute, private taskService: TaskService, private dialogService: NbDialogService, + private questUserResponsesService: QuestUserResponsesService, ) {} ngOnInit() { this.activatedRoute.data.subscribe((data) => { this.quest = data.quest; + this.getCurrentUserResponse(); this.getTask(); }); } @@ -45,6 +48,12 @@ export class PublicQuestHomepageComponent implements OnInit { }); } + getCurrentUserResponse() { + this.questUserResponsesService.getCurrentUserResponses(this.quest.id).subscribe((res) => { + this.questUserResponse = res; + }); + } + processTaskFromQueryParams() { this.activatedRoute.queryParamMap.subscribe((params) => { const taskId = Number(params.get('task_id')); diff --git a/apps/shared-components/quest-task-card/quest-task-card.component.ts b/apps/shared-components/quest-task-card/quest-task-card.component.ts index 8db969525..dd5f56d03 100644 --- a/apps/shared-components/quest-task-card/quest-task-card.component.ts +++ b/apps/shared-components/quest-task-card/quest-task-card.component.ts @@ -5,12 +5,14 @@ import { ITask, ERewardPointsColors, ERewardPointsLogo, + IQuestUserResponse, } from '@commudle/shared-models'; import { ExternalUserAuthHandlerService, ExternalUserAuthService, TaskService, ToastrService, + QuestUserResponsesService, } from '@commudle/shared-services'; import { NbDialogService } from '@commudle/theme'; @@ -22,6 +24,8 @@ import { NbDialogService } from '@commudle/theme'; export class QuestTaskCardComponent implements OnInit { @Input() task: ITask; @Input() adminPage: boolean = false; + @Input() questUserResponse: IQuestUserResponse; + userAuthTokens: IExternalUserAuth[]; selectedExternalUserAuthId: number; stepOne = true; @@ -37,11 +41,17 @@ export class QuestTaskCardComponent implements OnInit { private externalUserAuthService: ExternalUserAuthService, private taskService: TaskService, private toasterService: ToastrService, + private questUserResponses: QuestUserResponsesService, ) {} ngOnInit() {} openTaskPopup(task) { + if (this.questUserResponse) { + this.create_quest_task_user_response(); + } else { + this.createQuestUserResponse(); + } this.stepOne = true; this.stepTwo = false; this.stepThree = false; @@ -96,4 +106,16 @@ export class QuestTaskCardComponent implements OnInit { } }); } + + createQuestUserResponse() { + this.questUserResponses.create(this.task.quest_id).subscribe(); + } + + create_quest_task_user_response() { + this.questUserResponses + .create_quest_task_user_response(this.task.id, this.questUserResponse.id) + .subscribe((res) => { + console.log('🚀 ~ QuestTaskCardComponent ~ .subscribe ~ res:', res); + }); + } } diff --git a/libs/shared/models/src/index.ts b/libs/shared/models/src/index.ts index e1d617de0..6f48b3f60 100644 --- a/libs/shared/models/src/index.ts +++ b/libs/shared/models/src/index.ts @@ -44,3 +44,4 @@ export * from './lib/external-user-auth.model'; export * from './lib/quest.model'; export * from './lib/task.model'; export * from './lib/quest-task-type.model'; +export * from './lib/quest-user-response.model'; diff --git a/libs/shared/models/src/lib/quest-user-response.model.ts b/libs/shared/models/src/lib/quest-user-response.model.ts new file mode 100644 index 000000000..5d748727a --- /dev/null +++ b/libs/shared/models/src/lib/quest-user-response.model.ts @@ -0,0 +1,3 @@ +export interface IQuestUserResponse { + id: number; +} diff --git a/libs/shared/models/src/lib/task.model.ts b/libs/shared/models/src/lib/task.model.ts index a9204da56..6bfe1a429 100644 --- a/libs/shared/models/src/lib/task.model.ts +++ b/libs/shared/models/src/lib/task.model.ts @@ -8,6 +8,7 @@ export interface ITask { other_rewards: string; url: string; quest_task_type: IQuestTaskType; + quest_id: number; } export const ERewardPointsColors = { diff --git a/libs/shared/services/src/index.ts b/libs/shared/services/src/index.ts index 1de502b85..bd7859e48 100644 --- a/libs/shared/services/src/index.ts +++ b/libs/shared/services/src/index.ts @@ -26,3 +26,4 @@ export * from './lib/external-user-auth-handler.service'; export * from './lib/external-user-auth.service'; export * from './lib/quest.service'; export * from './lib/task.service'; +export * from './lib/quest-user-responses.service'; diff --git a/libs/shared/services/src/lib/api-routes.constant.ts b/libs/shared/services/src/lib/api-routes.constant.ts index 8bafaf366..b7025513d 100644 --- a/libs/shared/services/src/lib/api-routes.constant.ts +++ b/libs/shared/services/src/lib/api-routes.constant.ts @@ -988,4 +988,15 @@ export const API_ROUTES = { DESTROY: 'api/v2/tasks/quest_task_type', //DELETE }, }, + + QUEST_USER_RESPONSES: { + CREATE: 'api/v2/quest_user_responses', //POST + INDEX: 'api/v2/quest_user_responses', //GET + CURRENT_USER_RESPONSES: 'api/v2/quest_user_responses/current_user_responses', //GET + CREATE_QUEST_TASK_USER_RESPONSE: 'api/v2/quest_user_responses/create_quest_task_user_response', //POST + PUBLIC: { + INDEX: 'api/v2/quest_user_responses/public', //GET + SHOW: 'api/v2/quest_user_responses/public/show', //GET + }, + }, }; diff --git a/libs/shared/services/src/lib/quest-user-responses.service.ts b/libs/shared/services/src/lib/quest-user-responses.service.ts new file mode 100644 index 000000000..5a4c60e67 --- /dev/null +++ b/libs/shared/services/src/lib/quest-user-responses.service.ts @@ -0,0 +1,57 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { API_ROUTES } from './api-routes.constant'; +import { BaseApiService } from './base-api.service'; +import { HttpClient, HttpParams } from '@angular/common/http'; +import { IQuestUserResponse } from '@commudle/shared-models'; +@Injectable({ + providedIn: 'root', +}) +export class QuestUserResponsesService { + constructor(private http: HttpClient, private baseApiService: BaseApiService) {} + + create(questId: number | string): Observable { + const params = new HttpParams().set('quest_id', questId); + return this.http.post( + this.baseApiService.getRoute(API_ROUTES.QUEST_USER_RESPONSES.CREATE), + params, + ); + } + + index(questId: number | string): Observable { + const params = new HttpParams().set('quest_id', questId); + return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUEST_USER_RESPONSES.INDEX), { + params, + }); + } + + getCurrentUserResponses(questId: number | string): Observable { + const params = new HttpParams().set('quest_id', questId); + return this.http.get( + this.baseApiService.getRoute(API_ROUTES.QUEST_USER_RESPONSES.CURRENT_USER_RESPONSES), + { + params, + }, + ); + } + + create_quest_task_user_response(taskId: number, questUserResponseId: number) { + const params = new HttpParams().set('task_id', taskId).set('quest_user_response_id', questUserResponseId); + return this.http.post( + this.baseApiService.getRoute(API_ROUTES.QUEST_USER_RESPONSES.CREATE_QUEST_TASK_USER_RESPONSE), + params, + ); + } + + // PUBLIC API + publicIndex(questId: number | string): Observable { + const params = new HttpParams().set('quest_id', questId); + return this.http.get( + this.baseApiService.getRoute(API_ROUTES.QUEST_USER_RESPONSES.PUBLIC.INDEX), + { + params, + }, + ); + } +} From b0a832bb96c54872d108ecff9d166471705305ab Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Mon, 2 Dec 2024 14:15:26 +0530 Subject: [PATCH 24/30] feat: add quest on public community page --- .../home-community.component.html | 4 +++ .../home-community.component.ts | 3 +- .../public-community-quests.component.html | 9 +++++ .../public-community-quests.component.scss | 3 ++ .../public-community-quests.component.spec.ts | 27 +++++++++++++++ .../public-community-quests.component.ts | 33 +++++++++++++++++++ .../public-community-routing.module.ts | 5 +++ .../public-community.module.ts | 2 ++ libs/shared/services/src/lib/quest.service.ts | 15 +++++++-- 9 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 apps/commudle-admin/src/app/feature-modules/public-community/components/public-community-quests/public-community-quests.component.html create mode 100644 apps/commudle-admin/src/app/feature-modules/public-community/components/public-community-quests/public-community-quests.component.scss create mode 100644 apps/commudle-admin/src/app/feature-modules/public-community/components/public-community-quests/public-community-quests.component.spec.ts create mode 100644 apps/commudle-admin/src/app/feature-modules/public-community/components/public-community-quests/public-community-quests.component.ts diff --git a/apps/commudle-admin/src/app/feature-modules/public-community/components/home-community/home-community.component.html b/apps/commudle-admin/src/app/feature-modules/public-community/components/home-community/home-community.component.html index 52f17019b..fd0e0990e 100644 --- a/apps/commudle-admin/src/app/feature-modules/public-community/components/home-community/home-community.component.html +++ b/apps/commudle-admin/src/app/feature-modules/public-community/components/home-community/home-community.component.html @@ -232,6 +232,10 @@

{{ community.name }}

/> Hackathons + + + Quest +

{{ quest.name }}

diff --git a/apps/shared-components/quest-card/quest-card.component.scss b/apps/shared-components/quest-card/quest-card.component.scss index 541bf4ace..535d1833f 100644 --- a/apps/shared-components/quest-card/quest-card.component.scss +++ b/apps/shared-components/quest-card/quest-card.component.scss @@ -1,7 +1,7 @@ a { @apply com-no-underline; nb-card { - @apply hover:com-shadow-md; + @apply hover:com-shadow-md com-m-0; nb-card-header { @apply com-p-0 com-overflow-hidden com-h-full com-border-0; img { From 41a2bfde21729bc3c01c2ed6159fd449e54198cc Mon Sep 17 00:00:00 2001 From: Arshdeep Singh Date: Wed, 4 Dec 2024 17:23:27 +0530 Subject: [PATCH 30/30] refactor: update instagram client_id --- .../services/src/lib/external-user-auth-handler.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/shared/services/src/lib/external-user-auth-handler.service.ts b/libs/shared/services/src/lib/external-user-auth-handler.service.ts index 0b1b0f34b..ac685fab8 100644 --- a/libs/shared/services/src/lib/external-user-auth-handler.service.ts +++ b/libs/shared/services/src/lib/external-user-auth-handler.service.ts @@ -24,8 +24,8 @@ export class ExternalUserAuthHandlerService { } loginToInstagram() { - const YOUR_INSTAGRAM_CLIENT_ID = '989280999691182'; - const redirectUrl = 'https://www.commudle.com/'; + const YOUR_INSTAGRAM_CLIENT_ID = '1090108432225078'; + const redirectUrl = environment.app_url + '/auth/users/instagram/callback'; const state = { redirectTo: window.location.href, };