diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts
index 20016e4..ca868c3 100644
--- a/src/app/app.routing.ts
+++ b/src/app/app.routing.ts
@@ -445,6 +445,32 @@ export const appRoutes: Route[] = [
},
],
},
+ {
+ path: 'board',
+ children: [
+ {
+ path: 'notice',
+ loadChildren: () =>
+ import('app/modules/admin/board/notice/notice.module').then(
+ (m: any) => m.NoticeModule
+ ),
+ },
+ {
+ path: 'notice-oneline',
+ loadChildren: () =>
+ import(
+ 'app/modules/admin/board/notice-oneline/notice-oneline.module'
+ ).then((m: any) => m.NoticeOnelineModule),
+ },
+ {
+ path: 'popup',
+ loadChildren: () =>
+ import('app/modules/admin/board/popup/popup.module').then(
+ (m: any) => m.PopupModule
+ ),
+ },
+ ],
+ },
],
},
];
diff --git a/src/app/mock-api/apps/board/notice-oneline/api.ts b/src/app/mock-api/apps/board/notice-oneline/api.ts
new file mode 100644
index 0000000..af9ed95
--- /dev/null
+++ b/src/app/mock-api/apps/board/notice-oneline/api.ts
@@ -0,0 +1,223 @@
+import { Injectable } from '@angular/core';
+import { assign, cloneDeep } from 'lodash-es';
+import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
+import { noticeOnelines as noticeOnelinesData } from './data';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class BoardNoticeOnelineMockApi {
+ private _noticeOnelines: any[] = noticeOnelinesData;
+
+ /**
+ * Constructor
+ */
+ constructor(private _fuseMockApiService: FuseMockApiService) {
+ // Register Mock API handlers
+ this.registerHandlers();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Register Mock API handlers
+ */
+ registerHandlers(): void {
+ // -----------------------------------------------------------------------------------------------------
+ // @ NoticeOnelines - GET
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onGet('api/apps/board/notice-oneline/notice-onelines', 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 noticeOnelines
+ let noticeOnelines: any[] | null = cloneDeep(this._noticeOnelines);
+
+ // Sort the noticeOnelines
+ if (sort === 'sku' || sort === 'name' || sort === 'active') {
+ noticeOnelines.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 {
+ noticeOnelines.sort((a, b) =>
+ order === 'asc' ? a[sort] - b[sort] : b[sort] - a[sort]
+ );
+ }
+
+ // If search exists...
+ if (search) {
+ // Filter the noticeOnelines
+ noticeOnelines = noticeOnelines.filter(
+ (contact: any) =>
+ contact.name &&
+ contact.name.toLowerCase().includes(search.toLowerCase())
+ );
+ }
+
+ // Paginate - Start
+ const noticeOnelinesLength = noticeOnelines.length;
+
+ // Calculate pagination details
+ const begin = page * size;
+ const end = Math.min(size * (page + 1), noticeOnelinesLength);
+ const lastPage = Math.max(Math.ceil(noticeOnelinesLength / size), 1);
+
+ // Prepare the pagination object
+ let pagination = {};
+
+ // If the requested page number is bigger than
+ // the last possible page number, return null for
+ // noticeOnelines but also send the last possible page so
+ // the app can navigate to there
+ if (page > lastPage) {
+ noticeOnelines = null;
+ pagination = {
+ lastPage,
+ };
+ } else {
+ // Paginate the results by size
+ noticeOnelines = noticeOnelines.slice(begin, end);
+
+ // Prepare the pagination mock-api
+ pagination = {
+ length: noticeOnelinesLength,
+ size: size,
+ page: page,
+ lastPage: lastPage,
+ startIndex: begin,
+ endIndex: end - 1,
+ };
+ }
+
+ // Return the response
+ return [
+ 200,
+ {
+ noticeOnelines,
+ pagination,
+ },
+ ];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ NoticeOneline - GET
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onGet('api/apps/board/notice-oneline/notice-oneline')
+ .reply(({ request }) => {
+ // Get the id from the params
+ const id = request.params.get('id');
+
+ // Clone the noticeOnelines
+ const noticeOnelines = cloneDeep(this._noticeOnelines);
+
+ // Find the noticeOneline
+ const noticeOneline = noticeOnelines.find(
+ (item: any) => item.id === id
+ );
+
+ // Return the response
+ return [200, noticeOneline];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ NoticeOneline - POST
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onPost('api/apps/board/notice-oneline/notice-oneline')
+ .reply(() => {
+ // Generate a new noticeOneline
+ const newNoticeOneline = {
+ id: FuseMockApiUtils.guid(),
+ category: '',
+ name: 'A New User',
+ description: '',
+ tags: [],
+ sku: '',
+ barcode: '',
+ brand: '',
+ vendor: '',
+ stock: '',
+ reserved: '',
+ cost: '',
+ basePrice: '',
+ taxPercent: '',
+ price: '',
+ weight: '',
+ thumbnail: '',
+ images: [],
+ active: false,
+ };
+
+ // Unshift the new noticeOneline
+ this._noticeOnelines.unshift(newNoticeOneline);
+
+ // Return the response
+ return [200, newNoticeOneline];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ NoticeOneline - PATCH
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onPatch('api/apps/board/notice-oneline/notice-oneline')
+ .reply(({ request }) => {
+ // Get the id and noticeOneline
+ const id = request.body.id;
+ const noticeOneline = cloneDeep(request.body.noticeOneline);
+
+ // Prepare the updated noticeOneline
+ let updatedNoticeOneline = null;
+
+ // Find the noticeOneline and update it
+ this._noticeOnelines.forEach((item, index, noticeOnelines) => {
+ if (item.id === id) {
+ // Update the noticeOneline
+ noticeOnelines[index] = assign(
+ {},
+ noticeOnelines[index],
+ noticeOneline
+ );
+
+ // Store the updated noticeOneline
+ updatedNoticeOneline = noticeOnelines[index];
+ }
+ });
+
+ // Return the response
+ return [200, updatedNoticeOneline];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ NoticeOneline - DELETE
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onDelete('api/apps/board/notice-oneline/notice-oneline')
+ .reply(({ request }) => {
+ // Get the id
+ const id = request.params.get('id');
+
+ // Find the noticeOneline and delete it
+ this._noticeOnelines.forEach((item, index) => {
+ if (item.id === id) {
+ this._noticeOnelines.splice(index, 1);
+ }
+ });
+
+ // Return the response
+ return [200, true];
+ });
+ }
+}
diff --git a/src/app/mock-api/apps/board/notice-oneline/data.ts b/src/app/mock-api/apps/board/notice-oneline/data.ts
new file mode 100644
index 0000000..3b7cabc
--- /dev/null
+++ b/src/app/mock-api/apps/board/notice-oneline/data.ts
@@ -0,0 +1,33 @@
+/* eslint-disable */
+
+export const noticeOnelines = [
+ {
+ id: 'on00',
+ totalPartnerCount: '5',
+ totalHoldingMoney: 303675,
+ totalComp: 108933,
+ total: 412608,
+ branchCount: 1,
+ divisionCount: 1,
+ officeCount: 1,
+ storeCount: 1,
+ memberCount: 1,
+ nickname: 'on00',
+ accountHolder: '11',
+ phoneNumber: '010-1111-1111',
+ calculateType: '롤링',
+ ownCash: 50000,
+ ownComp: 1711,
+ ownCoupon: 50000,
+ gameMoney: 0,
+ todayComp: 0,
+ totalDeposit: 0,
+ totalWithdraw: 0,
+ balance: 0,
+ registDate: '2022-06-12 15:38',
+ finalSigninDate: '',
+ ip: '',
+ state: '정상',
+ note: '',
+ },
+];
diff --git a/src/app/mock-api/apps/board/notice/api.ts b/src/app/mock-api/apps/board/notice/api.ts
new file mode 100644
index 0000000..af86cb9
--- /dev/null
+++ b/src/app/mock-api/apps/board/notice/api.ts
@@ -0,0 +1,217 @@
+import { Injectable } from '@angular/core';
+import { assign, cloneDeep } from 'lodash-es';
+import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
+import { notices as noticesData } from './data';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class BoardNoticeMockApi {
+ private _notices: any[] = noticesData;
+
+ /**
+ * Constructor
+ */
+ constructor(private _fuseMockApiService: FuseMockApiService) {
+ // Register Mock API handlers
+ this.registerHandlers();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Register Mock API handlers
+ */
+ registerHandlers(): void {
+ // -----------------------------------------------------------------------------------------------------
+ // @ Notices - GET
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onGet('api/apps/board/notice/notices', 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 notices
+ let notices: any[] | null = cloneDeep(this._notices);
+
+ // Sort the notices
+ if (sort === 'sku' || sort === 'name' || sort === 'active') {
+ notices.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 {
+ notices.sort((a, b) =>
+ order === 'asc' ? a[sort] - b[sort] : b[sort] - a[sort]
+ );
+ }
+
+ // If search exists...
+ if (search) {
+ // Filter the notices
+ notices = notices.filter(
+ (contact: any) =>
+ contact.name &&
+ contact.name.toLowerCase().includes(search.toLowerCase())
+ );
+ }
+
+ // Paginate - Start
+ const noticesLength = notices.length;
+
+ // Calculate pagination details
+ const begin = page * size;
+ const end = Math.min(size * (page + 1), noticesLength);
+ const lastPage = Math.max(Math.ceil(noticesLength / size), 1);
+
+ // Prepare the pagination object
+ let pagination = {};
+
+ // If the requested page number is bigger than
+ // the last possible page number, return null for
+ // notices but also send the last possible page so
+ // the app can navigate to there
+ if (page > lastPage) {
+ notices = null;
+ pagination = {
+ lastPage,
+ };
+ } else {
+ // Paginate the results by size
+ notices = notices.slice(begin, end);
+
+ // Prepare the pagination mock-api
+ pagination = {
+ length: noticesLength,
+ size: size,
+ page: page,
+ lastPage: lastPage,
+ startIndex: begin,
+ endIndex: end - 1,
+ };
+ }
+
+ // Return the response
+ return [
+ 200,
+ {
+ notices,
+ pagination,
+ },
+ ];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Notice - GET
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onGet('api/apps/board/notice/notice')
+ .reply(({ request }) => {
+ // Get the id from the params
+ const id = request.params.get('id');
+
+ // Clone the notices
+ const notices = cloneDeep(this._notices);
+
+ // Find the notice
+ const notice = notices.find((item: any) => item.id === id);
+
+ // Return the response
+ return [200, notice];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Notice - POST
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onPost('api/apps/board/notice/notice')
+ .reply(() => {
+ // Generate a new notice
+ const newNotice = {
+ id: FuseMockApiUtils.guid(),
+ category: '',
+ name: 'A New User',
+ description: '',
+ tags: [],
+ sku: '',
+ barcode: '',
+ brand: '',
+ vendor: '',
+ stock: '',
+ reserved: '',
+ cost: '',
+ basePrice: '',
+ taxPercent: '',
+ price: '',
+ weight: '',
+ thumbnail: '',
+ images: [],
+ active: false,
+ };
+
+ // Unshift the new notice
+ this._notices.unshift(newNotice);
+
+ // Return the response
+ return [200, newNotice];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Notice - PATCH
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onPatch('api/apps/board/notice/notice')
+ .reply(({ request }) => {
+ // Get the id and notice
+ const id = request.body.id;
+ const notice = cloneDeep(request.body.notice);
+
+ // Prepare the updated notice
+ let updatedNotice = null;
+
+ // Find the notice and update it
+ this._notices.forEach((item, index, notices) => {
+ if (item.id === id) {
+ // Update the notice
+ notices[index] = assign({}, notices[index], notice);
+
+ // Store the updated notice
+ updatedNotice = notices[index];
+ }
+ });
+
+ // Return the response
+ return [200, updatedNotice];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Notice - DELETE
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onDelete('api/apps/board/notice/notice')
+ .reply(({ request }) => {
+ // Get the id
+ const id = request.params.get('id');
+
+ // Find the notice and delete it
+ this._notices.forEach((item, index) => {
+ if (item.id === id) {
+ this._notices.splice(index, 1);
+ }
+ });
+
+ // Return the response
+ return [200, true];
+ });
+ }
+}
diff --git a/src/app/mock-api/apps/board/notice/data.ts b/src/app/mock-api/apps/board/notice/data.ts
new file mode 100644
index 0000000..85b9f0a
--- /dev/null
+++ b/src/app/mock-api/apps/board/notice/data.ts
@@ -0,0 +1,33 @@
+/* eslint-disable */
+
+export const notices = [
+ {
+ id: 'on00',
+ totalPartnerCount: '5',
+ totalHoldingMoney: 303675,
+ totalComp: 108933,
+ total: 412608,
+ branchCount: 1,
+ divisionCount: 1,
+ officeCount: 1,
+ storeCount: 1,
+ memberCount: 1,
+ nickname: 'on00',
+ accountHolder: '11',
+ phoneNumber: '010-1111-1111',
+ calculateType: '롤링',
+ ownCash: 50000,
+ ownComp: 1711,
+ ownCoupon: 50000,
+ gameMoney: 0,
+ todayComp: 0,
+ totalDeposit: 0,
+ totalWithdraw: 0,
+ balance: 0,
+ registDate: '2022-06-12 15:38',
+ finalSigninDate: '',
+ ip: '',
+ state: '정상',
+ note: '',
+ },
+];
diff --git a/src/app/mock-api/apps/board/popup/api.ts b/src/app/mock-api/apps/board/popup/api.ts
new file mode 100644
index 0000000..2cdc93a
--- /dev/null
+++ b/src/app/mock-api/apps/board/popup/api.ts
@@ -0,0 +1,215 @@
+import { Injectable } from '@angular/core';
+import { assign, cloneDeep } from 'lodash-es';
+import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api';
+import { popups as popupsData } from './data';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class BoardPopupMockApi {
+ private _popups: any[] = popupsData;
+
+ /**
+ * Constructor
+ */
+ constructor(private _fuseMockApiService: FuseMockApiService) {
+ // Register Mock API handlers
+ this.registerHandlers();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Register Mock API handlers
+ */
+ registerHandlers(): void {
+ // -----------------------------------------------------------------------------------------------------
+ // @ Popups - GET
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onGet('api/apps/board/popup/popups', 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 popups
+ let popups: any[] | null = cloneDeep(this._popups);
+
+ // Sort the popups
+ if (sort === 'sku' || sort === 'name' || sort === 'active') {
+ popups.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 {
+ popups.sort((a, b) =>
+ order === 'asc' ? a[sort] - b[sort] : b[sort] - a[sort]
+ );
+ }
+
+ // If search exists...
+ if (search) {
+ // Filter the popups
+ popups = popups.filter(
+ (contact: any) =>
+ contact.name &&
+ contact.name.toLowerCase().includes(search.toLowerCase())
+ );
+ }
+
+ // Paginate - Start
+ const popupsLength = popups.length;
+
+ // Calculate pagination details
+ const begin = page * size;
+ const end = Math.min(size * (page + 1), popupsLength);
+ const lastPage = Math.max(Math.ceil(popupsLength / size), 1);
+
+ // Prepare the pagination object
+ let pagination = {};
+
+ // If the requested page number is bigger than
+ // the last possible page number, return null for
+ // popups but also send the last possible page so
+ // the app can navigate to there
+ if (page > lastPage) {
+ popups = null;
+ pagination = {
+ lastPage,
+ };
+ } else {
+ // Paginate the results by size
+ popups = popups.slice(begin, end);
+
+ // Prepare the pagination mock-api
+ pagination = {
+ length: popupsLength,
+ size: size,
+ page: page,
+ lastPage: lastPage,
+ startIndex: begin,
+ endIndex: end - 1,
+ };
+ }
+
+ // Return the response
+ return [
+ 200,
+ {
+ popups,
+ pagination,
+ },
+ ];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Popup - GET
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onGet('api/apps/board/popup/popup')
+ .reply(({ request }) => {
+ // Get the id from the params
+ const id = request.params.get('id');
+
+ // Clone the popups
+ const popups = cloneDeep(this._popups);
+
+ // Find the popup
+ const popup = popups.find((item: any) => item.id === id);
+
+ // Return the response
+ return [200, popup];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Popup - POST
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService.onPost('api/apps/board/popup/popup').reply(() => {
+ // Generate a new popup
+ const newPopup = {
+ id: FuseMockApiUtils.guid(),
+ category: '',
+ name: 'A New User',
+ description: '',
+ tags: [],
+ sku: '',
+ barcode: '',
+ brand: '',
+ vendor: '',
+ stock: '',
+ reserved: '',
+ cost: '',
+ basePrice: '',
+ taxPercent: '',
+ price: '',
+ weight: '',
+ thumbnail: '',
+ images: [],
+ active: false,
+ };
+
+ // Unshift the new popup
+ this._popups.unshift(newPopup);
+
+ // Return the response
+ return [200, newPopup];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Popup - PATCH
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onPatch('api/apps/board/popup/popup')
+ .reply(({ request }) => {
+ // Get the id and popup
+ const id = request.body.id;
+ const popup = cloneDeep(request.body.popup);
+
+ // Prepare the updated popup
+ let updatedPopup = null;
+
+ // Find the popup and update it
+ this._popups.forEach((item, index, popups) => {
+ if (item.id === id) {
+ // Update the popup
+ popups[index] = assign({}, popups[index], popup);
+
+ // Store the updated popup
+ updatedPopup = popups[index];
+ }
+ });
+
+ // Return the response
+ return [200, updatedPopup];
+ });
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Popup - DELETE
+ // -----------------------------------------------------------------------------------------------------
+ this._fuseMockApiService
+ .onDelete('api/apps/board/popup/popup')
+ .reply(({ request }) => {
+ // Get the id
+ const id = request.params.get('id');
+
+ // Find the popup and delete it
+ this._popups.forEach((item, index) => {
+ if (item.id === id) {
+ this._popups.splice(index, 1);
+ }
+ });
+
+ // Return the response
+ return [200, true];
+ });
+ }
+}
diff --git a/src/app/mock-api/apps/board/popup/data.ts b/src/app/mock-api/apps/board/popup/data.ts
new file mode 100644
index 0000000..2945bfb
--- /dev/null
+++ b/src/app/mock-api/apps/board/popup/data.ts
@@ -0,0 +1,33 @@
+/* eslint-disable */
+
+export const popups = [
+ {
+ id: 'on00',
+ totalPartnerCount: '5',
+ totalHoldingMoney: 303675,
+ totalComp: 108933,
+ total: 412608,
+ branchCount: 1,
+ divisionCount: 1,
+ officeCount: 1,
+ storeCount: 1,
+ memberCount: 1,
+ nickname: 'on00',
+ accountHolder: '11',
+ phoneNumber: '010-1111-1111',
+ calculateType: '롤링',
+ ownCash: 50000,
+ ownComp: 1711,
+ ownCoupon: 50000,
+ gameMoney: 0,
+ todayComp: 0,
+ totalDeposit: 0,
+ totalWithdraw: 0,
+ balance: 0,
+ registDate: '2022-06-12 15:38',
+ finalSigninDate: '',
+ ip: '',
+ state: '정상',
+ note: '',
+ },
+];
diff --git a/src/app/mock-api/common/navigation/data.ts b/src/app/mock-api/common/navigation/data.ts
index 805f225..3f0f8fd 100644
--- a/src/app/mock-api/common/navigation/data.ts
+++ b/src/app/mock-api/common/navigation/data.ts
@@ -357,6 +357,36 @@ export const defaultNavigation: FuseNavigationItem[] = [
},
],
},
+ {
+ id: 'board',
+ title: 'Board',
+ subtitle: 'board managements',
+ type: 'group',
+ icon: 'heroicons_outline:home',
+ children: [
+ {
+ id: 'board.notice',
+ title: 'Notice',
+ type: 'basic',
+ icon: 'heroicons_outline:academic-cap',
+ link: '/board/notice',
+ },
+ {
+ id: 'board.notice-oneline',
+ title: 'Notice Oneline',
+ type: 'basic',
+ icon: 'heroicons_outline:academic-cap',
+ link: '/board/notice-oneline',
+ },
+ {
+ id: 'board.popup',
+ title: 'Popup',
+ type: 'basic',
+ icon: 'heroicons_outline:academic-cap',
+ link: '/board/popup',
+ },
+ ],
+ },
];
export const compactNavigation: FuseNavigationItem[] = [
{
diff --git a/src/app/mock-api/index.ts b/src/app/mock-api/index.ts
index defd1b9..f3aa174 100644
--- a/src/app/mock-api/index.ts
+++ b/src/app/mock-api/index.ts
@@ -60,6 +60,9 @@ import { ReportSessioninOverlapMockApi } from './apps/report/sessionin-overlap/a
import { ReportSessioninAdminMockApi } from './apps/report/sessionin-admin/api';
import { ReportExcelLogMockApi } from './apps/report/excel-log/api';
import { ReportLoosingMockApi } from './apps/report/loosing/api';
+import { BoardNoticeMockApi } from './apps/board/notice/api';
+import { BoardNoticeOnelineMockApi } from './apps/board/notice-oneline/api';
+import { BoardPopupMockApi } from './apps/board/popup/api';
export const mockApiServices = [
AcademyMockApi,
@@ -124,4 +127,7 @@ export const mockApiServices = [
ReportSessioninAdminMockApi,
ReportExcelLogMockApi,
ReportLoosingMockApi,
+ BoardNoticeMockApi,
+ BoardNoticeOnelineMockApi,
+ BoardPopupMockApi,
];
diff --git a/src/app/modules/admin/board/notice-oneline/components/index.ts b/src/app/modules/admin/board/notice-oneline/components/index.ts
new file mode 100644
index 0000000..04759eb
--- /dev/null
+++ b/src/app/modules/admin/board/notice-oneline/components/index.ts
@@ -0,0 +1,3 @@
+import { ListComponent } from './list.component';
+
+export const COMPONENTS = [ListComponent];
diff --git a/src/app/modules/admin/board/notice-oneline/components/list.component.html b/src/app/modules/admin/board/notice-oneline/components/list.component.html
new file mode 100644
index 0000000..c1f0b23
--- /dev/null
+++ b/src/app/modules/admin/board/notice-oneline/components/list.component.html
@@ -0,0 +1,359 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 40
+ 60
+ 80
+ 100
+
+
+
+
+ LV.1
+ LV.2
+ LV.3
+ LV.4
+
+
+
+
+ 정상
+ 대기
+ 탈퇴
+ 휴면
+ 블랙
+ 정지
+
+
+
+
+ 카지노제한
+ 슬롯제한
+
+
+
+
+ 계좌입금
+
+
+
+
+ 카지노콤프
+ 슬롯콤프
+ 배팅콤프
+ 첫충콤프
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0; else noNoticeOneline">
+
+
+
+
+
요율
+
상부트리
+
관리
+
매장수
+
회원수
+
아이디
+
닉네임
+
예금주
+
연락처
+
정산
+
보유금
+
게임중머니
+
카지노->캐쉬
+
금일콤프
+
총입출
+
로그
+
상태
+
회원수
+
비고
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ noticeOneline.id }}
+
+
+
+
+
+ {{ noticeOneline.nickname }}
+
+
+
+ {{ noticeOneline.accountHolder }}
+
+
+
+ {{ noticeOneline.phoneNumber }}
+
+
+
+ {{ noticeOneline.calculateType }}
+
+
+
+ 캐쉬{{ noticeOneline.ownCash }} 콤프{{
+ noticeOneline.ownComp
+ }}
+ 쿠폰{{ noticeOneline.ownCoupon }}
+
+
+
+ {{ noticeOneline.gameMoney }}
+
+
+
+
+
+
+
+
+ {{ noticeOneline.todayComp }}P
+
+
+
+ 입금{{ noticeOneline.totalDeposit }} 출금{{
+ noticeOneline.totalWithdraw
+ }}
+ 차익{{ noticeOneline.balance }}
+
+
+
+ 가입{{ noticeOneline.registDate }} 최종{{
+ noticeOneline.finalSigninDate
+ }}
+ IP{{ noticeOneline.ip }}
+
+
+
+ {{ noticeOneline.state }}
+
+
+
+ {{ noticeOneline.memberCount }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ There are no noticeOnelines!
+
+
+
+
+
diff --git a/src/app/modules/admin/board/notice-oneline/components/list.component.ts b/src/app/modules/admin/board/notice-oneline/components/list.component.ts
new file mode 100644
index 0000000..27e8944
--- /dev/null
+++ b/src/app/modules/admin/board/notice-oneline/components/list.component.ts
@@ -0,0 +1,198 @@
+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 '../../../member/user/models/user';
+import { NoticeOneline } from '../models/notice-oneline';
+import { NoticeOnelinePagination } from '../models/notice-oneline-pagination';
+import { NoticeOnelineService } from '../services/notice-oneline.service';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'notice-oneline-list',
+ templateUrl: './list.component.html',
+ styles: [
+ /* language=SCSS */
+ `
+ .inventory-grid {
+ grid-template-columns: 60px auto 40px;
+
+ @screen sm {
+ grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px;
+ }
+
+ @screen md {
+ grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px 60px;
+ }
+
+ @screen lg {
+ grid-template-columns: 60px 70px 70px 70px 70px 100px 60px 60px auto 60px 60px 60px 60px;
+ }
+ }
+ `,
+ ],
+ 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;
+
+ noticeOnelines$!: Observable;
+ users$!: Observable;
+
+ isLoading = false;
+ searchInputControl = new FormControl();
+ selectedNoticeOneline?: NoticeOneline;
+ pagination?: NoticeOnelinePagination;
+
+ private _unsubscribeAll: Subject = new Subject();
+
+ /**
+ * Constructor
+ */
+ constructor(
+ private _changeDetectorRef: ChangeDetectorRef,
+ private _fuseConfirmationService: FuseConfirmationService,
+ private _formBuilder: FormBuilder,
+ private _noticeOnelineService: NoticeOnelineService,
+ private router: Router
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Lifecycle hooks
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * On init
+ */
+ ngOnInit(): void {
+ // Get the pagination
+ this._noticeOnelineService.pagination$
+ .pipe(takeUntil(this._unsubscribeAll))
+ .subscribe((pagination: NoticeOnelinePagination | undefined) => {
+ // Update the pagination
+ this.pagination = pagination;
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+ });
+
+ // Get the products
+ this.noticeOnelines$ = this._noticeOnelineService.noticeOnelines$;
+ }
+
+ /**
+ * After view init
+ */
+ ngAfterViewInit(): void {
+ if (this._sort && this._paginator) {
+ // Set the initial sort
+ this._sort.sort({
+ id: 'name',
+ start: 'asc',
+ disableClear: true,
+ });
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+
+ // If the noticeOneline 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._noticeOnelineService.getNoticeOnelines(
+ 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
+ // -----------------------------------------------------------------------------------------------------
+
+ viewUserDetail(id: string): void {
+ let url: string = 'member/user/' + id;
+ this.router.navigateByUrl(url);
+ }
+ // -----------------------------------------------------------------------------------------------------
+ // @ 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/board/notice-oneline/models/notice-oneline-pagination.ts b/src/app/modules/admin/board/notice-oneline/models/notice-oneline-pagination.ts
new file mode 100644
index 0000000..0015771
--- /dev/null
+++ b/src/app/modules/admin/board/notice-oneline/models/notice-oneline-pagination.ts
@@ -0,0 +1,8 @@
+export interface NoticeOnelinePagination {
+ length: number;
+ size: number;
+ page: number;
+ lastPage: number;
+ startIndex: number;
+ endIndex: number;
+}
diff --git a/src/app/modules/admin/board/notice-oneline/models/notice-oneline.ts b/src/app/modules/admin/board/notice-oneline/models/notice-oneline.ts
new file mode 100644
index 0000000..0bdc5a9
--- /dev/null
+++ b/src/app/modules/admin/board/notice-oneline/models/notice-oneline.ts
@@ -0,0 +1,29 @@
+export interface NoticeOneline {
+ id?: string;
+ totalPartnerCount?: number;
+ totalHoldingMoney?: number;
+ totalComp?: number;
+ total?: number;
+ branchCount?: number;
+ divisionCount?: number;
+ officeCount?: number;
+ storeCount?: number;
+ memberCount?: number;
+ nickname?: string;
+ accountHolder?: string;
+ phoneNumber?: string;
+ calculateType?: string;
+ ownCash?: number;
+ ownComp?: number;
+ ownCoupon?: number;
+ gameMoney?: number;
+ todayComp?: number;
+ totalDeposit?: number;
+ totalWithdraw?: number;
+ balance?: number;
+ registDate?: string;
+ finalSigninDate?: string;
+ ip?: string;
+ state?: string;
+ note?: string;
+}
diff --git a/src/app/modules/admin/board/notice-oneline/notice-oneline.module.ts b/src/app/modules/admin/board/notice-oneline/notice-oneline.module.ts
new file mode 100644
index 0000000..a72789f
--- /dev/null
+++ b/src/app/modules/admin/board/notice-oneline/notice-oneline.module.ts
@@ -0,0 +1,50 @@
+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 { MatGridListModule } from '@angular/material/grid-list';
+import { MatSlideToggleModule } from '@angular/material/slide-toggle';
+import { MatRadioModule } from '@angular/material/radio';
+import { MatCheckboxModule } from '@angular/material/checkbox';
+
+import { TranslocoModule } from '@ngneat/transloco';
+
+import { SharedModule } from 'app/shared/shared.module';
+
+import { COMPONENTS } from './components';
+
+import { noticeOnelineRoutes } from './notice-oneline.routing';
+
+@NgModule({
+ declarations: [COMPONENTS],
+ imports: [
+ TranslocoModule,
+ SharedModule,
+ RouterModule.forChild(noticeOnelineRoutes),
+
+ MatButtonModule,
+ MatFormFieldModule,
+ MatIconModule,
+ MatInputModule,
+ MatPaginatorModule,
+ MatProgressBarModule,
+ MatRippleModule,
+ MatSortModule,
+ MatSelectModule,
+ MatTooltipModule,
+ MatGridListModule,
+ MatSlideToggleModule,
+ MatRadioModule,
+ MatCheckboxModule,
+ ],
+})
+export class NoticeOnelineModule {}
diff --git a/src/app/modules/admin/board/notice-oneline/notice-oneline.routing.ts b/src/app/modules/admin/board/notice-oneline/notice-oneline.routing.ts
new file mode 100644
index 0000000..06471ca
--- /dev/null
+++ b/src/app/modules/admin/board/notice-oneline/notice-oneline.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 { NoticeOnelinesResolver } from './resolvers/notice-oneline.resolver';
+import { UserResolver } from '../../member/user/resolvers/user.resolver';
+
+export const noticeOnelineRoutes: Route[] = [
+ {
+ path: '',
+ component: ListComponent,
+ resolve: {
+ noticeOnelines: NoticeOnelinesResolver,
+ },
+ },
+ {
+ path: ':id',
+ component: ViewComponent,
+ resolve: {
+ users: UserResolver,
+ },
+ },
+];
diff --git a/src/app/modules/admin/board/notice-oneline/resolvers/notice-oneline.resolver.ts b/src/app/modules/admin/board/notice-oneline/resolvers/notice-oneline.resolver.ts
new file mode 100644
index 0000000..9cf54c8
--- /dev/null
+++ b/src/app/modules/admin/board/notice-oneline/resolvers/notice-oneline.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 { NoticeOneline } from '../models/notice-oneline';
+import { NoticeOnelinePagination } from '../models/notice-oneline-pagination';
+import { NoticeOnelineService } from '../services/notice-oneline.service';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class NoticeOnelineResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(
+ private _noticeOnelineService: NoticeOnelineService,
+ private _router: Router
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable {
+ return this._noticeOnelineService
+ .getNoticeOnelineById(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 NoticeOnelinesResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(private _noticeOnelineService: NoticeOnelineService) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable<{
+ pagination: NoticeOnelinePagination;
+ noticeOnelines: NoticeOneline[];
+ }> {
+ return this._noticeOnelineService.getNoticeOnelines();
+ }
+}
diff --git a/src/app/modules/admin/board/notice-oneline/services/notice-oneline.service.ts b/src/app/modules/admin/board/notice-oneline/services/notice-oneline.service.ts
new file mode 100644
index 0000000..611bfbf
--- /dev/null
+++ b/src/app/modules/admin/board/notice-oneline/services/notice-oneline.service.ts
@@ -0,0 +1,161 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import {
+ BehaviorSubject,
+ filter,
+ map,
+ Observable,
+ of,
+ switchMap,
+ take,
+ tap,
+ throwError,
+} from 'rxjs';
+
+import { NoticeOneline } from '../models/notice-oneline';
+import { NoticeOnelinePagination } from '../models/notice-oneline-pagination';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class NoticeOnelineService {
+ // Private
+ private __pagination = new BehaviorSubject<
+ NoticeOnelinePagination | undefined
+ >(undefined);
+ private __noticeOneline = new BehaviorSubject(
+ undefined
+ );
+ private __noticeOnelines = new BehaviorSubject(
+ undefined
+ );
+
+ /**
+ * Constructor
+ */
+ constructor(private _httpClient: HttpClient) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Accessors
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Getter for pagination
+ */
+ get pagination$(): Observable {
+ return this.__pagination.asObservable();
+ }
+
+ /**
+ * Getter for noticeOneline
+ */
+ get noticeOneline$(): Observable {
+ return this.__noticeOneline.asObservable();
+ }
+
+ /**
+ * Getter for noticeOnelines
+ */
+ get noticeOnelines$(): Observable {
+ return this.__noticeOnelines.asObservable();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Get NoticeOnelines
+ *
+ *
+ * @param page
+ * @param size
+ * @param sort
+ * @param order
+ * @param search
+ */
+ getNoticeOnelines(
+ page: number = 0,
+ size: number = 10,
+ sort: string = 'name',
+ order: 'asc' | 'desc' | '' = 'asc',
+ search: string = ''
+ ): Observable<{
+ pagination: NoticeOnelinePagination;
+ noticeOnelines: NoticeOneline[];
+ }> {
+ return this._httpClient
+ .get<{
+ pagination: NoticeOnelinePagination;
+ noticeOnelines: NoticeOneline[];
+ }>('api/apps/board/notice-oneline/notice-onelines', {
+ params: {
+ page: '' + page,
+ size: '' + size,
+ sort,
+ order,
+ search,
+ },
+ })
+ .pipe(
+ tap((response) => {
+ this.__pagination.next(response.pagination);
+ this.__noticeOnelines.next(response.noticeOnelines);
+ })
+ );
+ }
+
+ /**
+ * Get product by id
+ */
+ getNoticeOnelineById(id: string | null): Observable {
+ return this.__noticeOnelines.pipe(
+ take(1),
+ map((noticeOnelines) => {
+ // Find the product
+ const noticeOneline =
+ noticeOnelines?.find((item) => item.id === id) || undefined;
+
+ // Update the product
+ this.__noticeOneline.next(noticeOneline);
+
+ // Return the product
+ return noticeOneline;
+ }),
+ switchMap((product) => {
+ if (!product) {
+ return throwError('Could not found product with id of ' + id + '!');
+ }
+
+ return of(product);
+ })
+ );
+ }
+
+ /**
+ * Create product
+ */
+ createNoticeOneline(): Observable {
+ return this.noticeOnelines$.pipe(
+ take(1),
+ switchMap((noticeOnelines) =>
+ this._httpClient
+ .post('api/apps/board/notice-oneline/product', {})
+ .pipe(
+ map((newNoticeOneline) => {
+ // Update the noticeOnelines with the new product
+ if (!!noticeOnelines) {
+ this.__noticeOnelines.next([
+ newNoticeOneline,
+ ...noticeOnelines,
+ ]);
+ }
+
+ // Return the new product
+ return newNoticeOneline;
+ })
+ )
+ )
+ );
+ }
+}
diff --git a/src/app/modules/admin/board/notice/components/index.ts b/src/app/modules/admin/board/notice/components/index.ts
new file mode 100644
index 0000000..04759eb
--- /dev/null
+++ b/src/app/modules/admin/board/notice/components/index.ts
@@ -0,0 +1,3 @@
+import { ListComponent } from './list.component';
+
+export const COMPONENTS = [ListComponent];
diff --git a/src/app/modules/admin/board/notice/components/list.component.html b/src/app/modules/admin/board/notice/components/list.component.html
new file mode 100644
index 0000000..3b0681f
--- /dev/null
+++ b/src/app/modules/admin/board/notice/components/list.component.html
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 40
+ 60
+ 80
+ 100
+
+
+
+
+ LV.1
+ LV.2
+ LV.3
+ LV.4
+
+
+
+
+ 정상
+ 대기
+ 탈퇴
+ 휴면
+ 블랙
+ 정지
+
+
+
+
+ 카지노제한
+ 슬롯제한
+
+
+
+
+ 계좌입금
+
+
+
+
+ 카지노콤프
+ 슬롯콤프
+ 배팅콤프
+ 첫충콤프
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0; else noNotice">
+
+
+
+
+
요율
+
상부트리
+
관리
+
매장수
+
회원수
+
아이디
+
닉네임
+
예금주
+
연락처
+
정산
+
보유금
+
게임중머니
+
카지노->캐쉬
+
금일콤프
+
총입출
+
로그
+
상태
+
회원수
+
비고
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ notice.id }}
+
+
+
+
+
+ {{ notice.nickname }}
+
+
+
+ {{ notice.accountHolder }}
+
+
+
+ {{ notice.phoneNumber }}
+
+
+
+ {{ notice.calculateType }}
+
+
+
+ 캐쉬{{ notice.ownCash }} 콤프{{ notice.ownComp }} 쿠폰{{
+ notice.ownCoupon
+ }}
+
+
+
+ {{ notice.gameMoney }}
+
+
+
+
+
+
+
+
+ {{ notice.todayComp }}P
+
+
+
+ 입금{{ notice.totalDeposit }} 출금{{
+ notice.totalWithdraw
+ }}
+ 차익{{ notice.balance }}
+
+
+
+ 가입{{ notice.registDate }} 최종{{
+ notice.finalSigninDate
+ }}
+ IP{{ notice.ip }}
+
+
+
+ {{ notice.state }}
+
+
+
+ {{ notice.memberCount }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ There are no notices!
+
+
+
+
+
diff --git a/src/app/modules/admin/board/notice/components/list.component.ts b/src/app/modules/admin/board/notice/components/list.component.ts
new file mode 100644
index 0000000..812f993
--- /dev/null
+++ b/src/app/modules/admin/board/notice/components/list.component.ts
@@ -0,0 +1,198 @@
+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 '../../../member/user/models/user';
+import { Notice } from '../models/notice';
+import { NoticePagination } from '../models/notice-pagination';
+import { NoticeService } from '../services/notice.service';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'notice-list',
+ templateUrl: './list.component.html',
+ styles: [
+ /* language=SCSS */
+ `
+ .inventory-grid {
+ grid-template-columns: 60px auto 40px;
+
+ @screen sm {
+ grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px;
+ }
+
+ @screen md {
+ grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px 60px;
+ }
+
+ @screen lg {
+ grid-template-columns: 60px 70px 70px 70px 70px 100px 60px 60px auto 60px 60px 60px 60px;
+ }
+ }
+ `,
+ ],
+ 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;
+
+ notices$!: Observable;
+ users$!: Observable;
+
+ isLoading = false;
+ searchInputControl = new FormControl();
+ selectedNotice?: Notice;
+ pagination?: NoticePagination;
+
+ private _unsubscribeAll: Subject = new Subject();
+
+ /**
+ * Constructor
+ */
+ constructor(
+ private _changeDetectorRef: ChangeDetectorRef,
+ private _fuseConfirmationService: FuseConfirmationService,
+ private _formBuilder: FormBuilder,
+ private _noticeService: NoticeService,
+ private router: Router
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Lifecycle hooks
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * On init
+ */
+ ngOnInit(): void {
+ // Get the pagination
+ this._noticeService.pagination$
+ .pipe(takeUntil(this._unsubscribeAll))
+ .subscribe((pagination: NoticePagination | undefined) => {
+ // Update the pagination
+ this.pagination = pagination;
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+ });
+
+ // Get the products
+ this.notices$ = this._noticeService.notices$;
+ }
+
+ /**
+ * After view init
+ */
+ ngAfterViewInit(): void {
+ if (this._sort && this._paginator) {
+ // Set the initial sort
+ this._sort.sort({
+ id: 'name',
+ start: 'asc',
+ disableClear: true,
+ });
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+
+ // If the notice 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._noticeService.getNotices(
+ 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
+ // -----------------------------------------------------------------------------------------------------
+
+ viewUserDetail(id: string): void {
+ let url: string = 'member/user/' + id;
+ this.router.navigateByUrl(url);
+ }
+ // -----------------------------------------------------------------------------------------------------
+ // @ 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/board/notice/models/notice-pagination.ts b/src/app/modules/admin/board/notice/models/notice-pagination.ts
new file mode 100644
index 0000000..1df4d0a
--- /dev/null
+++ b/src/app/modules/admin/board/notice/models/notice-pagination.ts
@@ -0,0 +1,8 @@
+export interface NoticePagination {
+ length: number;
+ size: number;
+ page: number;
+ lastPage: number;
+ startIndex: number;
+ endIndex: number;
+}
diff --git a/src/app/modules/admin/board/notice/models/notice.ts b/src/app/modules/admin/board/notice/models/notice.ts
new file mode 100644
index 0000000..d88ca9e
--- /dev/null
+++ b/src/app/modules/admin/board/notice/models/notice.ts
@@ -0,0 +1,29 @@
+export interface Notice {
+ id?: string;
+ totalPartnerCount?: number;
+ totalHoldingMoney?: number;
+ totalComp?: number;
+ total?: number;
+ branchCount?: number;
+ divisionCount?: number;
+ officeCount?: number;
+ storeCount?: number;
+ memberCount?: number;
+ nickname?: string;
+ accountHolder?: string;
+ phoneNumber?: string;
+ calculateType?: string;
+ ownCash?: number;
+ ownComp?: number;
+ ownCoupon?: number;
+ gameMoney?: number;
+ todayComp?: number;
+ totalDeposit?: number;
+ totalWithdraw?: number;
+ balance?: number;
+ registDate?: string;
+ finalSigninDate?: string;
+ ip?: string;
+ state?: string;
+ note?: string;
+}
diff --git a/src/app/modules/admin/board/notice/notice.module.ts b/src/app/modules/admin/board/notice/notice.module.ts
new file mode 100644
index 0000000..0ffebc2
--- /dev/null
+++ b/src/app/modules/admin/board/notice/notice.module.ts
@@ -0,0 +1,50 @@
+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 { MatGridListModule } from '@angular/material/grid-list';
+import { MatSlideToggleModule } from '@angular/material/slide-toggle';
+import { MatRadioModule } from '@angular/material/radio';
+import { MatCheckboxModule } from '@angular/material/checkbox';
+
+import { TranslocoModule } from '@ngneat/transloco';
+
+import { SharedModule } from 'app/shared/shared.module';
+
+import { COMPONENTS } from './components';
+
+import { noticeRoutes } from './notice.routing';
+
+@NgModule({
+ declarations: [COMPONENTS],
+ imports: [
+ TranslocoModule,
+ SharedModule,
+ RouterModule.forChild(noticeRoutes),
+
+ MatButtonModule,
+ MatFormFieldModule,
+ MatIconModule,
+ MatInputModule,
+ MatPaginatorModule,
+ MatProgressBarModule,
+ MatRippleModule,
+ MatSortModule,
+ MatSelectModule,
+ MatTooltipModule,
+ MatGridListModule,
+ MatSlideToggleModule,
+ MatRadioModule,
+ MatCheckboxModule,
+ ],
+})
+export class NoticeModule {}
diff --git a/src/app/modules/admin/board/notice/notice.routing.ts b/src/app/modules/admin/board/notice/notice.routing.ts
new file mode 100644
index 0000000..04c30c6
--- /dev/null
+++ b/src/app/modules/admin/board/notice/notice.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 { NoticesResolver } from './resolvers/notice.resolver';
+import { UserResolver } from '../../member/user/resolvers/user.resolver';
+
+export const noticeRoutes: Route[] = [
+ {
+ path: '',
+ component: ListComponent,
+ resolve: {
+ notices: NoticesResolver,
+ },
+ },
+ {
+ path: ':id',
+ component: ViewComponent,
+ resolve: {
+ users: UserResolver,
+ },
+ },
+];
diff --git a/src/app/modules/admin/board/notice/resolvers/notice.resolver.ts b/src/app/modules/admin/board/notice/resolvers/notice.resolver.ts
new file mode 100644
index 0000000..fb5b3b5
--- /dev/null
+++ b/src/app/modules/admin/board/notice/resolvers/notice.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 { Notice } from '../models/notice';
+import { NoticePagination } from '../models/notice-pagination';
+import { NoticeService } from '../services/notice.service';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class NoticeResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(private _noticeService: NoticeService, private _router: Router) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable {
+ return this._noticeService.getNoticeById(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 NoticesResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(private _noticeService: NoticeService) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable<{
+ pagination: NoticePagination;
+ notices: Notice[];
+ }> {
+ return this._noticeService.getNotices();
+ }
+}
diff --git a/src/app/modules/admin/board/notice/services/notice.service.ts b/src/app/modules/admin/board/notice/services/notice.service.ts
new file mode 100644
index 0000000..a8a52a8
--- /dev/null
+++ b/src/app/modules/admin/board/notice/services/notice.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 { Notice } from '../models/notice';
+import { NoticePagination } from '../models/notice-pagination';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class NoticeService {
+ // Private
+ private __pagination = new BehaviorSubject(
+ undefined
+ );
+ private __notice = new BehaviorSubject(undefined);
+ private __notices = new BehaviorSubject(undefined);
+
+ /**
+ * Constructor
+ */
+ constructor(private _httpClient: HttpClient) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Accessors
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Getter for pagination
+ */
+ get pagination$(): Observable {
+ return this.__pagination.asObservable();
+ }
+
+ /**
+ * Getter for notice
+ */
+ get notice$(): Observable {
+ return this.__notice.asObservable();
+ }
+
+ /**
+ * Getter for notices
+ */
+ get notices$(): Observable {
+ return this.__notices.asObservable();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Get Notices
+ *
+ *
+ * @param page
+ * @param size
+ * @param sort
+ * @param order
+ * @param search
+ */
+ getNotices(
+ page: number = 0,
+ size: number = 10,
+ sort: string = 'name',
+ order: 'asc' | 'desc' | '' = 'asc',
+ search: string = ''
+ ): Observable<{
+ pagination: NoticePagination;
+ notices: Notice[];
+ }> {
+ return this._httpClient
+ .get<{
+ pagination: NoticePagination;
+ notices: Notice[];
+ }>('api/apps/board/notice/notices', {
+ params: {
+ page: '' + page,
+ size: '' + size,
+ sort,
+ order,
+ search,
+ },
+ })
+ .pipe(
+ tap((response) => {
+ this.__pagination.next(response.pagination);
+ this.__notices.next(response.notices);
+ })
+ );
+ }
+
+ /**
+ * Get product by id
+ */
+ getNoticeById(id: string | null): Observable {
+ return this.__notices.pipe(
+ take(1),
+ map((notices) => {
+ // Find the product
+ const notice = notices?.find((item) => item.id === id) || undefined;
+
+ // Update the product
+ this.__notice.next(notice);
+
+ // Return the product
+ return notice;
+ }),
+ switchMap((product) => {
+ if (!product) {
+ return throwError('Could not found product with id of ' + id + '!');
+ }
+
+ return of(product);
+ })
+ );
+ }
+
+ /**
+ * Create product
+ */
+ createNotice(): Observable {
+ return this.notices$.pipe(
+ take(1),
+ switchMap((notices) =>
+ this._httpClient.post('api/apps/board/notice/product', {}).pipe(
+ map((newNotice) => {
+ // Update the notices with the new product
+ if (!!notices) {
+ this.__notices.next([newNotice, ...notices]);
+ }
+
+ // Return the new product
+ return newNotice;
+ })
+ )
+ )
+ );
+ }
+}
diff --git a/src/app/modules/admin/board/popup/components/index.ts b/src/app/modules/admin/board/popup/components/index.ts
new file mode 100644
index 0000000..04759eb
--- /dev/null
+++ b/src/app/modules/admin/board/popup/components/index.ts
@@ -0,0 +1,3 @@
+import { ListComponent } from './list.component';
+
+export const COMPONENTS = [ListComponent];
diff --git a/src/app/modules/admin/board/popup/components/list.component.html b/src/app/modules/admin/board/popup/components/list.component.html
new file mode 100644
index 0000000..68c5687
--- /dev/null
+++ b/src/app/modules/admin/board/popup/components/list.component.html
@@ -0,0 +1,353 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 40
+ 60
+ 80
+ 100
+
+
+
+
+ LV.1
+ LV.2
+ LV.3
+ LV.4
+
+
+
+
+ 정상
+ 대기
+ 탈퇴
+ 휴면
+ 블랙
+ 정지
+
+
+
+
+ 카지노제한
+ 슬롯제한
+
+
+
+
+ 계좌입금
+
+
+
+
+ 카지노콤프
+ 슬롯콤프
+ 배팅콤프
+ 첫충콤프
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0; else noPopup">
+
+
+
+
+
요율
+
상부트리
+
관리
+
매장수
+
회원수
+
아이디
+
닉네임
+
예금주
+
연락처
+
정산
+
보유금
+
게임중머니
+
카지노->캐쉬
+
금일콤프
+
총입출
+
로그
+
상태
+
회원수
+
비고
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ popup.id }}
+
+
+
+
+
+ {{ popup.nickname }}
+
+
+
+ {{ popup.accountHolder }}
+
+
+
+ {{ popup.phoneNumber }}
+
+
+
+ {{ popup.calculateType }}
+
+
+
+ 캐쉬{{ popup.ownCash }} 콤프{{ popup.ownComp }} 쿠폰{{
+ popup.ownCoupon
+ }}
+
+
+
+ {{ popup.gameMoney }}
+
+
+
+
+
+
+
+
+ {{ popup.todayComp }}P
+
+
+
+ 입금{{ popup.totalDeposit }} 출금{{
+ popup.totalWithdraw
+ }}
+ 차익{{ popup.balance }}
+
+
+
+ 가입{{ popup.registDate }} 최종{{
+ popup.finalSigninDate
+ }}
+ IP{{ popup.ip }}
+
+
+
+ {{ popup.state }}
+
+
+
+ {{ popup.memberCount }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ There are no popups!
+
+
+
+
+
diff --git a/src/app/modules/admin/board/popup/components/list.component.ts b/src/app/modules/admin/board/popup/components/list.component.ts
new file mode 100644
index 0000000..9effff6
--- /dev/null
+++ b/src/app/modules/admin/board/popup/components/list.component.ts
@@ -0,0 +1,198 @@
+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 '../../../member/user/models/user';
+import { Popup } from '../models/popup';
+import { PopupPagination } from '../models/popup-pagination';
+import { PopupService } from '../services/popup.service';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'popup-list',
+ templateUrl: './list.component.html',
+ styles: [
+ /* language=SCSS */
+ `
+ .inventory-grid {
+ grid-template-columns: 60px auto 40px;
+
+ @screen sm {
+ grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px;
+ }
+
+ @screen md {
+ grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px 60px;
+ }
+
+ @screen lg {
+ grid-template-columns: 60px 70px 70px 70px 70px 100px 60px 60px auto 60px 60px 60px 60px;
+ }
+ }
+ `,
+ ],
+ 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;
+
+ popups$!: Observable;
+ users$!: Observable;
+
+ isLoading = false;
+ searchInputControl = new FormControl();
+ selectedPopup?: Popup;
+ pagination?: PopupPagination;
+
+ private _unsubscribeAll: Subject = new Subject();
+
+ /**
+ * Constructor
+ */
+ constructor(
+ private _changeDetectorRef: ChangeDetectorRef,
+ private _fuseConfirmationService: FuseConfirmationService,
+ private _formBuilder: FormBuilder,
+ private _popupService: PopupService,
+ private router: Router
+ ) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Lifecycle hooks
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * On init
+ */
+ ngOnInit(): void {
+ // Get the pagination
+ this._popupService.pagination$
+ .pipe(takeUntil(this._unsubscribeAll))
+ .subscribe((pagination: PopupPagination | undefined) => {
+ // Update the pagination
+ this.pagination = pagination;
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+ });
+
+ // Get the products
+ this.popups$ = this._popupService.popups$;
+ }
+
+ /**
+ * After view init
+ */
+ ngAfterViewInit(): void {
+ if (this._sort && this._paginator) {
+ // Set the initial sort
+ this._sort.sort({
+ id: 'name',
+ start: 'asc',
+ disableClear: true,
+ });
+
+ // Mark for check
+ this._changeDetectorRef.markForCheck();
+
+ // If the popup 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._popupService.getPopups(
+ 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
+ // -----------------------------------------------------------------------------------------------------
+
+ viewUserDetail(id: string): void {
+ let url: string = 'member/user/' + id;
+ this.router.navigateByUrl(url);
+ }
+ // -----------------------------------------------------------------------------------------------------
+ // @ 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/board/popup/models/popup-pagination.ts b/src/app/modules/admin/board/popup/models/popup-pagination.ts
new file mode 100644
index 0000000..64182c5
--- /dev/null
+++ b/src/app/modules/admin/board/popup/models/popup-pagination.ts
@@ -0,0 +1,8 @@
+export interface PopupPagination {
+ length: number;
+ size: number;
+ page: number;
+ lastPage: number;
+ startIndex: number;
+ endIndex: number;
+}
diff --git a/src/app/modules/admin/board/popup/models/popup.ts b/src/app/modules/admin/board/popup/models/popup.ts
new file mode 100644
index 0000000..533f1bf
--- /dev/null
+++ b/src/app/modules/admin/board/popup/models/popup.ts
@@ -0,0 +1,29 @@
+export interface Popup {
+ id?: string;
+ totalPartnerCount?: number;
+ totalHoldingMoney?: number;
+ totalComp?: number;
+ total?: number;
+ branchCount?: number;
+ divisionCount?: number;
+ officeCount?: number;
+ storeCount?: number;
+ memberCount?: number;
+ nickname?: string;
+ accountHolder?: string;
+ phoneNumber?: string;
+ calculateType?: string;
+ ownCash?: number;
+ ownComp?: number;
+ ownCoupon?: number;
+ gameMoney?: number;
+ todayComp?: number;
+ totalDeposit?: number;
+ totalWithdraw?: number;
+ balance?: number;
+ registDate?: string;
+ finalSigninDate?: string;
+ ip?: string;
+ state?: string;
+ note?: string;
+}
diff --git a/src/app/modules/admin/board/popup/popup.module.ts b/src/app/modules/admin/board/popup/popup.module.ts
new file mode 100644
index 0000000..0691ccc
--- /dev/null
+++ b/src/app/modules/admin/board/popup/popup.module.ts
@@ -0,0 +1,50 @@
+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 { MatGridListModule } from '@angular/material/grid-list';
+import { MatSlideToggleModule } from '@angular/material/slide-toggle';
+import { MatRadioModule } from '@angular/material/radio';
+import { MatCheckboxModule } from '@angular/material/checkbox';
+
+import { TranslocoModule } from '@ngneat/transloco';
+
+import { SharedModule } from 'app/shared/shared.module';
+
+import { COMPONENTS } from './components';
+
+import { popupRoutes } from './popup.routing';
+
+@NgModule({
+ declarations: [COMPONENTS],
+ imports: [
+ TranslocoModule,
+ SharedModule,
+ RouterModule.forChild(popupRoutes),
+
+ MatButtonModule,
+ MatFormFieldModule,
+ MatIconModule,
+ MatInputModule,
+ MatPaginatorModule,
+ MatProgressBarModule,
+ MatRippleModule,
+ MatSortModule,
+ MatSelectModule,
+ MatTooltipModule,
+ MatGridListModule,
+ MatSlideToggleModule,
+ MatRadioModule,
+ MatCheckboxModule,
+ ],
+})
+export class PopupModule {}
diff --git a/src/app/modules/admin/board/popup/popup.routing.ts b/src/app/modules/admin/board/popup/popup.routing.ts
new file mode 100644
index 0000000..4a53e31
--- /dev/null
+++ b/src/app/modules/admin/board/popup/popup.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 { PopupsResolver } from './resolvers/popup.resolver';
+import { UserResolver } from '../../member/user/resolvers/user.resolver';
+
+export const popupRoutes: Route[] = [
+ {
+ path: '',
+ component: ListComponent,
+ resolve: {
+ popups: PopupsResolver,
+ },
+ },
+ {
+ path: ':id',
+ component: ViewComponent,
+ resolve: {
+ users: UserResolver,
+ },
+ },
+];
diff --git a/src/app/modules/admin/board/popup/resolvers/popup.resolver.ts b/src/app/modules/admin/board/popup/resolvers/popup.resolver.ts
new file mode 100644
index 0000000..ebd8222
--- /dev/null
+++ b/src/app/modules/admin/board/popup/resolvers/popup.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 { Popup } from '../models/popup';
+import { PopupPagination } from '../models/popup-pagination';
+import { PopupService } from '../services/popup.service';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class PopupResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(private _popupService: PopupService, private _router: Router) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable {
+ return this._popupService.getPopupById(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 PopupsResolver implements Resolve {
+ /**
+ * Constructor
+ */
+ constructor(private _popupService: PopupService) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Resolver
+ *
+ * @param route
+ * @param state
+ */
+ resolve(
+ route: ActivatedRouteSnapshot,
+ state: RouterStateSnapshot
+ ): Observable<{
+ pagination: PopupPagination;
+ popups: Popup[];
+ }> {
+ return this._popupService.getPopups();
+ }
+}
diff --git a/src/app/modules/admin/board/popup/services/popup.service.ts b/src/app/modules/admin/board/popup/services/popup.service.ts
new file mode 100644
index 0000000..b228337
--- /dev/null
+++ b/src/app/modules/admin/board/popup/services/popup.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 { Popup } from '../models/popup';
+import { PopupPagination } from '../models/popup-pagination';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class PopupService {
+ // Private
+ private __pagination = new BehaviorSubject(
+ undefined
+ );
+ private __popup = new BehaviorSubject(undefined);
+ private __popups = new BehaviorSubject(undefined);
+
+ /**
+ * Constructor
+ */
+ constructor(private _httpClient: HttpClient) {}
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Accessors
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Getter for pagination
+ */
+ get pagination$(): Observable {
+ return this.__pagination.asObservable();
+ }
+
+ /**
+ * Getter for popup
+ */
+ get popup$(): Observable {
+ return this.__popup.asObservable();
+ }
+
+ /**
+ * Getter for popups
+ */
+ get popups$(): Observable {
+ return this.__popups.asObservable();
+ }
+
+ // -----------------------------------------------------------------------------------------------------
+ // @ Public methods
+ // -----------------------------------------------------------------------------------------------------
+
+ /**
+ * Get Popups
+ *
+ *
+ * @param page
+ * @param size
+ * @param sort
+ * @param order
+ * @param search
+ */
+ getPopups(
+ page: number = 0,
+ size: number = 10,
+ sort: string = 'name',
+ order: 'asc' | 'desc' | '' = 'asc',
+ search: string = ''
+ ): Observable<{
+ pagination: PopupPagination;
+ popups: Popup[];
+ }> {
+ return this._httpClient
+ .get<{
+ pagination: PopupPagination;
+ popups: Popup[];
+ }>('api/apps/board/popup/popups', {
+ params: {
+ page: '' + page,
+ size: '' + size,
+ sort,
+ order,
+ search,
+ },
+ })
+ .pipe(
+ tap((response) => {
+ this.__pagination.next(response.pagination);
+ this.__popups.next(response.popups);
+ })
+ );
+ }
+
+ /**
+ * Get product by id
+ */
+ getPopupById(id: string | null): Observable {
+ return this.__popups.pipe(
+ take(1),
+ map((popups) => {
+ // Find the product
+ const popup = popups?.find((item) => item.id === id) || undefined;
+
+ // Update the product
+ this.__popup.next(popup);
+
+ // Return the product
+ return popup;
+ }),
+ switchMap((product) => {
+ if (!product) {
+ return throwError('Could not found product with id of ' + id + '!');
+ }
+
+ return of(product);
+ })
+ );
+ }
+
+ /**
+ * Create product
+ */
+ createPopup(): Observable {
+ return this.popups$.pipe(
+ take(1),
+ switchMap((popups) =>
+ this._httpClient.post('api/apps/board/popup/product', {}).pipe(
+ map((newPopup) => {
+ // Update the popups with the new product
+ if (!!popups) {
+ this.__popups.next([newPopup, ...popups]);
+ }
+
+ // Return the new product
+ return newPopup;
+ })
+ )
+ )
+ );
+ }
+}
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index bad3712..e88cd37 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -37,5 +37,8 @@
"Sessionin Admin": "Sessionin Admin Info",
"Sessionin Overlap": "Sessionin Overlap",
"Excel Log": "Excel Download Logs",
- "Loosing": "Loosing Management"
+ "Loosing": "Loosing Management",
+ "Notice": "Notice",
+ "Notice Oneline": "Notice Oneline",
+ "Popup": "Pop Up"
}
diff --git a/src/assets/i18n/ko.json b/src/assets/i18n/ko.json
index 5622239..ea95cc5 100644
--- a/src/assets/i18n/ko.json
+++ b/src/assets/i18n/ko.json
@@ -43,5 +43,8 @@
"Sessionin Overlap": "중복로그인",
"Sessionin Admin": "관리자 로그인정보",
"Excel Log": "엑셀다운 로그",
- "Loosing": "루징관리"
+ "Loosing": "루징관리",
+ "Notice": "공지사항",
+ "Notice Oneline": "한줄공지",
+ "Popup": "팝업"
}