diff --git a/apps/commudle-admin/src/app/app-routing.module.ts b/apps/commudle-admin/src/app/app-routing.module.ts
index 8d26f8664a..b5c287e103 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: () =>
@@ -142,6 +146,11 @@ const routes: Routes = [
loadChildren: () =>
import('./feature-modules/public-hackathon/public-hackathon.module').then((m) => m.PublicHackathonModule),
},
+ {
+ path: 'communities/:community_id/quests/:quest_id',
+ loadChildren: () =>
+ import('./feature-modules/public-quests/public-quests.module').then((m) => m.PublicQuestsModule),
+ },
{
path: 'communities/:community_id/channels',
loadChildren: () =>
@@ -264,6 +273,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 861f5c68d7..c27c33fffe 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,8 @@ 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';
+import { QuestFormComponent } from 'apps/shared-components/quest-form/quest-form.component';
const routes = [
{
path: 'new',
@@ -136,6 +139,10 @@ const routes = [
path: 'team',
component: CommunityTeamComponent,
},
+ {
+ path: 'quests',
+ 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 265e2ccc5c..0c26d4a53f 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 e00b48cdd4..274d546a9b 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,8 +159,12 @@
{{ community.name }}
Members
+
+
+ Quests
+
-
+
Forms
diff --git a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.ts b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.ts
index b93647993e..fd4a184a36 100644
--- a/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.ts
+++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-control-panel/community-control-panel.component.ts
@@ -7,7 +7,7 @@ import { ICommunity } from 'apps/shared-models/community.model';
import { EemailTypes } from 'apps/shared-models/enums/email_types.enum';
import { SeoService } from 'apps/shared-services/seo.service';
import { Subscription } from 'rxjs';
-import { faScroll } from '@fortawesome/free-solid-svg-icons';
+import { faScroll, faShapes } from '@fortawesome/free-solid-svg-icons';
import { NotificationsStore } from 'apps/commudle-admin/src/app/feature-modules/notifications/store/notifications.store';
import { GoogleTagManagerService } from 'apps/commudle-admin/src/app/services/google-tag-manager.service';
import { ENotificationSenderTypes } from 'apps/shared-models/enums/notification_sender_types.enum';
@@ -27,7 +27,6 @@ export class CommunityControlPanelComponent implements OnInit, OnDestroy {
notificationCount = 0;
ENotificationSenderTypes = ENotificationSenderTypes;
- faScroll = faScroll;
subscriptions: Subscription[] = [];
icons = {
@@ -35,6 +34,8 @@ export class CommunityControlPanelComponent implements OnInit, OnDestroy {
faFileLines,
faNewspaper,
faMessage,
+ faShapes,
+ faScroll,
};
environment = environment;
darkMode: boolean;
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 0000000000..3afc6ce7b7
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.html
@@ -0,0 +1,57 @@
+
+
+
+
+ 0">
+
+ Name |
+ Creation date |
+ Dates |
+ No of tasks |
+ No of participants |
+ Actions |
+
+
+ {{ 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') }}
+
+
+ No Date selected yet!
+
+ |
+ {{ quest.tasks_count }} |
+ {{ quest.participants_count }} |
+
+
+ |
+
+
+
+
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 0000000000..f2e51c368c
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.scss
@@ -0,0 +1,24 @@
+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;
+ }
+ }
+
+ .pagination {
+ @apply com-mt-4;
+ }
+}
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 0000000000..a9d8287f54
--- /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 0000000000..a391e1432f
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/community-control-panel/components/community-quest/community-quest.component.ts
@@ -0,0 +1,49 @@
+import { Component, OnInit } from '@angular/core';
+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',
+ templateUrl: './community-quest.component.html',
+ styleUrls: ['./community-quest.component.scss'],
+})
+export class CommunityQuestComponent implements OnInit {
+ communityId: number | string;
+ quests: IQuest[];
+ moment = moment;
+ page = 1;
+ total = 0;
+ count = 10;
+ icons = {
+ faPlus,
+ faArrowUpRightFromSquare,
+ };
+
+ constructor(
+ private externalUserAuthHandlerService: ExternalUserAuthHandlerService,
+ private questService: QuestService,
+ private activatedRoute: ActivatedRoute,
+ ) {}
+
+ ngOnInit() {
+ this.activatedRoute.parent.params.subscribe((params) => {
+ this.communityId = params.community_id;
+ this.getQuests();
+ });
+ }
+
+ loginToDiscord() {
+ this.externalUserAuthHandlerService.loginToDiscord();
+ }
+
+ getQuests() {
+ 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/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 52f17019b0..fd0e0990e2 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Basic Information
+ Add basic information such as title, description, rewards
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 0000000000..97231b76f2
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/components/quest-control-panel-tasks/quest-control-panel-tasks.component.scss
@@ -0,0 +1,80 @@
+.heading-container {
+ .heading {
+ @apply com-text-base com-font-semibold com-text-gray-800;
+ }
+ .sub-heading {
+ @apply com-text-sm com-font-medium com-text-gray-400;
+ }
+}
+
+.social-media-cards {
+ @apply com-grid com-grid-cols-3 com-gap-6 com-mt-4;
+ .social-media-card {
+ @apply com-p-4 com-h-32 com-border com-border-solid com-border-gray-200 com-rounded-xl com-cursor-pointer hover:com-shadow;
+ .logo-title {
+ @apply com-flex com-gap-3 com-items-center;
+ .logo {
+ @apply com-h-6;
+ img {
+ @apply com-h-full;
+ }
+ }
+ .title {
+ @apply com-text-Yankees-Blue com-text-base com-font-semibold;
+ }
+ }
+ .description {
+ @apply com-text-xs com-font-normal com-my-3 com-text-gray-800;
+ }
+ }
+}
+
+.tasks {
+ @apply com-grid com-grid-cols-1 md:com-grid-cols-3;
+}
+
+.task-form {
+ @apply com-w-full md:com-w-[40dvw] com-max-h-[90dvh];
+ nb-card-header,
+ nb-card-footer {
+ @apply com-flex com-justify-between com-items-center;
+ }
+
+ .platform-container {
+ @apply com-flex com-gap-3 com-items-center com-bg-primary-100 com-w-full com-rounded-xl com-p-4;
+ p {
+ @apply com-text-base com-font-semibold com-text-primary-600 com-m-0;
+ }
+ img {
+ @apply com-h-6;
+ }
+ }
+ form {
+ .required {
+ @apply com-text-red-500;
+ }
+ nb-accordion {
+ @apply com-my-4 com-shadow-none com-border com-border-solid com-border-Bright-Gray com-rounded-xl;
+ nb-accordion-item {
+ @apply com-rounded-xl;
+ nb-accordion-item-header {
+ @apply com-flex-col com-items-start;
+ .heading {
+ @apply com-text-sm com-font-semibold com-inline-block;
+ }
+
+ .sub-heading {
+ @apply com-text-sm com-font-normal;
+ }
+ }
+ }
+ }
+
+ .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/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 0000000000..ac69648cd3
--- /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 0000000000..88b44f81c9
--- /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,99 @@
+import { Component, OnInit, TemplateRef } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { ActivatedRoute } from '@angular/router';
+import { IQuest, IQuestTaskType, ITask } from '@commudle/shared-models';
+import { TaskService } from '@commudle/shared-services';
+import { NbDialogService } from '@commudle/theme';
+
+@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 {
+ questTaskType: IQuestTaskType[];
+ taskForm: FormGroup;
+ selectedTaskType: IQuestTaskType;
+ quest: IQuest;
+ tasks: ITask[];
+
+ constructor(
+ private taskService: TaskService,
+ private dialogService: NbDialogService,
+ private fb: FormBuilder,
+ private activatedRoute: ActivatedRoute,
+ ) {
+ this.taskForm = this.fb.group({
+ name: ['', Validators.required],
+ description: ['', Validators.required],
+ url: ['', Validators.required],
+ reward_points: [0, [Validators.required, Validators.min(1)]],
+ other_rewards: [''],
+ quest_task_type_id: [0, [Validators.required, Validators.min(1)]],
+ });
+ }
+
+ ngOnInit() {
+ this.activatedRoute.parent.data.subscribe((data: { quest: IQuest }) => {
+ this.quest = data.quest;
+ this.getTasks();
+ });
+ this.getTaskTypesIndex();
+ }
+
+ getTasks() {
+ this.taskService.index(this.quest.id).subscribe((res) => {
+ this.tasks = res;
+ });
+ }
+
+ getTaskTypesIndex() {
+ this.taskService.getTaskTypesIndex().subscribe((res) => {
+ this.questTaskType = res;
+ });
+ }
+
+ openDialogBox(dialog: TemplateRef, taskType: IQuestTaskType, task?: ITask, index?: number) {
+ if (taskType) {
+ this.selectedTaskType = taskType;
+ }
+ if (task) {
+ this.taskForm.patchValue({
+ name: task.name,
+ description: task.description,
+ url: task.url,
+ 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: {
+ taskType: taskType,
+ task: task,
+ index: index,
+ },
+ });
+ }
+
+ 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);
+ });
+ }
+
+ updateTask() {}
+}
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 0000000000..3dee83b0dc
--- /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 @@
+
+
+
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 0000000000..f04e83ed48
--- /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 0000000000..3830dad70d
--- /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 0000000000..90857e9a8b
--- /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 0000000000..464f78bbfd
--- /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 0000000000..e69de29bb2
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 0000000000..524f1b522a
--- /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 0000000000..ac6909f052
--- /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
new file mode 100644
index 0000000000..25ecb26617
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.module.ts
@@ -0,0 +1,44 @@
+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 './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';
+import { NbButtonModule, NbCardModule, NbIconModule, NbAccordionModule, NbInputModule } from '@commudle/theme';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { SharedPipesModule } from 'apps/shared-pipes/pipes.module';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ QuestsControlPanelRoutes,
+ SharedComponentsModule,
+ FontAwesomeModule,
+ FormsModule,
+ ReactiveFormsModule,
+ SharedPipesModule,
+
+ // standalone
+ SidebarComponent,
+
+ // Nebular
+ NbCardModule,
+ NbIconModule,
+ NbButtonModule,
+ NbAccordionModule,
+ NbInputModule,
+ ],
+ 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
new file mode 100644
index 0000000000..abcb1a8921
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/quests-control-panel/quests-control-panel.routing.ts
@@ -0,0 +1,35 @@
+import { Routes, RouterModule } from '@angular/router';
+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 0000000000..653d1feec0
--- /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/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 43f57c09d9..6b4e36b60c 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 6a1b044668..5797a4f19f 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 0ed12d86ab..4994389c27 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/community-controls.component.html b/apps/commudle-admin/src/app/feature-modules/sys-admin/components/community-controls/community-controls.component.html
index 89427f2c42..ad6b39c07d 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
new file mode 100644
index 0000000000..455dd92ee4
--- /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,143 @@
+
+
+
+
+
+ List of Quest Task types platform
+
+
+
+ Logo |
+ Platform Name |
+ Description |
+ Platform Types |
+ Actions |
+
+
+ |
+ {{ 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 0000000000..5c12acdae4
--- /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;
+}
+.edit-create-task-types {
+ @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 0000000000..3e1b6a12a0
--- /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 0000000000..6f52cf9bab
--- /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 4ca2278de4..02bb415452 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 04450cc08c..32f07dab37 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 422f1f5461..bea1998754 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/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 0000000000..1767f5c33c
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.html
@@ -0,0 +1,8 @@
+
+
+
+
+
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 0000000000..9ebeb1b170
--- /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 0000000000..590fdc8f82
--- /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 0000000000..976f9e3634
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/discord/discord.component.ts
@@ -0,0 +1,30 @@
+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-discord',
+ templateUrl: './discord.component.html',
+ styleUrls: ['./discord.component.scss'],
+})
+export class DiscordComponent 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));
+ const baseUrl = state.redirectTo;
+ this.redirectTo = `${baseUrl}?task_id=${state.task_id}`;
+ 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 0000000000..981c0eb634
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/instagram/instagram.component.html
@@ -0,0 +1,8 @@
+
+
+
+
+
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 0000000000..9ebeb1b170
--- /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 0000000000..dc5af66ca4
--- /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 0000000000..9fa713124f
--- /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 0000000000..4db73de8c3
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/components/telegram/telegram.component.html
@@ -0,0 +1,8 @@
+
+
+
+
+
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 0000000000..9ebeb1b170
--- /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 0000000000..6d860fe62b
--- /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 0000000000..276a5f6dcb
--- /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
new file mode 100644
index 0000000000..8a2796c808
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.module.ts
@@ -0,0 +1,13 @@
+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';
+import { InstagramComponent } from './components/instagram/instagram.component';
+import { TelegramComponent } from './components/telegram/telegram.component';
+
+@NgModule({
+ imports: [CommonModule, UserOauthRoutes, SharedComponentsModule],
+ 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
new file mode 100644
index 0000000000..1e5fb2ade6
--- /dev/null
+++ b/apps/commudle-admin/src/app/feature-modules/user-oauth/user-oauth.routing.ts
@@ -0,0 +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/app/services/communities.service.ts b/apps/commudle-admin/src/app/services/communities.service.ts
index a7798ceb01..38ef49a297 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/commudle-admin/src/assets/static-assets.ts b/apps/commudle-admin/src/assets/static-assets.ts
index 81ae1ef5d7..0a4a3aa488 100644
--- a/apps/commudle-admin/src/assets/static-assets.ts
+++ b/apps/commudle-admin/src/assets/static-assets.ts
@@ -178,4 +178,24 @@ 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',
+
+ // 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',
+
+ // id: 169
+ quest_empty_state:
+ 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBM3RuQXc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--df86d3126a9f218dec017a1934acfd49a1e4dc56/Group%201.png',
+
+ // id: 170
+ quest_task_rewards:
+ 'https://json.commudle.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBMjluQXc9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--2297c1f6dafa2e70379940b391f20fbae9c982ba/RANK%20BADGES.svg',
};
diff --git a/apps/shared-components/quest-card/quest-card.component.html b/apps/shared-components/quest-card/quest-card.component.html
new file mode 100644
index 0000000000..ea1c673c64
--- /dev/null
+++ b/apps/shared-components/quest-card/quest-card.component.html
@@ -0,0 +1,16 @@
+
+
+
+
+ {{ quest.name }}
+ 0" class="reward-points">
+
{{
+ quest.total_rewards_points
+ }}
+ Reward Points
+
+
+
+
diff --git a/apps/shared-components/quest-card/quest-card.component.scss b/apps/shared-components/quest-card/quest-card.component.scss
new file mode 100644
index 0000000000..535d1833f9
--- /dev/null
+++ b/apps/shared-components/quest-card/quest-card.component.scss
@@ -0,0 +1,23 @@
+a {
+ @apply com-no-underline;
+ nb-card {
+ @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 {
+ @apply com-w-full;
+ }
+ }
+
+ nb-card-body {
+ @apply com-min-h-[134px];
+ .title {
+ @apply com-font-medium com-text-lg com-line-clamp-2 com-my-0 com-h-14;
+ }
+
+ .reward-points {
+ @apply com-flex com-gap-2 com-items-center com-border com-border-solid com-border-Bright-Gray com-rounded-3xl com-text-orange-700 com-py-1 com-px-3 com-w-max com-mt-4;
+ }
+ }
+ }
+}
diff --git a/apps/shared-components/quest-card/quest-card.component.spec.ts b/apps/shared-components/quest-card/quest-card.component.spec.ts
new file mode 100644
index 0000000000..b9416c9c44
--- /dev/null
+++ b/apps/shared-components/quest-card/quest-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 { QuestCardComponent } from './quest-card.component';
+
+describe('QuestCardComponent', () => {
+ let component: QuestCardComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [QuestCardComponent],
+ }).compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(QuestCardComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/apps/shared-components/quest-card/quest-card.component.ts b/apps/shared-components/quest-card/quest-card.component.ts
new file mode 100644
index 0000000000..1a7654c9c4
--- /dev/null
+++ b/apps/shared-components/quest-card/quest-card.component.ts
@@ -0,0 +1,17 @@
+import { Component, OnInit, Input } from '@angular/core';
+import { IQuest } from '@commudle/shared-models';
+import { staticAssets } from 'apps/commudle-admin/src/assets/static-assets';
+
+@Component({
+ selector: 'commudle-quest-card',
+ templateUrl: './quest-card.component.html',
+ styleUrls: ['./quest-card.component.scss'],
+})
+export class QuestCardComponent implements OnInit {
+ @Input() quest: IQuest;
+ staticAssets = staticAssets;
+
+ constructor() {}
+
+ ngOnInit() {}
+}
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 0000000000..0d29bc5970
--- /dev/null
+++ b/apps/shared-components/quest-form/quest-form.component.html
@@ -0,0 +1,70 @@
+
+ {{ quest ? 'Edit quest' : '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 0000000000..ed9dcf2104
--- /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 0000000000..63adfdbe55
--- /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 0000000000..6d5890ed83
--- /dev/null
+++ b/apps/shared-components/quest-form/quest-form.component.ts
@@ -0,0 +1,136 @@
+import { DatePipe } from '@angular/common';
+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, ToastrService } 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';
+ @Input() quest: IQuest;
+ parentId = '';
+ parentType: EDbModels;
+ EQuestVisibility = EQuestVisibility;
+ questForm: FormGroup;
+ isLoading = false;
+
+ 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 datePipe: DatePipe,
+ private toastService: ToastrService,
+ ) {
+ this.questForm = this.fb.group({
+ name: ['', Validators.required],
+ description: ['', Validators.required],
+ start_date: [''],
+ end_date: [''],
+ visibility: ['', Validators.required],
+ });
+ }
+
+ ngOnInit() {
+ if (this.quest) {
+ this.fetchQuestDetails();
+ }
+ 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;
+ }
+ });
+ }
+
+ createOrUpdateQuest() {
+ if (this.quest) {
+ this.updateQuest();
+ } else {
+ this.createQuest();
+ }
+ }
+
+ createQuest() {
+ this.isLoading = true;
+ this.questService.create(this.questForm.value, this.parentType, this.parentId).subscribe(
+ (quest: IQuest) => {
+ this.isLoading = false;
+ if (quest) {
+ this.toastService.successDialog('Quest created successfully');
+ }
+ },
+ () => {
+ this.isLoading = false;
+ },
+ );
+ }
+ updateQuest() {
+ this.isLoading = true;
+ this.questService.update(this.quest.id, this.questForm.value).subscribe(
+ (quest: IQuest) => {
+ this.isLoading = false;
+ if (quest) {
+ this.toastService.successDialog('Quest updated successfully');
+ }
+ },
+ () => {
+ this.isLoading = false;
+ },
+ );
+ }
+
+ fetchQuestDetails() {
+ 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/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 0000000000..d9304ea3e4
--- /dev/null
+++ b/apps/shared-components/quest-task-card/quest-task-card.component.html
@@ -0,0 +1,86 @@
+
+
+
+
+
{{ task.name }}
+
+ {{ task.description }}
+
+
+
{{ task.reward_points }} Reward Points
+
+
+
+
+ Completed
+
+
+
+
+
+
+
+
+ {{ data.name }}
+
+
+
+
+
Connect your account
+
+ Connect your {{ data.quest_task_type.platform_name | titlecase }} account to access the community server
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ data.quest_task_type.platform_type | capitalizeAndRemoveUnderscore }} on
+ {{ data.quest_task_type.platform_name | titlecase }}
+
+
+
+
+
+
+ Verify on Commudle
+
+
+
+
+
+
+
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 0000000000..caee264581
--- /dev/null
+++ b/apps/shared-components/quest-task-card/quest-task-card.component.scss
@@ -0,0 +1,78 @@
+.task {
+ @apply com-cursor-pointer hover:com-shadow;
+ .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-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;
+ }
+
+ .task-completed {
+ @apply com-flex com-items-center com-justify-center com-gap-2 com-w-full com-border com-border-solid com-border-green-600 com-bg-green-50 com-text-green-600 com-rounded-lg com-py-1;
+ span {
+ @apply com-text-sm com-font-bold;
+ }
+ }
+
+ &.admin-properties {
+ @apply com-cursor-text com-pointer-events-none hover:com-shadow-none;
+ }
+}
+
+.discord-dialog {
+ @apply com-w-full md:com-w-[400px];
+ nb-card-header,
+ nb-card-footer {
+ @apply com-flex com-justify-between com-items-center;
+ }
+
+ .step-one {
+ @apply com-flex com-flex-col com-items-center;
+ .title {
+ @apply com-text-Yankees-Blue com-font-semibold com-text-base com-my-0;
+ }
+ .sub-title {
+ @apply com-text-sm com-text-gray-500 com-text-center com-mt-2 com-mb-5;
+ }
+ }
+
+ .step-two {
+ @apply com-flex com-flex-col com-items-center;
+ .lock-icon {
+ @apply com-h-12 com-w-12 com-border com-border-solid com-border-Bright-Gray com-rounded-lg com-flex com-justify-center com-items-center com-mb-2;
+ fa-icon {
+ @apply com-text-3xl;
+ }
+ }
+ .title {
+ @apply com-text-Yankees-Blue com-font-semibold com-text-base com-my-0;
+ }
+ .sub-title {
+ @apply com-text-sm com-text-gray-500 com-text-center com-mt-2;
+ }
+ .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 com-mb-5;
+ select {
+ @apply com-bg-[#F6F9FC] hover:com-bg-[#eef2f7]/50 com-cursor-pointer com-border-0 com-w-full;
+ }
+ }
+ }
+
+ .step-three {
+ nb-card {
+ @apply com-mx-0 com-mt-0;
+ .title {
+ @apply com-font-bold com-text-sm com-mb-3 com-mt-0;
+ }
+ }
+ }
+}
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 0000000000..f7b2449ac0
--- /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 0000000000..80bb5d0e9c
--- /dev/null
+++ b/apps/shared-components/quest-task-card/quest-task-card.component.ts
@@ -0,0 +1,169 @@
+import { Component, EventEmitter, Input, OnInit, Output, TemplateRef, ViewChild } from '@angular/core';
+import {
+ EExternalUserAuth,
+ IExternalUserAuth,
+ ITask,
+ ERewardPointsColors,
+ ERewardPointsLogo,
+ IQuestUserResponse,
+ IQuestTaskUserResponse,
+} from '@commudle/shared-models';
+import {
+ ExternalUserAuthHandlerService,
+ ExternalUserAuthService,
+ TaskService,
+ ToastrService,
+ QuestUserResponsesService,
+} from '@commudle/shared-services';
+import { NbDialogRef, NbDialogService } from '@commudle/theme';
+import { faCircleCheck, faLock } from '@fortawesome/free-solid-svg-icons';
+
+@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;
+ @Input() questUserResponse: IQuestUserResponse;
+ @Output() updateUserResponse = new EventEmitter();
+
+ userAuthTokens: IExternalUserAuth[];
+ selectedExternalUserAuth: IExternalUserAuth;
+ stepOne = true;
+ stepTwo = false;
+ stepThree = false;
+ ERewardPointsColors = ERewardPointsColors;
+ ERewardPointsLogo = ERewardPointsLogo;
+ icons = {
+ faLock,
+ faCircleCheck,
+ };
+ dialogRef: NbDialogRef;
+ isVerifying = false;
+ @ViewChild('discordDialog') discordDialogBox: TemplateRef;
+
+ constructor(
+ private dialogBoxService: NbDialogService,
+ private externalUserAuthHandlerService: ExternalUserAuthHandlerService,
+ private externalUserAuthService: ExternalUserAuthService,
+ private taskService: TaskService,
+ private toasterService: ToastrService,
+ private questUserResponsesService: QuestUserResponsesService,
+ ) {}
+
+ ngOnInit() {}
+
+ openTaskPopup(task) {
+ if (this.questUserResponse) {
+ const taskResponseExist = this.questUserResponse.task_responses.find(
+ (userTaskResponse) => userTaskResponse.task_id === task.id,
+ );
+ if (!taskResponseExist) {
+ this.createQuestTaskUserResponse(this.questUserResponse.id);
+ }
+ } else {
+ this.createQuestUserResponse();
+ }
+ this.stepOne = true;
+ this.stepTwo = false;
+ this.stepThree = false;
+
+ switch (task.quest_task_type.platform_name) {
+ case EExternalUserAuth.DISCORD:
+ this.getExternalUsers(EExternalUserAuth.DISCORD);
+ this.dialogRef = this.dialogBoxService.open(this.discordDialogBox, { context: task });
+ return;
+ case EExternalUserAuth.INSTAGRAM:
+ this.getExternalUsers(EExternalUserAuth.INSTAGRAM);
+ this.dialogRef = this.dialogBoxService.open(this.discordDialogBox, { context: task });
+ return;
+ case EExternalUserAuth.TELEGRAM:
+ this.getExternalUsers(EExternalUserAuth.TELEGRAM);
+ this.dialogRef = 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.selectedExternalUserAuth = this.userAuthTokens[0];
+ }
+ });
+ }
+
+ selectUserAuthToken(event) {
+ const selected = this.userAuthTokens.find((token) => token.id === event.target.value);
+ this.selectedExternalUserAuth = selected;
+ }
+
+ loginAccount() {
+ switch (this.task.quest_task_type.platform_name) {
+ case EExternalUserAuth.DISCORD:
+ this.externalUserAuthHandlerService.loginToDiscord(this.task.id);
+ return;
+ case EExternalUserAuth.INSTAGRAM:
+ this.externalUserAuthHandlerService.loginToInstagram();
+ return;
+ case EExternalUserAuth.TELEGRAM:
+ this.externalUserAuthHandlerService.loginToTelegram();
+ return;
+ }
+ }
+
+ verifyDiscordServer() {
+ this.isVerifying = true;
+ this.taskService.verifyDiscord(this.task.id, this.selectedExternalUserAuth.id).subscribe((res) => {
+ if (res) {
+ setTimeout(() => {
+ const index = this.questUserResponse.task_responses.findIndex(
+ (userTaskResponse) => userTaskResponse.task_id === this.task.id,
+ );
+ this.questUserResponsesService
+ .questTaskUserResponseMarkedCompleted(this.questUserResponse.task_responses[index].id)
+ .subscribe((data) => {
+ this.questUserResponse.task_responses[index] = data;
+ this.updateUserResponse.emit(true);
+ });
+ this.toasterService.successDialog('Verified!, You have completed this task');
+ this.dialogRef.close();
+ this.isVerifying = false;
+ }, 1000);
+ } else {
+ this.isVerifying = false;
+ this.toasterService.warningDialog('Not Verified');
+ }
+ });
+ }
+
+ createQuestUserResponse() {
+ this.questUserResponsesService.create(this.task.quest_id).subscribe((data) => {
+ this.questUserResponse = data;
+ this.createQuestTaskUserResponse(data.id);
+ });
+ }
+
+ createQuestTaskUserResponse(questUserResponseId) {
+ this.questUserResponsesService
+ .create_quest_task_user_response(this.task.id, questUserResponseId)
+ .subscribe((res) => {
+ this.questUserResponse.task_responses.unshift(res);
+ });
+ }
+
+ taskCompleted(): boolean {
+ if (!this.questUserResponse || !this.questUserResponse.task_responses) {
+ return false;
+ }
+
+ return this.questUserResponse.task_responses.some(
+ (taskResponse: { completed: boolean; task_id: number }) =>
+ taskResponse.completed === true && taskResponse.task_id === this.task.id,
+ );
+ }
+}
diff --git a/apps/shared-components/shared-components.module.ts b/apps/shared-components/shared-components.module.ts
index 13dc46ba7e..b06231fbaa 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';
@@ -91,7 +92,9 @@ 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';
+import { QuestTaskCardComponent } from './quest-task-card/quest-task-card.component';
+import { QuestCardComponent } from './quest-card/quest-card.component';
@NgModule({
declarations: [
WorkInProgressComponent,
@@ -145,6 +148,9 @@ import { NewsletterCardComponent } from './newsletter-card/newsletter-card.compo
UserDetailsCheckboxFormComponent,
UserDetailsFormComponent,
NewsletterCardComponent,
+ QuestFormComponent,
+ QuestTaskCardComponent,
+ QuestCardComponent,
],
imports: [
CommonModule,
@@ -188,6 +194,7 @@ import { NewsletterCardComponent } from './newsletter-card/newsletter-card.compo
NbToggleModule,
NbContextMenuModule,
NbSpinnerModule,
+ NbDialogModule,
//cdk
DragDropModule,
@@ -236,6 +243,9 @@ import { NewsletterCardComponent } from './newsletter-card/newsletter-card.compo
UserDetailsCheckboxFormComponent,
UserDetailsFormComponent,
NewsletterCardComponent,
+ QuestFormComponent,
+ QuestTaskCardComponent,
+ QuestCardComponent,
],
providers: [{ provide: TINYMCE_SCRIPT_SRC, useValue: 'tinymce/tinymce.min.js' }],
})
diff --git a/libs/shared/environments/src/lib/environments.ts b/libs/shared/environments/src/lib/environments.ts
index 8a0e33f84b..0c3a7216f3 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/index.ts b/libs/shared/models/src/index.ts
index 33ae60fb91..cc9ce7ce75 100644
--- a/libs/shared/models/src/index.ts
+++ b/libs/shared/models/src/index.ts
@@ -40,3 +40,9 @@ 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';
+export * from './lib/quest.model';
+export * from './lib/task.model';
+export * from './lib/quest-task-type.model';
+export * from './lib/quest-user-response.model';
+export * from './lib/quest-task-user-response.model';
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 0000000000..f2d7b90256
--- /dev/null
+++ b/libs/shared/models/src/lib/external-user-auth.model.ts
@@ -0,0 +1,19 @@
+export interface IExternalUserAuth {
+ id: number;
+ platform: EExternalUserAuth;
+ token: string;
+ active: boolean;
+ data: Date;
+ username: string;
+}
+
+export enum EExternalUserAuth {
+ DISCORD = 'discord',
+ TWITTER = 'twitter',
+ INSTAGRAM = 'instagram',
+ FACEBOOK = 'facebook',
+ LINKEDIN = 'linkedin',
+ TELEGRAM = 'telegram',
+ YOUTUBE = 'youtube',
+ GITHUB = 'github',
+}
diff --git a/libs/shared/models/src/lib/quest-task-type.model.ts b/libs/shared/models/src/lib/quest-task-type.model.ts
new file mode 100644
index 0000000000..acc7ea3fab
--- /dev/null
+++ b/libs/shared/models/src/lib/quest-task-type.model.ts
@@ -0,0 +1,13 @@
+export interface IQuestTaskType {
+ id: number;
+ platform_name: string;
+ logo_url: string;
+ description: string;
+ platform_type: string;
+ platform_types: [
+ {
+ id: number;
+ name: string;
+ },
+ ];
+}
diff --git a/libs/shared/models/src/lib/quest-task-user-response.model.ts b/libs/shared/models/src/lib/quest-task-user-response.model.ts
new file mode 100644
index 0000000000..2ccf61130d
--- /dev/null
+++ b/libs/shared/models/src/lib/quest-task-user-response.model.ts
@@ -0,0 +1,7 @@
+export interface IQuestTaskUserResponse {
+ id: number;
+ completed: boolean;
+ task_id: number;
+ quest_user_response_id: number;
+ user_id: number;
+}
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 0000000000..3d1104fe66
--- /dev/null
+++ b/libs/shared/models/src/lib/quest-user-response.model.ts
@@ -0,0 +1,11 @@
+import { IUser } from './user.model';
+import { IQuestTaskUserResponse } from './quest-task-user-response.model';
+
+export interface IQuestUserResponse {
+ id: number;
+ completed_task_count: number;
+ reward_points_earned: number;
+ task_responses: IQuestTaskUserResponse[];
+ user: IUser;
+ last_task_time: Date;
+}
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 0000000000..0849f49b7e
--- /dev/null
+++ b/libs/shared/models/src/lib/quest.model.ts
@@ -0,0 +1,23 @@
+import { ICommunity } from './community.model';
+
+export interface IQuest {
+ id: number;
+ name: string;
+ description: string;
+ start_date: Date;
+ end_date: Date;
+ visibility: EQuestVisibility;
+ created_at: Date;
+ slug: string;
+ tasks_count: number;
+ participants_count: number;
+ community: ICommunity;
+ is_active: boolean;
+ total_rewards_points: number;
+}
+
+export enum EQuestVisibility {
+ PUBLIC = 'is_public',
+ PRIVATE = 'is_private',
+ DRAFT = 'is_draft',
+}
diff --git a/libs/shared/models/src/lib/task.model.ts b/libs/shared/models/src/lib/task.model.ts
new file mode 100644
index 0000000000..6bfe1a429c
--- /dev/null
+++ b/libs/shared/models/src/lib/task.model.ts
@@ -0,0 +1,28 @@
+import { IQuestTaskType } from './quest-task-type.model';
+
+export interface ITask {
+ id: number;
+ name: string;
+ description: string;
+ reward_points: number;
+ other_rewards: string;
+ url: string;
+ quest_task_type: IQuestTaskType;
+ quest_id: number;
+}
+
+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/index.ts b/libs/shared/services/src/index.ts
index f3d1757834..bd7859e489 100644
--- a/libs/shared/services/src/index.ts
+++ b/libs/shared/services/src/index.ts
@@ -22,3 +22,8 @@ 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';
+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 787c2e01c1..54ed773127 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',
@@ -951,4 +953,51 @@ 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
+ INDEX: 'api/v2/external_user_auth', //GET
+ },
+
+ 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/quests/public', //GET
+ SHOW: 'api/v2/quests/public/show', //GET
+ },
+ },
+
+ TASKS: {
+ CREATE: 'api/v2/tasks', //POST
+ INDEX: 'api/v2/tasks', //GET
+ 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
+ },
+ 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
+ },
+ },
+
+ 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
+ QUEST_TASK_USER_RESPONSE_MARKED_COMPLETED: 'api/v2/quest_user_responses/quest_task_user_response_marked_completed', //PUT
+ 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/external-user-auth-handler.service.ts b/libs/shared/services/src/lib/external-user-auth-handler.service.ts
new file mode 100644
index 0000000000..ac685fab81
--- /dev/null
+++ b/libs/shared/services/src/lib/external-user-auth-handler.service.ts
@@ -0,0 +1,59 @@
+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',
+})
+export class ExternalUserAuthHandlerService {
+ constructor(private activatedRoute: ActivatedRoute, private externalUserAuthService: ExternalUserAuthService) {}
+
+ loginToDiscord(task_id?: number): void {
+ const state = {
+ redirectTo: window.location.href,
+ };
+ const redirectUrl = environment.app_url + '/auth/users/discord/callback';
+ if (task_id) {
+ state['task_id'] = task_id;
+ }
+ const encodedState = encodeURIComponent(JSON.stringify(state));
+ 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;
+ }
+
+ loginToInstagram() {
+ const YOUR_INSTAGRAM_CLIENT_ID = '1090108432225078';
+ const redirectUrl = environment.app_url + '/auth/users/instagram/callback';
+ 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(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: platformName,
+ };
+ this.externalUserAuthService.create(external_user_auth).subscribe();
+ }
+ });
+ }
+}
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 0000000000..5adb425c02
--- /dev/null
+++ b/libs/shared/services/src/lib/external-user-auth.service.ts
@@ -0,0 +1,32 @@
+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 { 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,
+ });
+ }
+
+ 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,
+ });
+ }
+
+ verifyDiscordServerMember(externalUserAuthTokenId: number, taskId: number): Observable {
+ const params = new HttpParams().set('external_user_auth_token_id', externalUserAuthTokenId).set('task_id', taskId);
+ return this.http.get(this.baseApiService.getRoute(API_ROUTES.EXTERNAL_USER_AUTH.CREATE), {
+ params,
+ });
+ }
+}
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 0000000000..c817443c52
--- /dev/null
+++ b/libs/shared/services/src/lib/quest-user-responses.service.ts
@@ -0,0 +1,65 @@
+/* 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 { IPaginationCount, IQuestTaskUserResponse, 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): Observable {
+ 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,
+ );
+ }
+
+ questTaskUserResponseMarkedCompleted(taskUserResponseId: number): Observable {
+ const params = new HttpParams().set('task_user_response_id', taskUserResponseId);
+ return this.http.put(
+ this.baseApiService.getRoute(API_ROUTES.QUEST_USER_RESPONSES.QUEST_TASK_USER_RESPONSE_MARKED_COMPLETED),
+ params,
+ );
+ }
+
+ // PUBLIC API
+ publicIndex(questId: number | string, page = 1, count = 10): Observable> {
+ const params = new HttpParams().set('quest_id', questId).set('page', page).set('count', count);
+ return this.http.get>(
+ this.baseApiService.getRoute(API_ROUTES.QUEST_USER_RESPONSES.PUBLIC.INDEX),
+ {
+ params,
+ },
+ );
+ }
+}
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 0000000000..16f378f4eb
--- /dev/null
+++ b/libs/shared/services/src/lib/quest.service.ts
@@ -0,0 +1,82 @@
+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, IPaginationCount, 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.QUESTS.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.QUESTS.UPDATE),
+ {
+ quest: data,
+ },
+ { params },
+ );
+ }
+
+ 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,
+ });
+ }
+
+ 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,
+ });
+ }
+
+ // PUBLIC API
+ publicIndex(
+ 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.PUBLIC.INDEX), {
+ params,
+ });
+ }
+
+ publicShow(questId: number): Observable {
+ const params = new HttpParams().set('quest_id', questId);
+ return this.http.get(this.baseApiService.getRoute(API_ROUTES.QUESTS.PUBLIC.SHOW), {
+ params,
+ });
+ }
+}
diff --git a/libs/shared/services/src/lib/task.service.ts b/libs/shared/services/src/lib/task.service.ts
new file mode 100644
index 0000000000..6f452512c4
--- /dev/null
+++ b/libs/shared/services/src/lib/task.service.ts
@@ -0,0 +1,80 @@
+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 { IQuestTaskType, ITask } from '@commudle/shared-models';
+@Injectable({
+ providedIn: 'root',
+})
+export class TaskService {
+ constructor(private http: HttpClient, private baseApiService: BaseApiService) {}
+
+ createTask(questId: number, formData): Observable {
+ const params = new HttpParams().set('quest_id', questId);
+ return this.http.post(
+ this.baseApiService.getRoute(API_ROUTES.TASKS.CREATE),
+ {
+ task: formData,
+ },
+ {
+ params,
+ },
+ );
+ }
+
+ index(questId: number): Observable {
+ const params = new HttpParams().set('quest_id', questId);
+ return this.http.get(this.baseApiService.getRoute(API_ROUTES.TASKS.INDEX), {
+ params,
+ });
+ }
+
+ getTaskTypesIndex(): Observable {
+ return this.http.get(this.baseApiService.getRoute(API_ROUTES.TASKS.TASK_TYPES_INDEX));
+ }
+
+ 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), {
+ 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,
+ },
+ );
+ }
+}