diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts
index 9e91b4e..64a8035 100644
--- a/src/app/app.routing.ts
+++ b/src/app/app.routing.ts
@@ -288,6 +288,18 @@ export const appRoutes: Route[] = [
},
],
},
+ {
+ path: 'settings',
+ children: [
+ {
+ path: 'basic',
+ loadChildren: () =>
+ import('app/modules/admin/settings/basic/basic.module').then(
+ (m: any) => m.BasicModule
+ ),
+ },
+ ],
+ },
],
},
];
diff --git a/src/app/mock-api/apps/settings/basic/api.ts b/src/app/mock-api/apps/settings/basic/api.ts
new file mode 100644
index 0000000..db372d9
--- /dev/null
+++ b/src/app/mock-api/apps/settings/basic/api.ts
@@ -0,0 +1,74 @@
+import { Injectable } from '@angular/core';
+import { assign, cloneDeep } from 'lodash-es';
+import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
+import { basicSetting as basicSettingData } from './data';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class BasicSettingMockApi {
+ private _basicSetting: any[] = basicSettingData;
+
+ /**
+ * Constructor
+ */
+ constructor(private _fuseMockApiService: FuseMockApiService) {
+ // Register Mock API handlers
+ this.registerHandlers();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Register Mock API handlers
+ */
+ registerHandlers(): void {
+ // -----------------------------------------------------------------------------------------------------
+ // @ BasicSetting - GET
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onGet('api/apps/settings/basic', 300)
+ .reply(({ request }) => {
+ // Clone the deposits
+ let basicSetting: any | null = cloneDeep(this._basicSetting);
+
+ // Return the response
+ return [
+ 200,
+ {
+ basicSetting,
+ },
+ ];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ BasicSetting - PATCH
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onPatch('api/apps/settings/basic')
+ .reply(({ request }) => {
+ // Get the id and deposit
+ const id = request.body.id;
+ const basicSetting = cloneDeep(request.body.basicSetting);
+
+ // Prepare the updated basicSetting
+ let updatedBasicSetting = null;
+
+ // Find the deposit and update it
+ // this._basicSetting.forEach((item, index, bs) => {
+ // if (item.id === id) {
+ // // Update the deposit
+ // basicSetting[index] = assign({}, basicSetting[index], deposit);
+
+ // // Store the updated deposit
+ // updatedDeposit = deposits[index];
+ // }
+ // });
+
+ // Return the response
+ return [200, basicSetting];
+ });
+ }
+}
diff --git a/src/app/mock-api/apps/settings/basic/data.ts b/src/app/mock-api/apps/settings/basic/data.ts
new file mode 100644
index 0000000..7ab80d1
--- /dev/null
+++ b/src/app/mock-api/apps/settings/basic/data.ts
@@ -0,0 +1,132 @@
+/* eslint-disable */
+
+import { SiteStatusType } from 'app/modules/admin/settings/basic/types/site-status.type';
+
+export const basicSetting = [
+ {
+ siteStatus: SiteStatusType.joinAvailable,
+ memo: '메모 테스트',
+ earnSettings: [
+ {
+ lv1: [
+ {
+ earnFirst: {
+ rate: '15',
+ isUse: true,
+ maxEarnMoney: '10000',
+ },
+ },
+ {
+ earnEvery: {
+ rate: '15',
+ isUse: true,
+ maxEarnMoney: '10000',
+ },
+ },
+ ],
+ },
+ {
+ lv2: [
+ {
+ earnFirst: {
+ rate: '15',
+ isUse: true,
+ maxEarnMoney: '10000',
+ },
+ },
+ {
+ earnEvery: {
+ rate: '15',
+ isUse: true,
+ maxEarnMoney: '10000',
+ },
+ },
+ ],
+ },
+ {
+ lv3: [
+ {
+ earnFirst: {
+ rate: '15',
+ isUse: true,
+ maxEarnMoney: '10000',
+ },
+ },
+ {
+ earnEvery: {
+ rate: '15',
+ isUse: true,
+ maxEarnMoney: '10000',
+ },
+ },
+ ],
+ },
+ {
+ lv4: [
+ {
+ earnFirst: {
+ rate: '15',
+ isUse: true,
+ maxEarnMoney: '10000',
+ },
+ },
+ {
+ earnEvery: {
+ rate: '15',
+ isUse: true,
+ maxEarnMoney: '10000',
+ },
+ },
+ ],
+ },
+ ],
+ gameSetting: [
+ {
+ name: '스포츠게임 가져오기',
+ isUse: true,
+ memo: '슬롯 사이트 메모',
+ description: '다른서버에서 경기가져오고 있음(5분)',
+ },
+ {
+ name: '스포츠게임 결과 가져오기',
+ isUse: false,
+ memo: '슬롯 사이트 메모',
+ description: '다른서버에서 경기결과 가져오고 있음(5분)',
+ },
+ {
+ name: '실시간게임 가져오기',
+ isUse: true,
+ memo: '슬롯 사이트 메모',
+ description: '하루한번 21시50분에 가져옴',
+ },
+ {
+ name: '실시간게임 결과처리/정산',
+ isUse: true,
+ memo: '슬롯 사이트 메모',
+ description: '5분 단위로 체크(4분35초, 40초, 54초, 50초, 55초 정각)',
+ },
+ {
+ name: '스포츠실시간 포인트 정산',
+ isUse: true,
+ memo: '슬롯 사이트 메모',
+ description: '10초마다 완료된 경기 포인트 정산',
+ },
+ {
+ name: '카지노 로그 가져오기',
+ isUse: true,
+ memo: '슬롯 사이트 메모',
+ description: '20초마다 마지막 로그 가져옴',
+ },
+ {
+ name: '카지노 포인트 정산',
+ isUse: true,
+ memo: '슬롯 사이트 메모',
+ description: '5분마다 정산내용 DB저장',
+ },
+ ],
+ },
+ // siteStatus?: SiteStatusType;
+ // memo?: string;
+ // earnSetting?: any;
+ // gameSetting?: any;
+];
diff --git a/src/app/mock-api/apps/settings/withdraw/api.ts b/src/app/mock-api/apps/settings/withdraw/api.ts
new file mode 100644
index 0000000..b328d3c
--- /dev/null
+++ b/src/app/mock-api/apps/settings/withdraw/api.ts
@@ -0,0 +1,212 @@
+import { Injectable } from '@angular/core';
+import { assign, cloneDeep } from 'lodash-es';
+import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
+import { withdraws as withdrawsData } from './data';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class BankWithdrawMockApi {
+ private _withdraws: any[] = withdrawsData;
+
+ /**
+ * Constructor
+ */
+ constructor(private _fuseMockApiService: FuseMockApiService) {
+ // Register Mock API handlers
+ this.registerHandlers();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Register Mock API handlers
+ */
+ registerHandlers(): void {
+ // -----------------------------------------------------------------------------------------------------
+ // @ Withdraws - GET
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onGet('api/apps/bank/withdraw/withdraws', 300)
+ .reply(({ request }) => {
+ // Get available queries
+ const search = request.params.get('search');
+ const sort = request.params.get('sort') || 'name';
+ const order = request.params.get('order') || 'asc';
+ const page = parseInt(request.params.get('page') ?? '1', 10);
+ const size = parseInt(request.params.get('size') ?? '10', 10);
+
+ // Clone the withdraws
+ let withdraws: any[] | null = cloneDeep(this._withdraws);
+
+ // Sort the withdraws
+ if (sort === 'sku' || sort === 'name' || sort === 'active') {
+ withdraws.sort((a, b) => {
+ const fieldA = a[sort].toString().toUpperCase();
+ const fieldB = b[sort].toString().toUpperCase();
+ return order === 'asc'
+ ? fieldA.localeCompare(fieldB)
+ : fieldB.localeCompare(fieldA);
+ });
+ } else {
+ withdraws.sort((a, b) =>
+ order === 'asc' ? a[sort] - b[sort] : b[sort] - a[sort]
+ );
+ }
+
+ // If search exists...
+ if (search) {
+ // Filter the withdraws
+ withdraws = withdraws.filter(
+ (contact: any) =>
+ contact.name &&
+ contact.name.toLowerCase().includes(search.toLowerCase())
+ );
+ }
+
+ // Paginate - Start
+ const withdrawsLength = withdraws.length;
+
+ // Calculate pagination details
+ const begin = page * size;
+ const end = Math.min(size * (page + 1), withdrawsLength);
+ const lastPage = Math.max(Math.ceil(withdrawsLength / size), 1);
+
+ // Prepare the pagination object
+ let pagination = {};
+
+ // If the requested page number is bigger than
+ // the last possible page number, return null for
+ // users but also send the last possible page so
+ // the app can navigate to there
+ if (page > lastPage) {
+ withdraws = null;
+ pagination = {
+ lastPage,
+ };
+ } else {
+ // Paginate the results by size
+ withdraws = withdraws.slice(begin, end);
+
+ // Prepare the pagination mock-api
+ pagination = {
+ length: withdrawsLength,
+ size: size,
+ page: page,
+ lastPage: lastPage,
+ startIndex: begin,
+ endIndex: end - 1,
+ };
+ }
+
+ // Return the response
+ return [
+ 200,
+ {
+ withdraws,
+ pagination,
+ },
+ ];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Withdraws - GET
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onGet('api/apps/bank/withdraw/withdraw')
+ .reply(({ request }) => {
+ // Get the id from the params
+ const id = request.params.get('id');
+
+ // Clone the users
+ const withdraws = cloneDeep(this._withdraws);
+
+ // Find the withdraw
+ const withdraw = withdraws.find((item: any) => item.id === id);
+
+ // Return the response
+ return [200, withdraw];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Withdraws - POST
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onPost('api/apps/bank/withdraw/withdraw')
+ .reply(() => {
+ // Generate a new withdraw
+ const newWithdraw = {
+ id: FuseMockApiUtils.guid(),
+ rank: '',
+ nickname: '',
+ exchangeApplication: '',
+ calculateType: '',
+ accountHolder: '',
+ note: '',
+ registrationDate: '',
+ processDate: '',
+ deposit: '',
+ withdrawal: '',
+ total: '',
+ highRank: '',
+ state: '',
+ };
+
+ // Unshift the new withdraw
+ this._withdraws.unshift(newWithdraw);
+
+ // Return the response
+ return [200, newWithdraw];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Withdraw - PATCH
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onPatch('api/apps/bank/withdraw/withdraw')
+ .reply(({ request }) => {
+ // Get the id and withdraw
+ const id = request.body.id;
+ const withdraw = cloneDeep(request.body.withdraw);
+
+ // Prepare the updated withdraw
+ let updatedWithdraw = null;
+
+ // Find the withdraw and update it
+ this._withdraws.forEach((item, index, withdraws) => {
+ if (item.id === id) {
+ // Update the withdraw
+ withdraws[index] = assign({}, withdraws[index], withdraw);
+
+ // Store the updated withdraw
+ updatedWithdraw = withdraws[index];
+ }
+ });
+
+ // Return the response
+ return [200, updatedWithdraw];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Withdraw - DELETE
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onDelete('api/apps/bank/withdraw/withdraw')
+ .reply(({ request }) => {
+ // Get the id
+ const id = request.params.get('id');
+
+ // Find the withdraw and delete it
+ this._withdraws.forEach((item, index) => {
+ if (item.id === id) {
+ this._withdraws.splice(index, 1);
+ }
+ });
+
+ // Return the response
+ return [200, true];
+ });
+ }
+}
diff --git a/src/app/mock-api/apps/settings/withdraw/data.ts b/src/app/mock-api/apps/settings/withdraw/data.ts
new file mode 100644
index 0000000..72ff135
--- /dev/null
+++ b/src/app/mock-api/apps/settings/withdraw/data.ts
@@ -0,0 +1,52 @@
+/* eslint-disable */
+
+export const withdraws = [
+ {
+ rank: '회원',
+ id: 'aa100',
+ nickname: 'aa100',
+ exchangeApplication: 14000000,
+ calculateType: '롤링',
+ accountHolder: '광주은행121212121212sss',
+ note: '@',
+ registrationDate: '2022-06-10 16:51',
+ processDate: '2022-06-10 16:51',
+ deposit: 41200000,
+ withdraw: 19000000,
+ total: 22200000,
+ highRank: '[매장]kgon5',
+ state: '완료',
+ },
+ {
+ rank: '회원',
+ id: 'aa100',
+ nickname: 'aa100',
+ exchangeApplication: 5000000,
+ calculateType: '롤링',
+ accountHolder: '광주은행121212121212sss',
+ note: '@',
+ registrationDate: '2022-06-08 18:31',
+ processDate: '2022-06-08 20:13',
+ deposit: 41200000,
+ withdraw: 19000000,
+ total: 22200000,
+ highRank: '[매장]kgon5',
+ state: '완료',
+ },
+ {
+ rank: '회원',
+ id: 'qwer12',
+ nickname: '하하하',
+ exchangeApplication: 10000,
+ calculateType: '롤링',
+ accountHolder: '하나은행000210654151테스트',
+ note: '',
+ registrationDate: '2022-06-08 01:22',
+ processDate: '2022-06-08 01:22',
+ deposit: 10000000,
+ withdraw: 10000,
+ total: 9990000,
+ highRank: '[매장]kgon5',
+ state: '완료',
+ },
+];
diff --git a/src/app/mock-api/common/navigation/data.ts b/src/app/mock-api/common/navigation/data.ts
index 703ea4c..46a634b 100644
--- a/src/app/mock-api/common/navigation/data.ts
+++ b/src/app/mock-api/common/navigation/data.ts
@@ -192,6 +192,22 @@ export const defaultNavigation: FuseNavigationItem[] = [
},
],
},
+ {
+ id: 'settings',
+ title: 'Settings',
+ subtitle: 'site settings',
+ type: 'group',
+ icon: 'heroicons_outline:cog',
+ children: [
+ {
+ id: 'settings.basic',
+ title: 'Basic-Setting',
+ type: 'basic',
+ icon: 'heroicons_outline:cog',
+ link: '/settings/basic',
+ },
+ ],
+ },
];
export const compactNavigation: FuseNavigationItem[] = [
{
@@ -226,6 +242,14 @@ export const compactNavigation: FuseNavigationItem[] = [
icon: 'heroicons_outline:home',
children: [], // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
},
+ {
+ id: 'settings',
+ title: 'Settings',
+ subtitle: 'site settings',
+ type: 'group',
+ icon: 'heroicons_outline:home',
+ children: [], // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
+ },
];
export const futuristicNavigation: FuseNavigationItem[] = [
{
@@ -252,6 +276,12 @@ export const futuristicNavigation: FuseNavigationItem[] = [
type: 'group',
children: [], // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
},
+ {
+ id: 'settings',
+ title: 'Settings',
+ type: 'group',
+ children: [], // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
+ },
];
export const horizontalNavigation: FuseNavigationItem[] = [
{
@@ -282,4 +312,10 @@ export const horizontalNavigation: FuseNavigationItem[] = [
icon: 'heroicons_outline:home',
children: [], // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
},
+ {
+ id: 'settings',
+ title: 'Settings',
+ type: 'group',
+ children: [], // This will be filled from defaultNavigation so we don't have to manage multiple sets of the same navigation
+ },
];
diff --git a/src/app/mock-api/index.ts b/src/app/mock-api/index.ts
index 972794b..d48a734 100644
--- a/src/app/mock-api/index.ts
+++ b/src/app/mock-api/index.ts
@@ -39,6 +39,7 @@ import { GamePowerballMockApi } from './apps/game/powerball/api';
import { GameCasinoMockApi } from './apps/game/casino/api';
import { GameEvolutionMockApi } from './apps/game/evolution/api';
import { GameSlotMockApi } from './apps/game/slot/api';
+import { BasicSettingMockApi } from './apps/settings/basic/api';
export const mockApiServices = [
AcademyMockApi,
@@ -82,4 +83,5 @@ export const mockApiServices = [
GameCasinoMockApi,
GameEvolutionMockApi,
GameSlotMockApi,
+ BasicSettingMockApi,
];
diff --git a/src/app/modules/admin/settings/basic/basic.module.ts b/src/app/modules/admin/settings/basic/basic.module.ts
new file mode 100644
index 0000000..4f8e716
--- /dev/null
+++ b/src/app/modules/admin/settings/basic/basic.module.ts
@@ -0,0 +1,42 @@
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { MatButtonModule } from '@angular/material/button';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatIconModule } from '@angular/material/icon';
+import { MatInputModule } from '@angular/material/input';
+import { MatPaginatorModule } from '@angular/material/paginator';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
+import { MatRippleModule } from '@angular/material/core';
+import { MatSortModule } from '@angular/material/sort';
+import { MatSelectModule } from '@angular/material/select';
+import { MatTooltipModule } from '@angular/material/tooltip';
+
+import { TranslocoModule } from '@ngneat/transloco';
+
+import { SharedModule } from 'app/shared/shared.module';
+
+import { COMPONENTS } from './components';
+
+import { basicSettingRoutes } from './basic.routing';
+
+@NgModule({
+ declarations: [COMPONENTS],
+ imports: [
+ TranslocoModule,
+ SharedModule,
+ RouterModule.forChild(basicSettingRoutes),
+
+ MatButtonModule,
+ MatFormFieldModule,
+ MatIconModule,
+ MatInputModule,
+ MatPaginatorModule,
+ MatProgressBarModule,
+ MatRippleModule,
+ MatSortModule,
+ MatSelectModule,
+ MatTooltipModule,
+ ],
+})
+export class BasicModule {}
diff --git a/src/app/modules/admin/settings/basic/basic.routing.ts b/src/app/modules/admin/settings/basic/basic.routing.ts
new file mode 100644
index 0000000..deadaef
--- /dev/null
+++ b/src/app/modules/admin/settings/basic/basic.routing.ts
@@ -0,0 +1,15 @@
+import { Route } from '@angular/router';
+
+import { ListComponent } from './components/list.component';
+
+import { BasicResolver } from './resolvers/basic.resolver';
+
+export const basicSettingRoutes: Route[] = [
+ {
+ path: '',
+ component: ListComponent,
+ resolve: {
+ deposits: BasicResolver,
+ },
+ },
+];
diff --git a/src/app/modules/admin/settings/basic/components/index.ts b/src/app/modules/admin/settings/basic/components/index.ts
new file mode 100644
index 0000000..04759eb
--- /dev/null
+++ b/src/app/modules/admin/settings/basic/components/index.ts
@@ -0,0 +1,3 @@
+import { ListComponent } from './list.component';
+
+export const COMPONENTS = [ListComponent];
diff --git a/src/app/modules/admin/settings/basic/components/list.component.html b/src/app/modules/admin/settings/basic/components/list.component.html
new file mode 100644
index 0000000..69fe978
--- /dev/null
+++ b/src/app/modules/admin/settings/basic/components/list.component.html
@@ -0,0 +1 @@
+
it's works
diff --git a/src/app/modules/admin/settings/basic/components/list.component.ts b/src/app/modules/admin/settings/basic/components/list.component.ts
new file mode 100644
index 0000000..13db10a
--- /dev/null
+++ b/src/app/modules/admin/settings/basic/components/list.component.ts
@@ -0,0 +1,137 @@
+import {
+ AfterViewInit,
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ OnDestroy,
+ OnInit,
+ ViewChild,
+ ViewEncapsulation,
+} from '@angular/core';
+import {
+ FormBuilder,
+ FormControl,
+ FormGroup,
+ Validators,
+} from '@angular/forms';
+import { MatCheckboxChange } from '@angular/material/checkbox';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import {
+ debounceTime,
+ map,
+ merge,
+ Observable,
+ Subject,
+ switchMap,
+ takeUntil,
+} from 'rxjs';
+import { fuseAnimations } from '@fuse/animations';
+import { FuseConfirmationService } from '@fuse/services/confirmation';
+
+import { BasicSetting } from '../models/basic-setting';
+import { BasicService } from '../services/basic.service';
+
+@Component({
+ selector: 'settings-basic',
+ templateUrl: './list.component.html',
+ styles: [
+ /* language=SCSS */
+ `
+ .inventory-grid {
+ grid-template-columns: 60px auto 40px;
+
+ @screen sm {
+ grid-template-columns: 60px auto 60px 72px;
+ }
+
+ @screen md {
+ grid-template-columns: 60px 60px auto 112px 72px;
+ }
+
+ @screen lg {
+ grid-template-columns: 60px 60px auto 112px 96px 96px 72px;
+ }
+ }
+ `,
+ ],
+ encapsulation: ViewEncapsulation.None,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ animations: fuseAnimations,
+})
+export class ListComponent implements OnInit, AfterViewInit, OnDestroy {
+ @ViewChild(MatPaginator) private _paginator!: MatPaginator;
+ @ViewChild(MatSort) private _sort!: MatSort;
+
+ basicSetting$!: Observable;
+
+ isLoading = false;
+
+ private _unsubscribeAll: Subject = new Subject();
+
+ /**
+ * Constructor
+ */
+ constructor(
+ private _changeDetectorRef: ChangeDetectorRef,
+ private _fuseConfirmationService: FuseConfirmationService,
+ private _formBuilder: FormBuilder,
+ private _basicService: BasicService
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Lifecycle hooks
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * On init
+ */
+ ngOnInit(): void {
+ // Get the products
+ this.basicSetting$ = this._basicService.basicSetting$;
+ }
+
+ /**
+ * After view init
+ */
+ ngAfterViewInit(): void {}
+
+ /**
+ * On destroy
+ */
+ ngOnDestroy(): void {
+ // Unsubscribe from all subscriptions
+ this._unsubscribeAll.next(null);
+ this._unsubscribeAll.complete();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Private methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Create product
+ */
+ __createProduct(): void {}
+
+ /**
+ * Toggle product details
+ *
+ * @param productId
+ */
+ __toggleDetails(productId: string): void {}
+
+ /**
+ * Track by function for ngFor loops
+ *
+ * @param index
+ * @param item
+ */
+ __trackByFn(index: number, item: any): any {
+ return item.id || index;
+ }
+}
diff --git a/src/app/modules/admin/settings/basic/models/basic-setting.ts b/src/app/modules/admin/settings/basic/models/basic-setting.ts
new file mode 100644
index 0000000..ccb0b16
--- /dev/null
+++ b/src/app/modules/admin/settings/basic/models/basic-setting.ts
@@ -0,0 +1,8 @@
+import { SiteStatusType } from '../types/site-status.type';
+
+export interface BasicSetting {
+ siteStatus?: SiteStatusType;
+ memo?: string;
+ earnSetting?: any;
+ gameSetting?: any;
+}
diff --git a/src/app/modules/admin/settings/basic/resolvers/basic.resolver.ts b/src/app/modules/admin/settings/basic/resolvers/basic.resolver.ts
new file mode 100644
index 0000000..75646f8
--- /dev/null
+++ b/src/app/modules/admin/settings/basic/resolvers/basic.resolver.ts
@@ -0,0 +1,40 @@
+import { Injectable } from '@angular/core';
+import {
+ ActivatedRouteSnapshot,
+ Resolve,
+ Router,
+ RouterStateSnapshot,
+} from '@angular/router';
+import { catchError, Observable, throwError } from 'rxjs';
+
+import { BasicSetting } from '../models/basic-setting';
+import { BasicService } from '../services/basic.service';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class BasicResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(private _basicService: BasicService) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable<{
+ basicSetting: BasicSetting;
+ }> {
+ return this._basicService.getBasicSetting();
+ }
+}
diff --git a/src/app/modules/admin/settings/basic/services/basic.service.ts b/src/app/modules/admin/settings/basic/services/basic.service.ts
new file mode 100644
index 0000000..6769ee2
--- /dev/null
+++ b/src/app/modules/admin/settings/basic/services/basic.service.ts
@@ -0,0 +1,62 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import {
+ BehaviorSubject,
+ filter,
+ map,
+ Observable,
+ of,
+ switchMap,
+ take,
+ tap,
+ throwError,
+} from 'rxjs';
+
+import { BasicSetting } from '../models/basic-setting';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class BasicService {
+ // Private
+ private __basicSetting = new BehaviorSubject(
+ undefined
+ );
+
+ /**
+ * Constructor
+ */
+ constructor(private _httpClient: HttpClient) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Accessors
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Getter for basicSetting
+ */
+ get basicSetting$(): Observable {
+ return this.__basicSetting.asObservable();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Get basicSetting
+ *
+ *
+ */
+ getBasicSetting(): Observable<{
+ basicSetting: BasicSetting;
+ }> {
+ return this._httpClient
+ .get<{ basicSetting: BasicSetting }>('api/apps/settings/basic')
+ .pipe(
+ tap((response) => {
+ this.__basicSetting.next(response.basicSetting);
+ })
+ );
+ }
+}
diff --git a/src/app/modules/admin/settings/basic/types/site-status.type.ts b/src/app/modules/admin/settings/basic/types/site-status.type.ts
new file mode 100644
index 0000000..c18e32b
--- /dev/null
+++ b/src/app/modules/admin/settings/basic/types/site-status.type.ts
@@ -0,0 +1,5 @@
+export enum SiteStatusType {
+ joinAvailable = 'JOIN_AVAILABLE',
+ joinUnAvailable = 'JOIN_UNAVAILABLE',
+ serverMaintenance = 'SEVER_MAINTENANCE',
+}
diff --git a/src/app/modules/admin/settings/branch/components/index.ts b/src/app/modules/admin/settings/branch/components/index.ts
new file mode 100644
index 0000000..04759eb
--- /dev/null
+++ b/src/app/modules/admin/settings/branch/components/index.ts
@@ -0,0 +1,3 @@
+import { ListComponent } from './list.component';
+
+export const COMPONENTS = [ListComponent];
diff --git a/src/app/modules/admin/settings/branch/components/list.component.html b/src/app/modules/admin/settings/branch/components/list.component.html
new file mode 100644
index 0000000..907126a
--- /dev/null
+++ b/src/app/modules/admin/settings/branch/components/list.component.html
@@ -0,0 +1,350 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 전체금액
+ 배팅100만미만
+ 배팅100-300만
+ 배팅300-500만
+ 배팅500만이상
+ 당첨1000만초과
+
+
+
+
+ 아이디
+ 게임아이디
+ 닉네임
+ 게임종류
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0; else noEvolution">
+
+
+
+
+
상위
+
유저
+
게임
+
형식
+
금액
+
최종금액
+
배팅
+
데이터
+
콤프
+
롤링
+
배팅시간 등록시간
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ evolution.gameId }}
+ {{ evolution.id }}
+ {{ evolution.nickname }}
+
+
+
+
+ {{ evolution.gameInfo1 }}
+ {{ evolution.gameInfo2 }}
+ {{ evolution.gameInfo3 }}
+
+
+
+
+
+
+
+ 배팅{{ evolution.betting }} 당첨{{
+ evolution.winning
+ }}
+ 손익{{ evolution.profitLoss }}
+
+
+
+
+ 배팅 전{{ evolution.beforeBetting }} 배팅 후{{
+ evolution.afterBetting
+ }}
+ 최종금액{{ evolution.finalMoney }}
+
+
+
+
+ {{ evolution.bettingInfo1 }}
+ {{ evolution.bettingInfo2 }}
+ {{ evolution.bettingInfo3 }}
+
+
+
+
+
+
+
+
+
+ {{ evolution.comp }}
+
+
+
+
+ 본사:{{ evolution.mainofficeName }}({{
+ evolution.mainofficePercent
+ }}%,{{ evolution.mainofficePoint }}P) 대본:{{
+ evolution.branchName
+ }}({{ evolution.branchPercent }}%,{{
+ evolution.branchPoint
+ }}P) 부본:{{ evolution.divisionName }}({{
+ evolution.divisionPercent
+ }}%,{{ evolution.divisionPoint }}P) 총판:{{
+ evolution.officeName
+ }}({{ evolution.officePercent }}%,{{
+ evolution.officePoint
+ }}P) 매장:{{ evolution.storeName }}({{
+ evolution.storePercent
+ }}%,{{ evolution.storePoint }}P) 회원:{{
+ evolution.memberName
+ }}({{ evolution.memberPercent }}%,{{
+ evolution.memberPoint
+ }}P)
+
+
+
+
+ {{ evolution.bettingTime }}
+ {{ evolution.registrationTime }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ There are no evolution!
+
+
+
+
+
diff --git a/src/app/modules/admin/settings/branch/components/list.component.ts b/src/app/modules/admin/settings/branch/components/list.component.ts
new file mode 100644
index 0000000..629a2cb
--- /dev/null
+++ b/src/app/modules/admin/settings/branch/components/list.component.ts
@@ -0,0 +1,190 @@
+import {
+ AfterViewInit,
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ OnDestroy,
+ OnInit,
+ ViewChild,
+ ViewEncapsulation,
+} from '@angular/core';
+import {
+ FormBuilder,
+ FormControl,
+ FormGroup,
+ Validators,
+} from '@angular/forms';
+import { MatCheckboxChange } from '@angular/material/checkbox';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import {
+ debounceTime,
+ map,
+ merge,
+ Observable,
+ Subject,
+ switchMap,
+ takeUntil,
+} from 'rxjs';
+import { fuseAnimations } from '@fuse/animations';
+import { FuseConfirmationService } from '@fuse/services/confirmation';
+
+import { Evolution } from '../models/evolution';
+import { EvolutionPagination } from '../models/evolution-pagination';
+import { EvolutionService } from '../services/evolution.service';
+
+@Component({
+ selector: 'evolution-list',
+ templateUrl: './list.component.html',
+ styles: [
+ /* language=SCSS */
+ `
+ .inventory-grid {
+ grid-template-columns: 60px auto 40px;
+
+ @screen sm {
+ grid-template-columns: 60px auto 60px 72px;
+ }
+
+ @screen md {
+ grid-template-columns: 60px 60px auto 112px 72px;
+ }
+
+ @screen lg {
+ grid-template-columns: 60px 60px auto 112px 96px 96px 72px;
+ }
+ }
+ `,
+ ],
+ encapsulation: ViewEncapsulation.None,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ animations: fuseAnimations,
+})
+export class ListComponent implements OnInit, AfterViewInit, OnDestroy {
+ @ViewChild(MatPaginator) private _paginator!: MatPaginator;
+ @ViewChild(MatSort) private _sort!: MatSort;
+
+ evolutions$!: Observable;
+
+ isLoading = false;
+ searchInputControl = new FormControl();
+ selectedEvolution?: Evolution;
+ pagination?: EvolutionPagination;
+
+ private _unsubscribeAll: Subject = new Subject();
+
+ /**
+ * Constructor
+ */
+ constructor(
+ private _changeDetectorRef: ChangeDetectorRef,
+ private _fuseConfirmationService: FuseConfirmationService,
+ private _formBuilder: FormBuilder,
+ private _evolutionService: EvolutionService
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Lifecycle hooks
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * On init
+ */
+ ngOnInit(): void {
+ // Get the pagination
+ this._evolutionService.pagination$
+ .pipe(takeUntil(this._unsubscribeAll))
+ .subscribe((pagination: EvolutionPagination | undefined) => {
+ // Update the pagination
+ this.pagination = pagination;
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+ });
+
+ // Get the products
+ this.evolutions$ = this._evolutionService.evolutions$;
+ }
+
+ /**
+ * After view init
+ */
+ ngAfterViewInit(): void {
+ if (this._sort && this._paginator) {
+ // Set the initial sort
+ this._sort.sort({
+ id: 'nickname',
+ start: 'asc',
+ disableClear: true,
+ });
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+
+ // If the evolution changes the sort order...
+ this._sort.sortChange
+ .pipe(takeUntil(this._unsubscribeAll))
+ .subscribe(() => {
+ // Reset back to the first page
+ this._paginator.pageIndex = 0;
+ });
+
+ // Get products if sort or page changes
+ merge(this._sort.sortChange, this._paginator.page)
+ .pipe(
+ switchMap(() => {
+ this.isLoading = true;
+ return this._evolutionService.getEvolutions(
+ this._paginator.pageIndex,
+ this._paginator.pageSize,
+ this._sort.active,
+ this._sort.direction
+ );
+ }),
+ map(() => {
+ this.isLoading = false;
+ })
+ )
+ .subscribe();
+ }
+ }
+
+ /**
+ * On destroy
+ */
+ ngOnDestroy(): void {
+ // Unsubscribe from all subscriptions
+ this._unsubscribeAll.next(null);
+ this._unsubscribeAll.complete();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Private methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Create product
+ */
+ __createProduct(): void {}
+
+ /**
+ * Toggle product details
+ *
+ * @param productId
+ */
+ __toggleDetails(productId: string): void {}
+
+ /**
+ * Track by function for ngFor loops
+ *
+ * @param index
+ * @param item
+ */
+ __trackByFn(index: number, item: any): any {
+ return item.id || index;
+ }
+}
diff --git a/src/app/modules/admin/settings/branch/evolution.module.ts b/src/app/modules/admin/settings/branch/evolution.module.ts
new file mode 100644
index 0000000..7fb584a
--- /dev/null
+++ b/src/app/modules/admin/settings/branch/evolution.module.ts
@@ -0,0 +1,42 @@
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { MatButtonModule } from '@angular/material/button';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatIconModule } from '@angular/material/icon';
+import { MatInputModule } from '@angular/material/input';
+import { MatPaginatorModule } from '@angular/material/paginator';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
+import { MatRippleModule } from '@angular/material/core';
+import { MatSortModule } from '@angular/material/sort';
+import { MatSelectModule } from '@angular/material/select';
+import { MatTooltipModule } from '@angular/material/tooltip';
+
+import { TranslocoModule } from '@ngneat/transloco';
+
+import { SharedModule } from 'app/shared/shared.module';
+
+import { COMPONENTS } from './components';
+
+import { evolutionRoutes } from './evolution.routing';
+
+@NgModule({
+ declarations: [COMPONENTS],
+ imports: [
+ TranslocoModule,
+ SharedModule,
+ RouterModule.forChild(evolutionRoutes),
+
+ MatButtonModule,
+ MatFormFieldModule,
+ MatIconModule,
+ MatInputModule,
+ MatPaginatorModule,
+ MatProgressBarModule,
+ MatRippleModule,
+ MatSortModule,
+ MatSelectModule,
+ MatTooltipModule,
+ ],
+})
+export class EvolutionModule {}
diff --git a/src/app/modules/admin/settings/branch/evolution.routing.ts b/src/app/modules/admin/settings/branch/evolution.routing.ts
new file mode 100644
index 0000000..78500d7
--- /dev/null
+++ b/src/app/modules/admin/settings/branch/evolution.routing.ts
@@ -0,0 +1,15 @@
+import { Route } from '@angular/router';
+
+import { ListComponent } from './components/list.component';
+
+import { EvolutionsResolver } from './resolvers/evolution.resolver';
+
+export const evolutionRoutes: Route[] = [
+ {
+ path: '',
+ component: ListComponent,
+ resolve: {
+ deposits: EvolutionsResolver,
+ },
+ },
+];
diff --git a/src/app/modules/admin/settings/branch/models/evolution-pagination.ts b/src/app/modules/admin/settings/branch/models/evolution-pagination.ts
new file mode 100644
index 0000000..d1bff25
--- /dev/null
+++ b/src/app/modules/admin/settings/branch/models/evolution-pagination.ts
@@ -0,0 +1,8 @@
+export interface EvolutionPagination {
+ length: number;
+ size: number;
+ page: number;
+ lastPage: number;
+ startIndex: number;
+ endIndex: number;
+}
diff --git a/src/app/modules/admin/settings/branch/models/evolution.ts b/src/app/modules/admin/settings/branch/models/evolution.ts
new file mode 100644
index 0000000..8d6f322
--- /dev/null
+++ b/src/app/modules/admin/settings/branch/models/evolution.ts
@@ -0,0 +1,58 @@
+export interface Evolution {
+ id?: string;
+ startDate?: string;
+ finishDate?: string;
+ availableBetting?: number;
+ bettingMoney?: number;
+ winningMoney?: number;
+ cancel?: number;
+ betWinCancel?: number;
+ mainofficeRolling?: number;
+ branchRolling?: number;
+ divisionRolling?: number;
+ officeRolling?: number;
+ storeRolling?: number;
+ memberRolling?: number;
+ totalrolling?: number;
+ highRank?: string;
+ gameId?: string;
+ nickname?: string;
+ gameName?: string;
+ gameInfo1?: string;
+ gameInfo2?: string;
+ gameInfo3?: string;
+ form?: string;
+ betting?: number;
+ profitLoss?: number;
+ beforeWinning?: number;
+ winning?: number;
+ afterWinning?: number;
+ beforeBetting?: number;
+ afterBetting?: number;
+ finalMoney?: number;
+ bettingInfo1?: string;
+ bettingInfo2?: number;
+ bettingInfo3?: number;
+ data?: string;
+ comp?: string;
+ mainofficeName?: string;
+ mainofficePercent?: number;
+ mainofficePoint?: number;
+ branchName?: string;
+ branchPercent?: number;
+ branchPoint?: number;
+ divisionName?: string;
+ divisionPercent?: number;
+ divisionPoint?: number;
+ officeName?: string;
+ officePercent?: number;
+ officePoint?: number;
+ storeName?: string;
+ storePercent?: number;
+ storePoint?: number;
+ memberName?: string;
+ memberPercent?: number;
+ memberPoint?: number;
+ bettingTime?: string;
+ registrationTime?: string;
+}
diff --git a/src/app/modules/admin/settings/branch/resolvers/evolution.resolver.ts b/src/app/modules/admin/settings/branch/resolvers/evolution.resolver.ts
new file mode 100644
index 0000000..4fc4dd8
--- /dev/null
+++ b/src/app/modules/admin/settings/branch/resolvers/evolution.resolver.ts
@@ -0,0 +1,89 @@
+import { Injectable } from '@angular/core';
+import {
+ ActivatedRouteSnapshot,
+ Resolve,
+ Router,
+ RouterStateSnapshot,
+} from '@angular/router';
+import { catchError, Observable, throwError } from 'rxjs';
+
+import { Evolution } from '../models/evolution';
+import { EvolutionPagination } from '../models/evolution-pagination';
+import { EvolutionService } from '../services/evolution.service';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class EvolutionResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(
+ private _evolutionService: EvolutionService,
+ private _router: Router
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable {
+ return this._evolutionService
+ .getEvolutionById(route.paramMap.get('id'))
+ .pipe(
+ // Error here means the requested product is not available
+ catchError((error) => {
+ // Log the error
+ console.error(error);
+
+ // Get the parent url
+ const parentUrl = state.url.split('/').slice(0, -1).join('/');
+
+ // Navigate to there
+ this._router.navigateByUrl(parentUrl);
+
+ // Throw an error
+ return throwError(error);
+ })
+ );
+ }
+}
+
+@Injectable({
+ providedIn: 'root',
+})
+export class EvolutionsResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(private _evolutionService: EvolutionService) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable<{
+ pagination: EvolutionPagination;
+ evolutions: Evolution[];
+ }> {
+ return this._evolutionService.getEvolutions();
+ }
+}
diff --git a/src/app/modules/admin/settings/branch/services/evolution.service.ts b/src/app/modules/admin/settings/branch/services/evolution.service.ts
new file mode 100644
index 0000000..396f0f7
--- /dev/null
+++ b/src/app/modules/admin/settings/branch/services/evolution.service.ts
@@ -0,0 +1,156 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import {
+ BehaviorSubject,
+ filter,
+ map,
+ Observable,
+ of,
+ switchMap,
+ take,
+ tap,
+ throwError,
+} from 'rxjs';
+
+import { Evolution } from '../models/evolution';
+import { EvolutionPagination } from '../models/evolution-pagination';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class EvolutionService {
+ // Private
+ private __pagination = new BehaviorSubject(
+ undefined
+ );
+ private __evolution = new BehaviorSubject(undefined);
+ private __evolutions = new BehaviorSubject(
+ undefined
+ );
+
+ /**
+ * Constructor
+ */
+ constructor(private _httpClient: HttpClient) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Accessors
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Getter for pagination
+ */
+ get pagination$(): Observable {
+ return this.__pagination.asObservable();
+ }
+
+ /**
+ * Getter for evolution
+ */
+ get evolution$(): Observable {
+ return this.__evolution.asObservable();
+ }
+
+ /**
+ * Getter for evolutions
+ */
+ get evolutions$(): Observable {
+ return this.__evolutions.asObservable();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Get evolutions
+ *
+ *
+ * @param page
+ * @param size
+ * @param sort
+ * @param order
+ * @param search
+ */
+ getEvolutions(
+ page: number = 0,
+ size: number = 10,
+ sort: string = 'nickname',
+ order: 'asc' | 'desc' | '' = 'asc',
+ search: string = ''
+ ): Observable<{
+ pagination: EvolutionPagination;
+ evolutions: Evolution[];
+ }> {
+ return this._httpClient
+ .get<{ pagination: EvolutionPagination; evolutions: Evolution[] }>(
+ 'api/apps/game/evolution/evolutions',
+ {
+ params: {
+ page: '' + page,
+ size: '' + size,
+ sort,
+ order,
+ search,
+ },
+ }
+ )
+ .pipe(
+ tap((response) => {
+ this.__pagination.next(response.pagination);
+ this.__evolutions.next(response.evolutions);
+ })
+ );
+ }
+
+ /**
+ * Get product by id
+ */
+ getEvolutionById(id: string | null): Observable {
+ return this.__evolutions.pipe(
+ take(1),
+ map((evolutions) => {
+ // Find the product
+ const evolution =
+ evolutions?.find((item) => item.id === id) || undefined;
+
+ // Update the product
+ this.__evolution.next(evolution);
+
+ // Return the product
+ return evolution;
+ }),
+ switchMap((product) => {
+ if (!product) {
+ return throwError('Could not found product with id of ' + id + '!');
+ }
+
+ return of(product);
+ })
+ );
+ }
+
+ /**
+ * Create product
+ */
+ createEvolution(): Observable {
+ return this.evolutions$.pipe(
+ take(1),
+ switchMap((evolutions) =>
+ this._httpClient
+ .post('api/apps/game/evolution/product', {})
+ .pipe(
+ map((newEvolution) => {
+ // Update the evolutions with the new product
+ if (!!evolutions) {
+ this.__evolutions.next([newEvolution, ...evolutions]);
+ }
+
+ // Return the new product
+ return newEvolution;
+ })
+ )
+ )
+ );
+ }
+}
diff --git a/src/app/modules/admin/settings/evo/components/index.ts b/src/app/modules/admin/settings/evo/components/index.ts
new file mode 100644
index 0000000..04759eb
--- /dev/null
+++ b/src/app/modules/admin/settings/evo/components/index.ts
@@ -0,0 +1,3 @@
+import { ListComponent } from './list.component';
+
+export const COMPONENTS = [ListComponent];
diff --git a/src/app/modules/admin/settings/evo/components/list.component.html b/src/app/modules/admin/settings/evo/components/list.component.html
new file mode 100644
index 0000000..eee3cf2
--- /dev/null
+++ b/src/app/modules/admin/settings/evo/components/list.component.html
@@ -0,0 +1,372 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 카지노
+ 슬롯
+
+
+
+
+ 전체
+ 프라그마틱 슬롯
+ 마이크로게이밍 슬롯
+ 하바네로
+ 부운고
+ 플레이손
+ 퀵스핀
+ 플레이엔고
+ 넷엔트
+ 메버릭
+ 레드레이크
+ 릴렉스
+ 블루프린트
+ ELK
+ 아시안게이밍 슬롯
+ CQ9 슬롯
+ 레드타이거
+ 드래곤 소프트
+ 스피어헤드
+ 엘리시움
+
+
+
+
+ 전체금액
+ 배팅100만미만
+ 배팅100-300만
+ 배팅300-500만
+ 배팅500만이상
+ 당첨1000만초과
+
+
+
+
+ 아이디
+ 게임아이디
+ 닉네임
+ 게임종류
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0; else noSlot">
+
+
+
+
+
상위
+
유저
+
게임
+
형식
+
금액
+
최종금액
+
배팅
+
데이터
+
콤프
+
롤링
+
배팅시간 등록시간
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ slot.gameId }}
+ {{ slot.id }}
+ {{ slot.nickname }}
+
+
+
+
+ {{ slot.gameInfo1 }}
+ {{ slot.gameInfo2 }}
+ {{ slot.gameInfo3 }}
+
+
+
+
+
+
+
+ 배팅{{ slot.betting }} 당첨{{ slot.winning }} 손익{{
+ slot.profitLoss
+ }}
+
+
+
+
+ 배팅 전{{ slot.beforeBetting }} 배팅 후{{
+ slot.afterBetting
+ }}
+ 최종금액{{ slot.finalMoney }}
+
+
+
+
+ {{ slot.bettingInfo1 }}
+ {{ slot.bettingInfo2 }}
+ {{ slot.bettingInfo3 }}
+
+
+
+
+
+
+
+
+
+ {{ slot.comp }}
+
+
+
+
+ 본사:{{ slot.mainofficeName }}({{
+ slot.mainofficePercent
+ }}%,{{ slot.mainofficePoint }}P) 대본:{{
+ slot.branchName
+ }}({{ slot.branchPercent }}%,{{ slot.branchPoint }}P)
+ 부본:{{ slot.divisionName }}({{ slot.divisionPercent }}%,{{
+ slot.divisionPoint
+ }}P) 총판:{{ slot.officeName }}({{ slot.officePercent }}%,{{
+ slot.officePoint
+ }}P) 매장:{{ slot.storeName }}({{ slot.storePercent }}%,{{
+ slot.storePoint
+ }}P) 회원:{{ slot.memberName }}({{ slot.memberPercent }}%,{{
+ slot.memberPoint
+ }}P)
+
+
+
+
+ {{ slot.bettingTime }}
+ {{ slot.registrationTime }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ There are no slot!
+
+
+
+
+
diff --git a/src/app/modules/admin/settings/evo/components/list.component.ts b/src/app/modules/admin/settings/evo/components/list.component.ts
new file mode 100644
index 0000000..63e9563
--- /dev/null
+++ b/src/app/modules/admin/settings/evo/components/list.component.ts
@@ -0,0 +1,190 @@
+import {
+ AfterViewInit,
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ OnDestroy,
+ OnInit,
+ ViewChild,
+ ViewEncapsulation,
+} from '@angular/core';
+import {
+ FormBuilder,
+ FormControl,
+ FormGroup,
+ Validators,
+} from '@angular/forms';
+import { MatCheckboxChange } from '@angular/material/checkbox';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import {
+ debounceTime,
+ map,
+ merge,
+ Observable,
+ Subject,
+ switchMap,
+ takeUntil,
+} from 'rxjs';
+import { fuseAnimations } from '@fuse/animations';
+import { FuseConfirmationService } from '@fuse/services/confirmation';
+
+import { Slot } from '../models/slot';
+import { SlotPagination } from '../models/slot-pagination';
+import { SlotService } from '../services/slot.service';
+
+@Component({
+ selector: 'slot-list',
+ templateUrl: './list.component.html',
+ styles: [
+ /* language=SCSS */
+ `
+ .inventory-grid {
+ grid-template-columns: 60px auto 40px;
+
+ @screen sm {
+ grid-template-columns: 60px auto 60px 72px;
+ }
+
+ @screen md {
+ grid-template-columns: 60px 60px auto 112px 72px;
+ }
+
+ @screen lg {
+ grid-template-columns: 60px 60px auto 112px 96px 96px 72px;
+ }
+ }
+ `,
+ ],
+ encapsulation: ViewEncapsulation.None,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ animations: fuseAnimations,
+})
+export class ListComponent implements OnInit, AfterViewInit, OnDestroy {
+ @ViewChild(MatPaginator) private _paginator!: MatPaginator;
+ @ViewChild(MatSort) private _sort!: MatSort;
+
+ slots$!: Observable;
+
+ isLoading = false;
+ searchInputControl = new FormControl();
+ selectedSlot?: Slot;
+ pagination?: SlotPagination;
+
+ private _unsubscribeAll: Subject = new Subject();
+
+ /**
+ * Constructor
+ */
+ constructor(
+ private _changeDetectorRef: ChangeDetectorRef,
+ private _fuseConfirmationService: FuseConfirmationService,
+ private _formBuilder: FormBuilder,
+ private _slotService: SlotService
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Lifecycle hooks
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * On init
+ */
+ ngOnInit(): void {
+ // Get the pagination
+ this._slotService.pagination$
+ .pipe(takeUntil(this._unsubscribeAll))
+ .subscribe((pagination: SlotPagination | undefined) => {
+ // Update the pagination
+ this.pagination = pagination;
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+ });
+
+ // Get the products
+ this.slots$ = this._slotService.slots$;
+ }
+
+ /**
+ * After view init
+ */
+ ngAfterViewInit(): void {
+ if (this._sort && this._paginator) {
+ // Set the initial sort
+ this._sort.sort({
+ id: 'nickname',
+ start: 'asc',
+ disableClear: true,
+ });
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+
+ // If the slot changes the sort order...
+ this._sort.sortChange
+ .pipe(takeUntil(this._unsubscribeAll))
+ .subscribe(() => {
+ // Reset back to the first page
+ this._paginator.pageIndex = 0;
+ });
+
+ // Get products if sort or page changes
+ merge(this._sort.sortChange, this._paginator.page)
+ .pipe(
+ switchMap(() => {
+ this.isLoading = true;
+ return this._slotService.getSlots(
+ this._paginator.pageIndex,
+ this._paginator.pageSize,
+ this._sort.active,
+ this._sort.direction
+ );
+ }),
+ map(() => {
+ this.isLoading = false;
+ })
+ )
+ .subscribe();
+ }
+ }
+
+ /**
+ * On destroy
+ */
+ ngOnDestroy(): void {
+ // Unsubscribe from all subscriptions
+ this._unsubscribeAll.next(null);
+ this._unsubscribeAll.complete();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Private methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Create product
+ */
+ __createProduct(): void {}
+
+ /**
+ * Toggle product details
+ *
+ * @param productId
+ */
+ __toggleDetails(productId: string): void {}
+
+ /**
+ * Track by function for ngFor loops
+ *
+ * @param index
+ * @param item
+ */
+ __trackByFn(index: number, item: any): any {
+ return item.id || index;
+ }
+}
diff --git a/src/app/modules/admin/settings/evo/models/slot-pagination.ts b/src/app/modules/admin/settings/evo/models/slot-pagination.ts
new file mode 100644
index 0000000..fb8c889
--- /dev/null
+++ b/src/app/modules/admin/settings/evo/models/slot-pagination.ts
@@ -0,0 +1,8 @@
+export interface SlotPagination {
+ length: number;
+ size: number;
+ page: number;
+ lastPage: number;
+ startIndex: number;
+ endIndex: number;
+}
diff --git a/src/app/modules/admin/settings/evo/models/slot.ts b/src/app/modules/admin/settings/evo/models/slot.ts
new file mode 100644
index 0000000..db2b6dc
--- /dev/null
+++ b/src/app/modules/admin/settings/evo/models/slot.ts
@@ -0,0 +1,58 @@
+export interface Slot {
+ id?: string;
+ startDate?: string;
+ finishDate?: string;
+ availableBetting?: number;
+ bettingMoney?: number;
+ winningMoney?: number;
+ cancel?: number;
+ betWinCancel?: number;
+ mainofficeRolling?: number;
+ branchRolling?: number;
+ divisionRolling?: number;
+ officeRolling?: number;
+ storeRolling?: number;
+ memberRolling?: number;
+ totalrolling?: number;
+ highRank?: string;
+ gameId?: string;
+ nickname?: string;
+ gameName?: string;
+ gameInfo1?: string;
+ gameInfo2?: string;
+ gameInfo3?: string;
+ form?: string;
+ betting?: number;
+ profitLoss?: number;
+ beforeWinning?: number;
+ winning?: number;
+ afterWinning?: number;
+ beforeBetting?: number;
+ afterBetting?: number;
+ finalMoney?: number;
+ bettingInfo1?: string;
+ bettingInfo2?: number;
+ bettingInfo3?: number;
+ data?: string;
+ comp?: string;
+ mainofficeName?: string;
+ mainofficePercent?: number;
+ mainofficePoint?: number;
+ branchName?: string;
+ branchPercent?: number;
+ branchPoint?: number;
+ divisionName?: string;
+ divisionPercent?: number;
+ divisionPoint?: number;
+ officeName?: string;
+ officePercent?: number;
+ officePoint?: number;
+ storeName?: string;
+ storePercent?: number;
+ storePoint?: number;
+ memberName?: string;
+ memberPercent?: number;
+ memberPoint?: number;
+ bettingTime?: string;
+ registrationTime?: string;
+}
diff --git a/src/app/modules/admin/settings/evo/resolvers/slot.resolver.ts b/src/app/modules/admin/settings/evo/resolvers/slot.resolver.ts
new file mode 100644
index 0000000..a88f4c4
--- /dev/null
+++ b/src/app/modules/admin/settings/evo/resolvers/slot.resolver.ts
@@ -0,0 +1,84 @@
+import { Injectable } from '@angular/core';
+import {
+ ActivatedRouteSnapshot,
+ Resolve,
+ Router,
+ RouterStateSnapshot,
+} from '@angular/router';
+import { catchError, Observable, throwError } from 'rxjs';
+
+import { Slot } from '../models/slot';
+import { SlotPagination } from '../models/slot-pagination';
+import { SlotService } from '../services/slot.service';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class SlotResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(private _slotService: SlotService, private _router: Router) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable {
+ return this._slotService.getSlotById(route.paramMap.get('id')).pipe(
+ // Error here means the requested product is not available
+ catchError((error) => {
+ // Log the error
+ console.error(error);
+
+ // Get the parent url
+ const parentUrl = state.url.split('/').slice(0, -1).join('/');
+
+ // Navigate to there
+ this._router.navigateByUrl(parentUrl);
+
+ // Throw an error
+ return throwError(error);
+ })
+ );
+ }
+}
+
+@Injectable({
+ providedIn: 'root',
+})
+export class SlotsResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(private _slotService: SlotService) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable<{
+ pagination: SlotPagination;
+ slots: Slot[];
+ }> {
+ return this._slotService.getSlots();
+ }
+}
diff --git a/src/app/modules/admin/settings/evo/services/slot.service.ts b/src/app/modules/admin/settings/evo/services/slot.service.ts
new file mode 100644
index 0000000..099df86
--- /dev/null
+++ b/src/app/modules/admin/settings/evo/services/slot.service.ts
@@ -0,0 +1,151 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import {
+ BehaviorSubject,
+ filter,
+ map,
+ Observable,
+ of,
+ switchMap,
+ take,
+ tap,
+ throwError,
+} from 'rxjs';
+
+import { Slot } from '../models/slot';
+import { SlotPagination } from '../models/slot-pagination';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class SlotService {
+ // Private
+ private __pagination = new BehaviorSubject(
+ undefined
+ );
+ private __slot = new BehaviorSubject(undefined);
+ private __slots = new BehaviorSubject(undefined);
+
+ /**
+ * Constructor
+ */
+ constructor(private _httpClient: HttpClient) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Accessors
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Getter for pagination
+ */
+ get pagination$(): Observable {
+ return this.__pagination.asObservable();
+ }
+
+ /**
+ * Getter for slot
+ */
+ get slot$(): Observable {
+ return this.__slot.asObservable();
+ }
+
+ /**
+ * Getter for slots
+ */
+ get slots$(): Observable {
+ return this.__slots.asObservable();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Get slots
+ *
+ *
+ * @param page
+ * @param size
+ * @param sort
+ * @param order
+ * @param search
+ */
+ getSlots(
+ page: number = 0,
+ size: number = 10,
+ sort: string = 'nickname',
+ order: 'asc' | 'desc' | '' = 'asc',
+ search: string = ''
+ ): Observable<{
+ pagination: SlotPagination;
+ slots: Slot[];
+ }> {
+ return this._httpClient
+ .get<{ pagination: SlotPagination; slots: Slot[] }>(
+ 'api/apps/game/slot/slots',
+ {
+ params: {
+ page: '' + page,
+ size: '' + size,
+ sort,
+ order,
+ search,
+ },
+ }
+ )
+ .pipe(
+ tap((response) => {
+ this.__pagination.next(response.pagination);
+ this.__slots.next(response.slots);
+ })
+ );
+ }
+
+ /**
+ * Get product by id
+ */
+ getSlotById(id: string | null): Observable {
+ return this.__slots.pipe(
+ take(1),
+ map((slots) => {
+ // Find the product
+ const slot = slots?.find((item) => item.id === id) || undefined;
+
+ // Update the product
+ this.__slot.next(slot);
+
+ // Return the product
+ return slot;
+ }),
+ switchMap((product) => {
+ if (!product) {
+ return throwError('Could not found product with id of ' + id + '!');
+ }
+
+ return of(product);
+ })
+ );
+ }
+
+ /**
+ * Create product
+ */
+ createSlot(): Observable {
+ return this.slots$.pipe(
+ take(1),
+ switchMap((slots) =>
+ this._httpClient.post('api/apps/game/slot/product', {}).pipe(
+ map((newSlot) => {
+ // Update the slots with the new product
+ if (!!slots) {
+ this.__slots.next([newSlot, ...slots]);
+ }
+
+ // Return the new product
+ return newSlot;
+ })
+ )
+ )
+ );
+ }
+}
diff --git a/src/app/modules/admin/settings/evo/slot.module.ts b/src/app/modules/admin/settings/evo/slot.module.ts
new file mode 100644
index 0000000..6b92e2f
--- /dev/null
+++ b/src/app/modules/admin/settings/evo/slot.module.ts
@@ -0,0 +1,42 @@
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { MatButtonModule } from '@angular/material/button';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatIconModule } from '@angular/material/icon';
+import { MatInputModule } from '@angular/material/input';
+import { MatPaginatorModule } from '@angular/material/paginator';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
+import { MatRippleModule } from '@angular/material/core';
+import { MatSortModule } from '@angular/material/sort';
+import { MatSelectModule } from '@angular/material/select';
+import { MatTooltipModule } from '@angular/material/tooltip';
+
+import { TranslocoModule } from '@ngneat/transloco';
+
+import { SharedModule } from 'app/shared/shared.module';
+
+import { COMPONENTS } from './components';
+
+import { slotRoutes } from './slot.routing';
+
+@NgModule({
+ declarations: [COMPONENTS],
+ imports: [
+ TranslocoModule,
+ SharedModule,
+ RouterModule.forChild(slotRoutes),
+
+ MatButtonModule,
+ MatFormFieldModule,
+ MatIconModule,
+ MatInputModule,
+ MatPaginatorModule,
+ MatProgressBarModule,
+ MatRippleModule,
+ MatSortModule,
+ MatSelectModule,
+ MatTooltipModule,
+ ],
+})
+export class SlotModule {}
diff --git a/src/app/modules/admin/settings/evo/slot.routing.ts b/src/app/modules/admin/settings/evo/slot.routing.ts
new file mode 100644
index 0000000..6643300
--- /dev/null
+++ b/src/app/modules/admin/settings/evo/slot.routing.ts
@@ -0,0 +1,15 @@
+import { Route } from '@angular/router';
+
+import { ListComponent } from './components/list.component';
+
+import { SlotsResolver } from './resolvers/slot.resolver';
+
+export const slotRoutes: Route[] = [
+ {
+ path: '',
+ component: ListComponent,
+ resolve: {
+ deposits: SlotsResolver,
+ },
+ },
+];
diff --git a/src/app/modules/admin/settings/game/components/index.ts b/src/app/modules/admin/settings/game/components/index.ts
new file mode 100644
index 0000000..04759eb
--- /dev/null
+++ b/src/app/modules/admin/settings/game/components/index.ts
@@ -0,0 +1,3 @@
+import { ListComponent } from './list.component';
+
+export const COMPONENTS = [ListComponent];
diff --git a/src/app/modules/admin/settings/game/components/list.component.html b/src/app/modules/admin/settings/game/components/list.component.html
new file mode 100644
index 0000000..fa9d0dd
--- /dev/null
+++ b/src/app/modules/admin/settings/game/components/list.component.html
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 파워볼
+ 카지노
+ 슬롯
+
+
+
+
+ 전체
+ 단폴
+ 조합
+
+
+
+
+ 리스트수
+ 40
+ 60
+ 80
+ 100
+
+
+
+
+ 전체금액
+ 100-50만미만
+ 50만-100만미만
+ 100만-200만이하
+ 300만초과
+
+
+
+
+ 진행목록
+ 당첨
+ 실패
+ 실패제외
+ 취소
+ 관리자취소
+ 전체목록
+
+
+
+
+ 아이디
+ 닉네임
+ 파워볼회차
+ 배팅번호
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0; else noPowerball">
+
+
+
+
+
번호
+
구분
+
등급
+
아이디
+
+ 배팅진행내역
+
+
배당률
+
배팅액
+
배당적중금
+
배팅시간
+
결과
+
취소/삭제 여부
+
+
+
+
+
+
+
+
+ {{ powerball.index }}
+
+
+
+ LV.{{ powerball.way }}
+
+
+
+
+
+
+
+
+
+
+ {{ powerball.id }}
+ ({{ powerball.nickname }})
+
+
+
+
+
+
+ {{ powerball.bettingProgress }}
+
+
+
+
+ {{ powerball.odds }}
+
+
+
+
+ {{ powerball.bettingMoney }}원
+
+
+
+
+ {{ powerball.hitMoney }}원
+
+
+
+
+ {{ powerball.bettingTime }}
+
+
+
+
+ {{ powerball.result }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ There are no powerball!
+
+
+
+
+
diff --git a/src/app/modules/admin/settings/game/components/list.component.ts b/src/app/modules/admin/settings/game/components/list.component.ts
new file mode 100644
index 0000000..fd01f57
--- /dev/null
+++ b/src/app/modules/admin/settings/game/components/list.component.ts
@@ -0,0 +1,192 @@
+import {
+ AfterViewInit,
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ OnDestroy,
+ OnInit,
+ ViewChild,
+ ViewEncapsulation,
+} from '@angular/core';
+import {
+ FormBuilder,
+ FormControl,
+ FormGroup,
+ Validators,
+} from '@angular/forms';
+import { MatCheckboxChange } from '@angular/material/checkbox';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import {
+ debounceTime,
+ map,
+ merge,
+ Observable,
+ Subject,
+ switchMap,
+ takeUntil,
+} from 'rxjs';
+import { fuseAnimations } from '@fuse/animations';
+import { FuseConfirmationService } from '@fuse/services/confirmation';
+
+import { User } from 'app/modules/admin/member/user/models/user';
+import { Powerball } from '../models/powerball';
+import { PowerballPagination } from '../models/powerball-pagination';
+import { PowerballService } from '../services/powerball.service';
+
+@Component({
+ selector: 'powerball-list',
+ templateUrl: './list.component.html',
+ styles: [
+ /* language=SCSS */
+ `
+ .inventory-grid {
+ grid-template-columns: 60px auto 40px;
+
+ @screen sm {
+ grid-template-columns: 60px auto 60px 72px;
+ }
+
+ @screen md {
+ grid-template-columns: 60px 60px auto 112px 72px;
+ }
+
+ @screen lg {
+ grid-template-columns: 60px 60px auto 112px 96px 96px 72px;
+ }
+ }
+ `,
+ ],
+ encapsulation: ViewEncapsulation.None,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ animations: fuseAnimations,
+})
+export class ListComponent implements OnInit, AfterViewInit, OnDestroy {
+ @ViewChild(MatPaginator) private _paginator!: MatPaginator;
+ @ViewChild(MatSort) private _sort!: MatSort;
+
+ powerballs$!: Observable;
+ users$!: Observable;
+
+ isLoading = false;
+ searchInputControl = new FormControl();
+ selectedPowerball?: Powerball;
+ pagination?: PowerballPagination;
+
+ private _unsubscribeAll: Subject = new Subject();
+
+ /**
+ * Constructor
+ */
+ constructor(
+ private _changeDetectorRef: ChangeDetectorRef,
+ private _fuseConfirmationService: FuseConfirmationService,
+ private _formBuilder: FormBuilder,
+ private _powerballService: PowerballService
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Lifecycle hooks
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * On init
+ */
+ ngOnInit(): void {
+ // Get the pagination
+ this._powerballService.pagination$
+ .pipe(takeUntil(this._unsubscribeAll))
+ .subscribe((pagination: PowerballPagination | undefined) => {
+ // Update the pagination
+ this.pagination = pagination;
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+ });
+
+ // Get the products
+ this.powerballs$ = this._powerballService.powerballs$;
+ }
+
+ /**
+ * After view init
+ */
+ ngAfterViewInit(): void {
+ if (this._sort && this._paginator) {
+ // Set the initial sort
+ this._sort.sort({
+ id: 'nickname',
+ start: 'asc',
+ disableClear: true,
+ });
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+
+ // If the powerball changes the sort order...
+ this._sort.sortChange
+ .pipe(takeUntil(this._unsubscribeAll))
+ .subscribe(() => {
+ // Reset back to the first page
+ this._paginator.pageIndex = 0;
+ });
+
+ // Get products if sort or page changes
+ merge(this._sort.sortChange, this._paginator.page)
+ .pipe(
+ switchMap(() => {
+ this.isLoading = true;
+ return this._powerballService.getPowerballs(
+ this._paginator.pageIndex,
+ this._paginator.pageSize,
+ this._sort.active,
+ this._sort.direction
+ );
+ }),
+ map(() => {
+ this.isLoading = false;
+ })
+ )
+ .subscribe();
+ }
+ }
+
+ /**
+ * On destroy
+ */
+ ngOnDestroy(): void {
+ // Unsubscribe from all subscriptions
+ this._unsubscribeAll.next(null);
+ this._unsubscribeAll.complete();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Private methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Create product
+ */
+ __createProduct(): void {}
+
+ /**
+ * Toggle product details
+ *
+ * @param productId
+ */
+ __toggleDetails(productId: string): void {}
+
+ /**
+ * Track by function for ngFor loops
+ *
+ * @param index
+ * @param item
+ */
+ __trackByFn(index: number, item: any): any {
+ return item.id || index;
+ }
+}
diff --git a/src/app/modules/admin/settings/game/models/powerball-pagination.ts b/src/app/modules/admin/settings/game/models/powerball-pagination.ts
new file mode 100644
index 0000000..6866a29
--- /dev/null
+++ b/src/app/modules/admin/settings/game/models/powerball-pagination.ts
@@ -0,0 +1,8 @@
+export interface PowerballPagination {
+ length: number;
+ size: number;
+ page: number;
+ lastPage: number;
+ startIndex: number;
+ endIndex: number;
+}
diff --git a/src/app/modules/admin/settings/game/models/powerball.ts b/src/app/modules/admin/settings/game/models/powerball.ts
new file mode 100644
index 0000000..9964f0f
--- /dev/null
+++ b/src/app/modules/admin/settings/game/models/powerball.ts
@@ -0,0 +1,19 @@
+export interface Powerball {
+ id?: string;
+ nickname?: string;
+ startDate?: string;
+ finishDate?: string;
+ totalBetting?: string;
+ totalWinning?: number;
+ proceedingMoney?: number;
+ calculate?: number;
+ index?: string;
+ way?: string;
+ rank?: string;
+ bettingProgress?: string;
+ odds?: number;
+ bettingMoney?: number;
+ hitMoney?: number;
+ bettingTime?: string;
+ result?: string;
+}
diff --git a/src/app/modules/admin/settings/game/powerball.module.ts b/src/app/modules/admin/settings/game/powerball.module.ts
new file mode 100644
index 0000000..d43cd9b
--- /dev/null
+++ b/src/app/modules/admin/settings/game/powerball.module.ts
@@ -0,0 +1,42 @@
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { MatButtonModule } from '@angular/material/button';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatIconModule } from '@angular/material/icon';
+import { MatInputModule } from '@angular/material/input';
+import { MatPaginatorModule } from '@angular/material/paginator';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
+import { MatRippleModule } from '@angular/material/core';
+import { MatSortModule } from '@angular/material/sort';
+import { MatSelectModule } from '@angular/material/select';
+import { MatTooltipModule } from '@angular/material/tooltip';
+
+import { TranslocoModule } from '@ngneat/transloco';
+
+import { SharedModule } from 'app/shared/shared.module';
+
+import { COMPONENTS } from './components';
+
+import { powerballRoutes } from './powerball.routing';
+
+@NgModule({
+ declarations: [COMPONENTS],
+ imports: [
+ TranslocoModule,
+ SharedModule,
+ RouterModule.forChild(powerballRoutes),
+
+ MatButtonModule,
+ MatFormFieldModule,
+ MatIconModule,
+ MatInputModule,
+ MatPaginatorModule,
+ MatProgressBarModule,
+ MatRippleModule,
+ MatSortModule,
+ MatSelectModule,
+ MatTooltipModule,
+ ],
+})
+export class PowerballModule {}
diff --git a/src/app/modules/admin/settings/game/powerball.routing.ts b/src/app/modules/admin/settings/game/powerball.routing.ts
new file mode 100644
index 0000000..6f935ac
--- /dev/null
+++ b/src/app/modules/admin/settings/game/powerball.routing.ts
@@ -0,0 +1,24 @@
+import { Route } from '@angular/router';
+
+import { ListComponent } from './components/list.component';
+import { ViewComponent } from '../../member/user/components/view.component';
+
+import { PowerballsResolver } from './resolvers/powerball.resolver';
+import { UserResolver } from '../../dashboards/user/user.resolvers';
+
+export const powerballRoutes: Route[] = [
+ {
+ path: '',
+ component: ListComponent,
+ resolve: {
+ deposits: PowerballsResolver,
+ },
+ },
+ {
+ path: ':id',
+ component: ViewComponent,
+ resolve: {
+ users: UserResolver,
+ },
+ },
+];
diff --git a/src/app/modules/admin/settings/game/resolvers/powerball.resolver.ts b/src/app/modules/admin/settings/game/resolvers/powerball.resolver.ts
new file mode 100644
index 0000000..fbe0c30
--- /dev/null
+++ b/src/app/modules/admin/settings/game/resolvers/powerball.resolver.ts
@@ -0,0 +1,89 @@
+import { Injectable } from '@angular/core';
+import {
+ ActivatedRouteSnapshot,
+ Resolve,
+ Router,
+ RouterStateSnapshot,
+} from '@angular/router';
+import { catchError, Observable, throwError } from 'rxjs';
+
+import { Powerball } from '../models/powerball';
+import { PowerballPagination } from '../models/powerball-pagination';
+import { PowerballService } from '../services/powerball.service';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class PowerballResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(
+ private _powerballService: PowerballService,
+ private _router: Router
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable {
+ return this._powerballService
+ .getPowerballById(route.paramMap.get('id'))
+ .pipe(
+ // Error here means the requested product is not available
+ catchError((error) => {
+ // Log the error
+ console.error(error);
+
+ // Get the parent url
+ const parentUrl = state.url.split('/').slice(0, -1).join('/');
+
+ // Navigate to there
+ this._router.navigateByUrl(parentUrl);
+
+ // Throw an error
+ return throwError(error);
+ })
+ );
+ }
+}
+
+@Injectable({
+ providedIn: 'root',
+})
+export class PowerballsResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(private _powerballService: PowerballService) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable<{
+ pagination: PowerballPagination;
+ powerballs: Powerball[];
+ }> {
+ return this._powerballService.getPowerballs();
+ }
+}
diff --git a/src/app/modules/admin/settings/game/services/powerball.service.ts b/src/app/modules/admin/settings/game/services/powerball.service.ts
new file mode 100644
index 0000000..fddd2d1
--- /dev/null
+++ b/src/app/modules/admin/settings/game/services/powerball.service.ts
@@ -0,0 +1,156 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import {
+ BehaviorSubject,
+ filter,
+ map,
+ Observable,
+ of,
+ switchMap,
+ take,
+ tap,
+ throwError,
+} from 'rxjs';
+
+import { Powerball } from '../models/powerball';
+import { PowerballPagination } from '../models/powerball-pagination';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class PowerballService {
+ // Private
+ private __pagination = new BehaviorSubject(
+ undefined
+ );
+ private __powerball = new BehaviorSubject(undefined);
+ private __powerballs = new BehaviorSubject(
+ undefined
+ );
+
+ /**
+ * Constructor
+ */
+ constructor(private _httpClient: HttpClient) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Accessors
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Getter for pagination
+ */
+ get pagination$(): Observable {
+ return this.__pagination.asObservable();
+ }
+
+ /**
+ * Getter for powerball
+ */
+ get powerball$(): Observable {
+ return this.__powerball.asObservable();
+ }
+
+ /**
+ * Getter for powerballs
+ */
+ get powerballs$(): Observable {
+ return this.__powerballs.asObservable();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Get powerballs
+ *
+ *
+ * @param page
+ * @param size
+ * @param sort
+ * @param order
+ * @param search
+ */
+ getPowerballs(
+ page: number = 0,
+ size: number = 10,
+ sort: string = 'nickname',
+ order: 'asc' | 'desc' | '' = 'asc',
+ search: string = ''
+ ): Observable<{
+ pagination: PowerballPagination;
+ powerballs: Powerball[];
+ }> {
+ return this._httpClient
+ .get<{ pagination: PowerballPagination; powerballs: Powerball[] }>(
+ 'api/apps/game/powerball/powerballs',
+ {
+ params: {
+ page: '' + page,
+ size: '' + size,
+ sort,
+ order,
+ search,
+ },
+ }
+ )
+ .pipe(
+ tap((response) => {
+ this.__pagination.next(response.pagination);
+ this.__powerballs.next(response.powerballs);
+ })
+ );
+ }
+
+ /**
+ * Get product by id
+ */
+ getPowerballById(id: string | null): Observable {
+ return this.__powerballs.pipe(
+ take(1),
+ map((powerballs) => {
+ // Find the product
+ const powerball =
+ powerballs?.find((item) => item.id === id) || undefined;
+
+ // Update the product
+ this.__powerball.next(powerball);
+
+ // Return the product
+ return powerball;
+ }),
+ switchMap((product) => {
+ if (!product) {
+ return throwError('Could not found product with id of ' + id + '!');
+ }
+
+ return of(product);
+ })
+ );
+ }
+
+ /**
+ * Create product
+ */
+ createPowerball(): Observable {
+ return this.powerballs$.pipe(
+ take(1),
+ switchMap((powerballs) =>
+ this._httpClient
+ .post('api/apps/game/powerball/product', {})
+ .pipe(
+ map((newPowerball) => {
+ // Update the powerballs with the new product
+ if (!!powerballs) {
+ this.__powerballs.next([newPowerball, ...powerballs]);
+ }
+
+ // Return the new product
+ return newPowerball;
+ })
+ )
+ )
+ );
+ }
+}
diff --git a/src/app/modules/admin/settings/ladder/components/index.ts b/src/app/modules/admin/settings/ladder/components/index.ts
new file mode 100644
index 0000000..04759eb
--- /dev/null
+++ b/src/app/modules/admin/settings/ladder/components/index.ts
@@ -0,0 +1,3 @@
+import { ListComponent } from './list.component';
+
+export const COMPONENTS = [ListComponent];
diff --git a/src/app/modules/admin/settings/ladder/components/list.component.html b/src/app/modules/admin/settings/ladder/components/list.component.html
new file mode 100644
index 0000000..907126a
--- /dev/null
+++ b/src/app/modules/admin/settings/ladder/components/list.component.html
@@ -0,0 +1,350 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 전체금액
+ 배팅100만미만
+ 배팅100-300만
+ 배팅300-500만
+ 배팅500만이상
+ 당첨1000만초과
+
+
+
+
+ 아이디
+ 게임아이디
+ 닉네임
+ 게임종류
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0; else noEvolution">
+
+
+
+
+
상위
+
유저
+
게임
+
형식
+
금액
+
최종금액
+
배팅
+
데이터
+
콤프
+
롤링
+
배팅시간 등록시간
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ evolution.gameId }}
+ {{ evolution.id }}
+ {{ evolution.nickname }}
+
+
+
+
+ {{ evolution.gameInfo1 }}
+ {{ evolution.gameInfo2 }}
+ {{ evolution.gameInfo3 }}
+
+
+
+
+
+
+
+ 배팅{{ evolution.betting }} 당첨{{
+ evolution.winning
+ }}
+ 손익{{ evolution.profitLoss }}
+
+
+
+
+ 배팅 전{{ evolution.beforeBetting }} 배팅 후{{
+ evolution.afterBetting
+ }}
+ 최종금액{{ evolution.finalMoney }}
+
+
+
+
+ {{ evolution.bettingInfo1 }}
+ {{ evolution.bettingInfo2 }}
+ {{ evolution.bettingInfo3 }}
+
+
+
+
+
+
+
+
+
+ {{ evolution.comp }}
+
+
+
+
+ 본사:{{ evolution.mainofficeName }}({{
+ evolution.mainofficePercent
+ }}%,{{ evolution.mainofficePoint }}P) 대본:{{
+ evolution.branchName
+ }}({{ evolution.branchPercent }}%,{{
+ evolution.branchPoint
+ }}P) 부본:{{ evolution.divisionName }}({{
+ evolution.divisionPercent
+ }}%,{{ evolution.divisionPoint }}P) 총판:{{
+ evolution.officeName
+ }}({{ evolution.officePercent }}%,{{
+ evolution.officePoint
+ }}P) 매장:{{ evolution.storeName }}({{
+ evolution.storePercent
+ }}%,{{ evolution.storePoint }}P) 회원:{{
+ evolution.memberName
+ }}({{ evolution.memberPercent }}%,{{
+ evolution.memberPoint
+ }}P)
+
+
+
+
+ {{ evolution.bettingTime }}
+ {{ evolution.registrationTime }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ There are no evolution!
+
+
+
+
+
diff --git a/src/app/modules/admin/settings/ladder/components/list.component.ts b/src/app/modules/admin/settings/ladder/components/list.component.ts
new file mode 100644
index 0000000..629a2cb
--- /dev/null
+++ b/src/app/modules/admin/settings/ladder/components/list.component.ts
@@ -0,0 +1,190 @@
+import {
+ AfterViewInit,
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ OnDestroy,
+ OnInit,
+ ViewChild,
+ ViewEncapsulation,
+} from '@angular/core';
+import {
+ FormBuilder,
+ FormControl,
+ FormGroup,
+ Validators,
+} from '@angular/forms';
+import { MatCheckboxChange } from '@angular/material/checkbox';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import {
+ debounceTime,
+ map,
+ merge,
+ Observable,
+ Subject,
+ switchMap,
+ takeUntil,
+} from 'rxjs';
+import { fuseAnimations } from '@fuse/animations';
+import { FuseConfirmationService } from '@fuse/services/confirmation';
+
+import { Evolution } from '../models/evolution';
+import { EvolutionPagination } from '../models/evolution-pagination';
+import { EvolutionService } from '../services/evolution.service';
+
+@Component({
+ selector: 'evolution-list',
+ templateUrl: './list.component.html',
+ styles: [
+ /* language=SCSS */
+ `
+ .inventory-grid {
+ grid-template-columns: 60px auto 40px;
+
+ @screen sm {
+ grid-template-columns: 60px auto 60px 72px;
+ }
+
+ @screen md {
+ grid-template-columns: 60px 60px auto 112px 72px;
+ }
+
+ @screen lg {
+ grid-template-columns: 60px 60px auto 112px 96px 96px 72px;
+ }
+ }
+ `,
+ ],
+ encapsulation: ViewEncapsulation.None,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ animations: fuseAnimations,
+})
+export class ListComponent implements OnInit, AfterViewInit, OnDestroy {
+ @ViewChild(MatPaginator) private _paginator!: MatPaginator;
+ @ViewChild(MatSort) private _sort!: MatSort;
+
+ evolutions$!: Observable;
+
+ isLoading = false;
+ searchInputControl = new FormControl();
+ selectedEvolution?: Evolution;
+ pagination?: EvolutionPagination;
+
+ private _unsubscribeAll: Subject = new Subject();
+
+ /**
+ * Constructor
+ */
+ constructor(
+ private _changeDetectorRef: ChangeDetectorRef,
+ private _fuseConfirmationService: FuseConfirmationService,
+ private _formBuilder: FormBuilder,
+ private _evolutionService: EvolutionService
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Lifecycle hooks
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * On init
+ */
+ ngOnInit(): void {
+ // Get the pagination
+ this._evolutionService.pagination$
+ .pipe(takeUntil(this._unsubscribeAll))
+ .subscribe((pagination: EvolutionPagination | undefined) => {
+ // Update the pagination
+ this.pagination = pagination;
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+ });
+
+ // Get the products
+ this.evolutions$ = this._evolutionService.evolutions$;
+ }
+
+ /**
+ * After view init
+ */
+ ngAfterViewInit(): void {
+ if (this._sort && this._paginator) {
+ // Set the initial sort
+ this._sort.sort({
+ id: 'nickname',
+ start: 'asc',
+ disableClear: true,
+ });
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+
+ // If the evolution changes the sort order...
+ this._sort.sortChange
+ .pipe(takeUntil(this._unsubscribeAll))
+ .subscribe(() => {
+ // Reset back to the first page
+ this._paginator.pageIndex = 0;
+ });
+
+ // Get products if sort or page changes
+ merge(this._sort.sortChange, this._paginator.page)
+ .pipe(
+ switchMap(() => {
+ this.isLoading = true;
+ return this._evolutionService.getEvolutions(
+ this._paginator.pageIndex,
+ this._paginator.pageSize,
+ this._sort.active,
+ this._sort.direction
+ );
+ }),
+ map(() => {
+ this.isLoading = false;
+ })
+ )
+ .subscribe();
+ }
+ }
+
+ /**
+ * On destroy
+ */
+ ngOnDestroy(): void {
+ // Unsubscribe from all subscriptions
+ this._unsubscribeAll.next(null);
+ this._unsubscribeAll.complete();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Private methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Create product
+ */
+ __createProduct(): void {}
+
+ /**
+ * Toggle product details
+ *
+ * @param productId
+ */
+ __toggleDetails(productId: string): void {}
+
+ /**
+ * Track by function for ngFor loops
+ *
+ * @param index
+ * @param item
+ */
+ __trackByFn(index: number, item: any): any {
+ return item.id || index;
+ }
+}
diff --git a/src/app/modules/admin/settings/ladder/evolution.module.ts b/src/app/modules/admin/settings/ladder/evolution.module.ts
new file mode 100644
index 0000000..7fb584a
--- /dev/null
+++ b/src/app/modules/admin/settings/ladder/evolution.module.ts
@@ -0,0 +1,42 @@
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+
+import { MatButtonModule } from '@angular/material/button';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatIconModule } from '@angular/material/icon';
+import { MatInputModule } from '@angular/material/input';
+import { MatPaginatorModule } from '@angular/material/paginator';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
+import { MatRippleModule } from '@angular/material/core';
+import { MatSortModule } from '@angular/material/sort';
+import { MatSelectModule } from '@angular/material/select';
+import { MatTooltipModule } from '@angular/material/tooltip';
+
+import { TranslocoModule } from '@ngneat/transloco';
+
+import { SharedModule } from 'app/shared/shared.module';
+
+import { COMPONENTS } from './components';
+
+import { evolutionRoutes } from './evolution.routing';
+
+@NgModule({
+ declarations: [COMPONENTS],
+ imports: [
+ TranslocoModule,
+ SharedModule,
+ RouterModule.forChild(evolutionRoutes),
+
+ MatButtonModule,
+ MatFormFieldModule,
+ MatIconModule,
+ MatInputModule,
+ MatPaginatorModule,
+ MatProgressBarModule,
+ MatRippleModule,
+ MatSortModule,
+ MatSelectModule,
+ MatTooltipModule,
+ ],
+})
+export class EvolutionModule {}
diff --git a/src/app/modules/admin/settings/ladder/evolution.routing.ts b/src/app/modules/admin/settings/ladder/evolution.routing.ts
new file mode 100644
index 0000000..78500d7
--- /dev/null
+++ b/src/app/modules/admin/settings/ladder/evolution.routing.ts
@@ -0,0 +1,15 @@
+import { Route } from '@angular/router';
+
+import { ListComponent } from './components/list.component';
+
+import { EvolutionsResolver } from './resolvers/evolution.resolver';
+
+export const evolutionRoutes: Route[] = [
+ {
+ path: '',
+ component: ListComponent,
+ resolve: {
+ deposits: EvolutionsResolver,
+ },
+ },
+];
diff --git a/src/app/modules/admin/settings/ladder/models/evolution-pagination.ts b/src/app/modules/admin/settings/ladder/models/evolution-pagination.ts
new file mode 100644
index 0000000..d1bff25
--- /dev/null
+++ b/src/app/modules/admin/settings/ladder/models/evolution-pagination.ts
@@ -0,0 +1,8 @@
+export interface EvolutionPagination {
+ length: number;
+ size: number;
+ page: number;
+ lastPage: number;
+ startIndex: number;
+ endIndex: number;
+}
diff --git a/src/app/modules/admin/settings/ladder/models/evolution.ts b/src/app/modules/admin/settings/ladder/models/evolution.ts
new file mode 100644
index 0000000..8d6f322
--- /dev/null
+++ b/src/app/modules/admin/settings/ladder/models/evolution.ts
@@ -0,0 +1,58 @@
+export interface Evolution {
+ id?: string;
+ startDate?: string;
+ finishDate?: string;
+ availableBetting?: number;
+ bettingMoney?: number;
+ winningMoney?: number;
+ cancel?: number;
+ betWinCancel?: number;
+ mainofficeRolling?: number;
+ branchRolling?: number;
+ divisionRolling?: number;
+ officeRolling?: number;
+ storeRolling?: number;
+ memberRolling?: number;
+ totalrolling?: number;
+ highRank?: string;
+ gameId?: string;
+ nickname?: string;
+ gameName?: string;
+ gameInfo1?: string;
+ gameInfo2?: string;
+ gameInfo3?: string;
+ form?: string;
+ betting?: number;
+ profitLoss?: number;
+ beforeWinning?: number;
+ winning?: number;
+ afterWinning?: number;
+ beforeBetting?: number;
+ afterBetting?: number;
+ finalMoney?: number;
+ bettingInfo1?: string;
+ bettingInfo2?: number;
+ bettingInfo3?: number;
+ data?: string;
+ comp?: string;
+ mainofficeName?: string;
+ mainofficePercent?: number;
+ mainofficePoint?: number;
+ branchName?: string;
+ branchPercent?: number;
+ branchPoint?: number;
+ divisionName?: string;
+ divisionPercent?: number;
+ divisionPoint?: number;
+ officeName?: string;
+ officePercent?: number;
+ officePoint?: number;
+ storeName?: string;
+ storePercent?: number;
+ storePoint?: number;
+ memberName?: string;
+ memberPercent?: number;
+ memberPoint?: number;
+ bettingTime?: string;
+ registrationTime?: string;
+}
diff --git a/src/app/modules/admin/settings/ladder/resolvers/evolution.resolver.ts b/src/app/modules/admin/settings/ladder/resolvers/evolution.resolver.ts
new file mode 100644
index 0000000..4fc4dd8
--- /dev/null
+++ b/src/app/modules/admin/settings/ladder/resolvers/evolution.resolver.ts
@@ -0,0 +1,89 @@
+import { Injectable } from '@angular/core';
+import {
+ ActivatedRouteSnapshot,
+ Resolve,
+ Router,
+ RouterStateSnapshot,
+} from '@angular/router';
+import { catchError, Observable, throwError } from 'rxjs';
+
+import { Evolution } from '../models/evolution';
+import { EvolutionPagination } from '../models/evolution-pagination';
+import { EvolutionService } from '../services/evolution.service';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class EvolutionResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(
+ private _evolutionService: EvolutionService,
+ private _router: Router
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable {
+ return this._evolutionService
+ .getEvolutionById(route.paramMap.get('id'))
+ .pipe(
+ // Error here means the requested product is not available
+ catchError((error) => {
+ // Log the error
+ console.error(error);
+
+ // Get the parent url
+ const parentUrl = state.url.split('/').slice(0, -1).join('/');
+
+ // Navigate to there
+ this._router.navigateByUrl(parentUrl);
+
+ // Throw an error
+ return throwError(error);
+ })
+ );
+ }
+}
+
+@Injectable({
+ providedIn: 'root',
+})
+export class EvolutionsResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(private _evolutionService: EvolutionService) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable<{
+ pagination: EvolutionPagination;
+ evolutions: Evolution[];
+ }> {
+ return this._evolutionService.getEvolutions();
+ }
+}
diff --git a/src/app/modules/admin/settings/ladder/services/evolution.service.ts b/src/app/modules/admin/settings/ladder/services/evolution.service.ts
new file mode 100644
index 0000000..396f0f7
--- /dev/null
+++ b/src/app/modules/admin/settings/ladder/services/evolution.service.ts
@@ -0,0 +1,156 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import {
+ BehaviorSubject,
+ filter,
+ map,
+ Observable,
+ of,
+ switchMap,
+ take,
+ tap,
+ throwError,
+} from 'rxjs';
+
+import { Evolution } from '../models/evolution';
+import { EvolutionPagination } from '../models/evolution-pagination';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class EvolutionService {
+ // Private
+ private __pagination = new BehaviorSubject(
+ undefined
+ );
+ private __evolution = new BehaviorSubject(undefined);
+ private __evolutions = new BehaviorSubject(
+ undefined
+ );
+
+ /**
+ * Constructor
+ */
+ constructor(private _httpClient: HttpClient) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Accessors
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Getter for pagination
+ */
+ get pagination$(): Observable {
+ return this.__pagination.asObservable();
+ }
+
+ /**
+ * Getter for evolution
+ */
+ get evolution$(): Observable {
+ return this.__evolution.asObservable();
+ }
+
+ /**
+ * Getter for evolutions
+ */
+ get evolutions$(): Observable {
+ return this.__evolutions.asObservable();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Get evolutions
+ *
+ *
+ * @param page
+ * @param size
+ * @param sort
+ * @param order
+ * @param search
+ */
+ getEvolutions(
+ page: number = 0,
+ size: number = 10,
+ sort: string = 'nickname',
+ order: 'asc' | 'desc' | '' = 'asc',
+ search: string = ''
+ ): Observable<{
+ pagination: EvolutionPagination;
+ evolutions: Evolution[];
+ }> {
+ return this._httpClient
+ .get<{ pagination: EvolutionPagination; evolutions: Evolution[] }>(
+ 'api/apps/game/evolution/evolutions',
+ {
+ params: {
+ page: '' + page,
+ size: '' + size,
+ sort,
+ order,
+ search,
+ },
+ }
+ )
+ .pipe(
+ tap((response) => {
+ this.__pagination.next(response.pagination);
+ this.__evolutions.next(response.evolutions);
+ })
+ );
+ }
+
+ /**
+ * Get product by id
+ */
+ getEvolutionById(id: string | null): Observable {
+ return this.__evolutions.pipe(
+ take(1),
+ map((evolutions) => {
+ // Find the product
+ const evolution =
+ evolutions?.find((item) => item.id === id) || undefined;
+
+ // Update the product
+ this.__evolution.next(evolution);
+
+ // Return the product
+ return evolution;
+ }),
+ switchMap((product) => {
+ if (!product) {
+ return throwError('Could not found product with id of ' + id + '!');
+ }
+
+ return of(product);
+ })
+ );
+ }
+
+ /**
+ * Create product
+ */
+ createEvolution(): Observable {
+ return this.evolutions$.pipe(
+ take(1),
+ switchMap((evolutions) =>
+ this._httpClient
+ .post('api/apps/game/evolution/product', {})
+ .pipe(
+ map((newEvolution) => {
+ // Update the evolutions with the new product
+ if (!!evolutions) {
+ this.__evolutions.next([newEvolution, ...evolutions]);
+ }
+
+ // Return the new product
+ return newEvolution;
+ })
+ )
+ )
+ );
+ }
+}
diff --git a/src/assets/i18n/ko.json b/src/assets/i18n/ko.json
index e9e09e7..029ce5b 100644
--- a/src/assets/i18n/ko.json
+++ b/src/assets/i18n/ko.json
@@ -22,5 +22,6 @@
"Casino": "카지노배팅리스트",
"Evolution": "에볼루션배팅리스트",
"Slot": "슬롯배팅리스트",
- "Current User": "현재접속자 & 쪽지전송"
+ "Current User": "현재접속자 & 쪽지전송",
+ "Basic-Setting": "사이트 기본설정"
}