Browse Source

backup

main
Artemis 6 months ago
commit
50b3d05234
102 changed files with 31744 additions and 0 deletions
  1. +17
    -0
      .browserslistrc
  2. +16
    -0
      .editorconfig
  3. +45
    -0
      .gitignore
  4. +27
    -0
      README.md
  5. +111
    -0
      angular.json
  6. +44
    -0
      karma.conf.js
  7. +28468
    -0
      package-lock.json
  8. +64
    -0
      package.json
  9. +6
    -0
      src/api/api.interface.ts
  10. +16
    -0
      src/api/api.service.spec.ts
  11. +19
    -0
      src/api/api.service.ts
  12. +76
    -0
      src/api/auth/api.auth.interface.ts
  13. +109
    -0
      src/api/auth/api.auth.ts
  14. +67
    -0
      src/api/fund/api.fund.interface.ts
  15. +102
    -0
      src/api/fund/api.fund.ts
  16. +19
    -0
      src/api/kyc/api.kyc.interface.ts
  17. +116
    -0
      src/api/kyc/api.kyc.ts
  18. +6
    -0
      src/api/system/api.system.interface.ts
  19. +20
    -0
      src/api/system/api.system.ts
  20. +33
    -0
      src/api/transactions/api.transactions.interface.ts
  21. +58
    -0
      src/api/transactions/api.transactions.ts
  22. +14
    -0
      src/api/wallet/api.wallet.interface.ts
  23. +37
    -0
      src/api/wallet/api.wallet.ts
  24. +19
    -0
      src/app/app-routing.module.ts
  25. +1
    -0
      src/app/app.component.html
  26. +0
    -0
      src/app/app.component.scss
  27. +35
    -0
      src/app/app.component.spec.ts
  28. +10
    -0
      src/app/app.component.ts
  29. +20
    -0
      src/app/app.module.ts
  30. +0
    -0
      src/assets/.gitkeep
  31. BIN
      src/assets/fonts/woff/IRANSansX-Bold.woff
  32. BIN
      src/assets/fonts/woff/IRANSansX-Regular.woff
  33. BIN
      src/assets/fonts/woff2/IRANSansX-Bold.woff2
  34. BIN
      src/assets/fonts/woff2/IRANSansX-Regular.woff2
  35. +15
    -0
      src/components/image/image.component.html
  36. +92
    -0
      src/components/image/image.component.scss
  37. +25
    -0
      src/components/image/image.component.spec.ts
  38. +128
    -0
      src/components/image/image.component.ts
  39. +18
    -0
      src/components/image/image.module.ts
  40. +15
    -0
      src/components/image/material.ts
  41. +1
    -0
      src/database/app.ts
  42. +13
    -0
      src/database/drawer.ts
  43. +4
    -0
      src/environments/environment.prod.ts
  44. +17
    -0
      src/environments/environment.ts
  45. BIN
      src/favicon.ico
  46. +18
    -0
      src/index.html
  47. +12
    -0
      src/main.ts
  48. +11
    -0
      src/material.empty.ts
  49. +65
    -0
      src/polyfills.ts
  50. +26
    -0
      src/routes/auth/auth.module.ts
  51. +26
    -0
      src/routes/auth/auth/auth.component.html
  52. +52
    -0
      src/routes/auth/auth/auth.component.scss
  53. +25
    -0
      src/routes/auth/auth/auth.component.spec.ts
  54. +55
    -0
      src/routes/auth/auth/auth.component.ts
  55. +24
    -0
      src/routes/auth/material.ts
  56. +28
    -0
      src/routes/routes/profile/material.ts
  57. +38
    -0
      src/routes/routes/profile/profile.component.html
  58. +0
    -0
      src/routes/routes/profile/profile.component.scss
  59. +25
    -0
      src/routes/routes/profile/profile.component.spec.ts
  60. +57
    -0
      src/routes/routes/profile/profile.component.ts
  61. +32
    -0
      src/routes/routes/profile/profile.module.ts
  62. +12
    -0
      src/routes/routes/routes.ts
  63. +10
    -0
      src/routes/routes/users/list/list.component.html
  64. +0
    -0
      src/routes/routes/users/list/list.component.scss
  65. +25
    -0
      src/routes/routes/users/list/list.component.spec.ts
  66. +17
    -0
      src/routes/routes/users/list/list.component.ts
  67. +28
    -0
      src/routes/routes/users/material.ts
  68. +58
    -0
      src/routes/routes/users/one/one.component.html
  69. +0
    -0
      src/routes/routes/users/one/one.component.scss
  70. +25
    -0
      src/routes/routes/users/one/one.component.spec.ts
  71. +20
    -0
      src/routes/routes/users/one/one.component.ts
  72. +30
    -0
      src/routes/routes/users/users.module.ts
  73. +20
    -0
      src/routes/view/material.ts
  74. +54
    -0
      src/routes/view/view.component.html
  75. +103
    -0
      src/routes/view/view.component.scss
  76. +25
    -0
      src/routes/view/view.component.spec.ts
  77. +31
    -0
      src/routes/view/view.component.ts
  78. +24
    -0
      src/routes/view/view.module.ts
  79. +20
    -0
      src/services/confirm/confirm.module.ts
  80. +16
    -0
      src/services/confirm/confirm.service.spec.ts
  81. +20
    -0
      src/services/confirm/confirm.service.ts
  82. +9
    -0
      src/services/confirm/dialog/dialog.component.html
  83. +14
    -0
      src/services/confirm/dialog/dialog.component.scss
  84. +25
    -0
      src/services/confirm/dialog/dialog.component.spec.ts
  85. +21
    -0
      src/services/confirm/dialog/dialog.component.ts
  86. +8
    -0
      src/services/confirm/interface.ts
  87. +13
    -0
      src/services/toast/toast.module.ts
  88. +16
    -0
      src/services/toast/toast.service.spec.ts
  89. +19
    -0
      src/services/toast/toast.service.ts
  90. +38
    -0
      src/style/custom/form.scss
  91. +43
    -0
      src/style/custom/mat-card.scss
  92. +49
    -0
      src/style/flex.scss
  93. +34
    -0
      src/style/font.css
  94. +351
    -0
      src/style/normalize.css
  95. +7
    -0
      src/style/normalize.scss
  96. +9
    -0
      src/style/root.css
  97. +36
    -0
      src/style/theme.scss
  98. +29
    -0
      src/styles.scss
  99. +25
    -0
      src/test.ts
  100. +15
    -0
      tsconfig.app.json

+ 17
- 0
.browserslistrc View File

@ -0,0 +1,17 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

+ 16
- 0
.editorconfig View File

@ -0,0 +1,16 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false

+ 45
- 0
.gitignore View File

@ -0,0 +1,45 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events*.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db

+ 27
- 0
README.md View File

@ -0,0 +1,27 @@
# Panel Boilerplate
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.1.4.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
## Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

+ 111
- 0
angular.json View File

@ -0,0 +1,111 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"panel-boilerplate": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
},
"@schematics/angular:application": {
"strict": true
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/panel-boilerplate",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"outputHashing": "all"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"browserTarget": "panel-boilerplate:build:production"
},
"development": {
"browserTarget": "panel-boilerplate:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "panel-boilerplate:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
}
}
}
}
},
"defaultProject": "panel-boilerplate"
}

+ 44
- 0
karma.conf.js View File

@ -0,0 +1,44 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, './coverage/panel-boilerplate'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};

+ 28468
- 0
package-lock.json
File diff suppressed because it is too large
View File


+ 64
- 0
package.json View File

@ -0,0 +1,64 @@
{
"name": "panel-boilerplate",
"description": "This is a panel from boilerplate",
"keywords": [
"Panel",
"Admin Panel",
"Angular Panel",
"Boilerplate"
],
"license": "MIT",
"homepage": "https://iamroot.ir/repo/panel-boilerplate",
"readme": "https://github.com/iamnonroot/panel-boilerplate#readme",
"author": {
"name": "!Root",
"url": "https://iamroot.ir",
"email": "iamnonroot@gmail.com"
},
"bugs": {
"email": "iamnonroot@gmail.com",
"url": "https://github.com/iamnonroot/panel-boilerplate/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/iamnonroot/panel-boilerplate"
},
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "~12.1.0",
"@angular/cdk": "^12.2.0",
"@angular/common": "~12.1.0",
"@angular/compiler": "~12.1.0",
"@angular/core": "~12.1.0",
"@angular/forms": "~12.1.0",
"@angular/material": "^12.2.0",
"@angular/platform-browser": "~12.1.0",
"@angular/platform-browser-dynamic": "~12.1.0",
"@angular/router": "~12.1.0",
"rxjs": "~6.6.0",
"tslib": "^2.2.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "~12.1.4",
"@angular/cli": "~12.1.4",
"@angular/compiler-cli": "~12.1.0",
"@types/jasmine": "~3.8.0",
"@types/node": "^12.11.1",
"jasmine-core": "~3.8.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "~1.7.0",
"typescript": "~4.3.2"
}
}

+ 6
- 0
src/api/api.interface.ts View File

@ -0,0 +1,6 @@
export * from './auth/api.auth.interface'
export * from './wallet/api.wallet.interface'
export * from './transactions/api.transactions.interface'
export * from './kyc/api.kyc.interface'
export * from './system/api.system.interface'
export * from './fund/api.fund.interface'

+ 16
- 0
src/api/api.service.spec.ts View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { ApiService } from './api.service';
describe('ApiService', () => {
let service: ApiService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ApiService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

+ 19
- 0
src/api/api.service.ts View File

@ -0,0 +1,19 @@
import { Injectable } from '@angular/core';
import { CAuth, Auth } from './auth/api.auth';
import { CFund, Fund } from './fund/api.fund';
import { CKYC, KYC } from './kyc/api.kyc';
import { CSystem, System } from './system/api.system';
import { CTransaction, Transaction } from './transactions/api.transactions';
import { CWallet, Wallet } from './wallet/api.wallet';
@Injectable({
providedIn: 'root'
})
export class ApiService {
public Auth: CAuth = Auth
public Wallet: CWallet = Wallet
public Transaction: CTransaction = Transaction
public KYC: CKYC = KYC
public System: CSystem = System
public Fund: CFund = Fund
}

+ 76
- 0
src/api/auth/api.auth.interface.ts View File

@ -0,0 +1,76 @@
export interface IRegisterData {
ref_code: string
email: string
phone: string
password: string
}
export interface ILoginData {
email: string
password: string
}
// ============== response ============== //
export interface IErrorResponse {
statusCode: number;
message: string;
}
export interface ITokensResponse {
access: {
token: string;
expires: Date;
}
refresh: {
token: string;
expires: Date;
}
}
export interface IAuthLoginResponse {
expiresIn: number;
token: string;
}
export interface IAuthRegisterResponse {
id: number;
name: null;
name_status: null | number;
last_name: null;
last_name_status: null | number;
phone_status: null | number;
homeNumber: null;
homeNumber_status: null | number;
birthDate: null;
birthDate_status: null | number;
nationalId: null;
nationalId_status: null | number;
city: null;
city_status: null | number;
address: null;
address_status: null | number;
introducer: null;
nationalId_image: null;
nationalId_image_status: null | number;
selfi_image: null;
selfi_image_status: null | number;
status: null | 'pending' | 'active' | 'suspend' | 'failed' | '';
token_email: null;
token_sms: null;
ref_code: string;
email_status: null | number;
role: null;
_id: string;
email: string;
password: string;
phone: string;
__v: number;
}
export interface IAuthProfileResponse extends IAuthRegisterResponse { }
export interface IAuthResetPassword {
status: boolean
}

+ 109
- 0
src/api/auth/api.auth.ts View File

@ -0,0 +1,109 @@
import { IRegisterData, IAuthLoginResponse, ILoginData, IAuthRegisterResponse, IAuthProfileResponse, IAuthResetPassword } from './api.auth.interface';
import { environment } from '../../environments/environment';
export class CAuth {
public get AccessToken(): string | null {
return window.localStorage.getItem('melon:access-token')
}
public set AccessToken(value: string | null) {
value == null ?
window.localStorage.removeItem('melon:access-token') :
window.localStorage.setItem('melon:access-token', value!)
}
public async Register(data: IRegisterData): Promise<IAuthRegisterResponse> {
try {
let res = await fetch(`${environment.endpoint}/users`, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'content-type': 'application/json'
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async Login(data: ILoginData): Promise<IAuthLoginResponse> {
try {
let res = await fetch(`${environment.endpoint}/auth`, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'content-type': 'application/json'
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async Me(): Promise<IAuthProfileResponse | null> {
try {
if (!this.AccessToken) return Promise.resolve(null)
let res = await fetch(`${environment.endpoint}/auth/profile`, {
method: 'GET',
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${this.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async RequestResetPassword(email: string): Promise<IAuthResetPassword> {
try {
let res = await fetch(`${environment.endpoint}/users/password/send/email`, {
method: 'POST',
body: JSON.stringify({ email }),
headers: {
'content-type': 'application/json'
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async ResetPassword(email: string, password: string, token: string): Promise<IAuthResetPassword> {
try {
let res = await fetch(`${environment.endpoint}/users/password/check/email`, {
method: 'POST',
body: JSON.stringify({ email, password, token }),
headers: {
'content-type': 'application/json'
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async ChangePassword(password: string): Promise<IAuthResetPassword> {
try {
if (!this.AccessToken) return Promise.resolve({ 'status': false })
let res = await fetch(`${environment.endpoint}/users/password/update`, {
method: 'POST',
body: JSON.stringify({ password }),
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${this.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
}
export const Auth: CAuth = new CAuth()

+ 67
- 0
src/api/fund/api.fund.interface.ts View File

@ -0,0 +1,67 @@
export interface Fund {
id: number;
init_date: Date;
portfolio: Portfolio[];
chart: Chart[];
_id: string;
title: string;
description: string;
minimum_investment: number;
lock_time: number;
ftype: string;
kyc: boolean | undefined | null
createdAt: Date;
updatedAt: Date;
}
export interface Chart {
date: number;
percent: number;
}
export interface Portfolio {
title: string;
color: string;
percent: number;
}
export interface IFundResponse {
funds: Fund
}
export type IFundsResponse = Fund[]
export interface IFundType {
type: string
name: string
description: string
}
export interface IInvestData {
value: number
fund_id: string
}
export interface IDeinvestData {
id: string
}
export interface IInvestResponse {
id: string
}
export interface IInvest {
id: number;
status: number;
created_at: Date;
updated_at: Date;
_id: string;
user_id: number;
type: string;
currency: string;
value: number;
fund_id: string;
locked: boolean;
}
export type IInvests = IInvest[]

+ 102
- 0
src/api/fund/api.fund.ts View File

@ -0,0 +1,102 @@
import { IDeinvestData, IFundResponse, IFundsResponse, IFundType, IInvestData, IInvestResponse, IInvests } from "./api.fund.interface";
import { environment } from '../../environments/environment';
import { Auth } from "../auth/api.auth";
export class CFund {
public async All(): Promise<IFundsResponse> {
try {
let res = await fetch(`${environment.endpoint}/fund/all`, {
method: 'GET',
headers: {
'content-type': 'application/json',
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async One(id: string): Promise<IFundResponse> {
try {
let res = await fetch(`${environment.endpoint}/fund/${id}`, {
method: 'GET',
headers: {
'content-type': 'application/json',
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async Type(): Promise<IFundType[]> {
try {
let res = await fetch(`${environment.endpoint}/fund/types`, {
method: 'GET',
headers: {
'content-type': 'application/json',
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async Invest(data: IInvestData): Promise<IInvestResponse> {
try {
(data as any).type = 'stake';
(data as any).currency = 'USDT';
let res = await fetch(`${environment.endpoint}/stakes`, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async Deinvest(data: IDeinvestData): Promise<IInvestResponse> {
try {
(data as any).type = 'unstake';
(data as any).currency = 'USDT';
let res = await fetch(`${environment.endpoint}/stakes`, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async Table(): Promise<IInvests> {
try {
let res = await fetch(`${environment.endpoint}/stakes`, {
method: 'GET',
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
}
export const Fund: CFund = new CFund()

+ 19
- 0
src/api/kyc/api.kyc.interface.ts View File

@ -0,0 +1,19 @@
export interface IUploadResponse {
status: number
}
export type UploadID = 'nationalId' | 'selfi'
export interface ISubmitData {
name: string,
lastName: string,
homeNumber: string,
BirthDate: string,
nationalId: string,
city: string,
address: string
}
export interface ISubmitResponse {
status: boolean
}

+ 116
- 0
src/api/kyc/api.kyc.ts View File

@ -0,0 +1,116 @@
import { ISubmitData, ISubmitResponse, IUploadResponse, UploadID } from "./api.kyc.interface";
import { environment } from '../../environments/environment';
import { Auth } from "../auth/api.auth";
export class CKYC {
public async Upload(id: UploadID, file: File): Promise<IUploadResponse> {
try {
let form = new FormData()
form.append(id, file)
let res = await fetch(`${environment.endpoint}/users/kyc/${id}`, {
method: 'POST',
body: form,
headers: {
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async Submit(data: ISubmitData): Promise<ISubmitResponse> {
try {
(data as any).token = 'is_angular'
let res = await fetch(`${environment.endpoint}/users/kyc/check/final`, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async SendEmailToken(): Promise<any> {
try {
let res = await fetch(`${environment.endpoint}/users/kyc/send/email`, {
method: 'GET',
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async SendPhoneToken(): Promise<any> {
try {
let res = await fetch(`${environment.endpoint}/users/kyc/send/sms`, {
method: 'GET',
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async VerifyEmailToken(token: string): Promise<ISubmitResponse> {
try {
let res = await fetch(`${environment.endpoint}/users/kyc/check/email`, {
method: 'POST',
body: JSON.stringify({ token }),
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async VerifyPhoneToken(token: string): Promise<ISubmitResponse> {
try {
let res = await fetch(`${environment.endpoint}/users/kyc/check/sms`, {
method: 'POST',
body: JSON.stringify({ token }),
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public ImageOf(file: string): string {
return `${environment.endpoint}/uploads/kyc/${file}`
}
}
export const KYC: CKYC = new CKYC()

+ 6
- 0
src/api/system/api.system.interface.ts View File

@ -0,0 +1,6 @@
export interface INetwork {
type: 'ERC20' | 'TRC20' | 'KCC'
address: string
fee: number
description: string
}

+ 20
- 0
src/api/system/api.system.ts View File

@ -0,0 +1,20 @@
import { INetwork } from "./api.system.interface";
import { environment } from '../../environments/environment';
export class CSystem {
public async Networks(): Promise<INetwork[]> {
try {
let res = await fetch(`${environment.endpoint}/wallet/system/list`, {
method: 'GET',
headers: {
'content-type': 'application/json',
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
}
export const System: CSystem = new CSystem()

+ 33
- 0
src/api/transactions/api.transactions.interface.ts View File

@ -0,0 +1,33 @@
export interface Transaction {
id: number;
fee: number;
status: number;
tx_id: string;
created_at: Date;
updated_at: Date;
_id: string;
user_id: number;
type: 'deposit' | 'withdraw';
currency: string;
value: number;
network: string;
wallet: string;
}
export type Transactions = Transaction[]
export interface ITransactionResponse {
id: string
}
export interface IDepositData {
network: string
value: number
tx_id: string
}
export interface IWithdrawData {
network: string
value: number
wallet: string
}

+ 58
- 0
src/api/transactions/api.transactions.ts View File

@ -0,0 +1,58 @@
import { IDepositData, ITransactionResponse, IWithdrawData, Transactions } from "./api.transactions.interface"
import { environment } from '../../environments/environment'
import { Auth } from "../auth/api.auth"
export class CTransaction {
public async All(): Promise<Transactions> {
try {
let res = await fetch(`${environment.endpoint}/transactions`, {
method: 'GET',
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async Deposit(data: IDepositData): Promise<ITransactionResponse> {
try {
(data as any)['type'] = 'deposit';
(data as any)['currency'] = 'USDT';
let res = await fetch(`${environment.endpoint}/transactions`, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async Widthdraw(data: IWithdrawData): Promise<ITransactionResponse> {
try {
(data as any)['type'] = 'withdraw';
(data as any)['currency'] = 'USDT';
let res = await fetch(`${environment.endpoint}/transactions`, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
}
export const Transaction: CTransaction = new CTransaction()

+ 14
- 0
src/api/wallet/api.wallet.interface.ts View File

@ -0,0 +1,14 @@
export interface Wallet {
id: number;
status: number;
last_locked_at: Date;
_id: string;
user_id: number;
balance: number;
locked: number;
createdAt: Date;
updatedAt: Date;
__v: number;
}
export type Wallets = Wallet[]

+ 37
- 0
src/api/wallet/api.wallet.ts View File

@ -0,0 +1,37 @@
import { Wallets } from "./api.wallet.interface";
import { environment } from '../../environments/environment';
import { Auth } from "../auth/api.auth";
export class CWallet {
public async All(): Promise<Wallets> {
try {
let res = await fetch(`${environment.endpoint}/wallet`, {
method: 'GET',
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
public async Create(): Promise<Wallets> {
try {
let res = await fetch(`${environment.endpoint}/wallet`, {
method: 'POST',
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${Auth.AccessToken}`
}
})
return await res.json()
} catch (error) {
return Promise.reject(error)
}
}
}
export const Wallet: CWallet = new CWallet()

+ 19
- 0
src/app/app-routing.module.ts View File

@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: 'auth',
loadChildren: async () => (await import('../routes/auth/auth.module')).AuthModule
},
{
path: 'panel',
loadChildren: async () => (await import('../routes/view/view.module')).ViewModule
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

+ 1
- 0
src/app/app.component.html View File

@ -0,0 +1 @@
<router-outlet></router-outlet>

+ 0
- 0
src/app/app.component.scss View File


+ 35
- 0
src/app/app.component.spec.ts View File

@ -0,0 +1,35 @@
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'panel-boilerplate'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('panel-boilerplate');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('.content span')?.textContent).toContain('panel-boilerplate app is running!');
});
});

+ 10
- 0
src/app/app.component.ts View File

@ -0,0 +1,10 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'panel-boilerplate';
}

+ 20
- 0
src/app/app.module.ts View File

@ -0,0 +1,20 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

+ 0
- 0
src/assets/.gitkeep View File


BIN
src/assets/fonts/woff/IRANSansX-Bold.woff View File


BIN
src/assets/fonts/woff/IRANSansX-Regular.woff View File


BIN
src/assets/fonts/woff2/IRANSansX-Bold.woff2 View File


BIN
src/assets/fonts/woff2/IRANSansX-Regular.woff2 View File


+ 15
- 0
src/components/image/image.component.html View File

@ -0,0 +1,15 @@
<div class="image-container flex column ai-c jc-c" [ngClass]="{'disabled': disabled, 'error': error}">
<div class="click-area" (click)="click()"></div>
<ng-container *ngIf="deleteable && src && src.length != 0">
<button mat-icon-button color="warn" (click)="delete()">
<mat-icon>delete</mat-icon>
</button>
</ng-container>
<ng-container *ngIf="src == null || src.length == 0">
<mat-icon class="photo">insert_photo</mat-icon>
<span>افزودن تصویر</span>
</ng-container>
<ng-container *ngIf="src != null && src.length != 0">
<div class="image" [ngStyle]="{'background-image': 'url('+src+')'}"></div>
</ng-container>
</div>

+ 92
- 0
src/components/image/image.component.scss View File

@ -0,0 +1,92 @@
@mixin positionFrom($length) {
top: $length;
left: $length;
right: $length;
bottom: $length;
}
div.image-container {
height: inherit;
min-height: inherit;
max-height: inherit;
width: inherit;
min-width: inherit;
max-width: inherit;
border: 1px solid rgba($color: #000000, $alpha: 0.12);
border-radius: 5px;
cursor: pointer;
position: relative;
&::before {
content: "";
position: absolute;
@include positionFrom(-1px);
border: 2px solid rgba($color: #000000, $alpha: 0.6);
border-radius: 5px;
opacity: 0;
}
&:hover {
border-color: transparent;
&::before {
opacity: 1;
}
}
&.disabled {
pointer-events: none;
filter: grayscale(1);
color: rgba($color: #000000, $alpha: 0.6);
}
&.error {
border-color: var(--error-color);
}
div.click-area {
position: absolute;
@include positionFrom(0);
z-index: 1;
}
button[mat-icon-button] {
position: absolute;
@include positionFrom(5px);
z-index: 2;
}
mat-icon.photo {
width: 32px;
height: 32px;
font-size: 32px;
margin-bottom: 15px;
}
div.image {
position: absolute;
@include positionFrom(0);
background-size: contain;
background-repeat: no-repeat;
background-position: center center;
}
}

+ 25
- 0
src/components/image/image.component.spec.ts View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ImageComponent } from './image.component';
describe('ImageComponent', () => {
let component: ImageComponent;
let fixture: ComponentFixture<ImageComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ImageComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ImageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 128
- 0
src/components/image/image.component.ts View File

@ -0,0 +1,128 @@
import { Component, Input } from '@angular/core';
import { AbstractControl, ControlValueAccessor, NG_VALIDATORS, NG_VALUE_ACCESSOR, ValidationErrors, Validator } from '@angular/forms';
@Component({
selector: 'app-image',
templateUrl: './image.component.html',
styleUrls: ['./image.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: ImageComponent,
multi: true
},
{
provide: NG_VALIDATORS,
multi: true,
useExisting: ImageComponent
}
]
})
export class ImageComponent implements ControlValueAccessor, Validator {
public src: string | undefined | null;
public disabled: boolean = false;
public error: boolean = false;
private inited: boolean = false; // inited errors ?
@Input() deleteable: boolean = false;
// ControlValueAccessor Implementation
onChange: any = () => { };
onTouched: any = () => { };
onValidatorChange: any = () => { };
constructor() { }
validate(control: AbstractControl): ValidationErrors | null {
let error = null;
if (('required' in (control.errors || {}) && (control.errors || {}).required == true) && (control.value == null || (control.value as string).length == 0)) {
this.error = this.inited;
error = {
"required": true
};
} else {
this.error = false;
}
this.inited = true;
return error;
}
registerOnValidatorChange?(onValidatorChange: any): void {
this.onValidatorChange = onValidatorChange;
}
writeValue(value: string): void {
this.src = value;
}
registerOnChange(onChange: any): void {
this.onChange = onChange;
}
registerOnTouched(onTouched: any): void {
this.onTouched = onTouched;
}
setDisabledState(disabled: boolean): void {
this.disabled = disabled;
}
public delete(): void {
this.src = null;
this.onChange(null);
this.onTouched();
}
public async click(): Promise<void> {
try {
let file: File | null = await this.select();
if (file) {
let base64 = await this.toBase64(file);
this.src = base64;
this.onChange(this.src);
this.onTouched();
}
} catch (error) {
}
}
private select(): Promise<File | null> {
return new Promise((resolve) => {
let id = 'file-selector';
let input: HTMLInputElement = <HTMLInputElement>document.getElementById(id);
if (input) document.body.removeChild(input);
input = document.createElement('input');
input.type = 'file';
input.accept = [".jpg", ".png", ".jpeg", ".webp", ".svg"].join();
input.id = id;
input.style.display = 'none';
document.body.appendChild(input);
input.onchange = (event: any) => {
resolve(event.target['files'][0]);
}
input.focus();
input.click();
})
}
private toBase64(file: File): Promise<string | null> {
return new Promise((resolve) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = async () => {
resolve(reader.result ? reader.result.toString() : null);
}
});
}
}

+ 18
- 0
src/components/image/image.module.ts View File

@ -0,0 +1,18 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ImageComponent } from './image.component';
import { MaterialModule } from './material';
@NgModule({
declarations: [
ImageComponent
],
imports: [
CommonModule,
MaterialModule,
],
exports: [ImageComponent]
})
export class ImageModule { }

+ 15
- 0
src/components/image/material.ts View File

@ -0,0 +1,15 @@
import { NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
const modules: any[] = [
MatButtonModule,
MatIconModule,
];
@NgModule({
imports: modules,
exports: modules,
})
export class MaterialModule { }

+ 1
- 0
src/database/app.ts View File

@ -0,0 +1 @@
export const AppTitle = 'پنل مدیریت میدون';

+ 13
- 0
src/database/drawer.ts View File

@ -0,0 +1,13 @@
export interface IDrawerItem {
path: string
icon: string
title: string
}
export const drawerItems: IDrawerItem[] = [
{
path: '/panel/users',
icon: 'group',
title: 'کاربران'
}
];

+ 4
- 0
src/environments/environment.prod.ts View File

@ -0,0 +1,4 @@
export const environment = {
production: true,
endpoint: 'https://api.melonex.xyz'
};

+ 17
- 0
src/environments/environment.ts View File

@ -0,0 +1,17 @@
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false,
endpoint: 'https://api.melonex.xyz'
};
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.

BIN
src/favicon.ico View File

Before After
Width: 28  |  Height: 30  |  Size: 948 B

+ 18
- 0
src/index.html View File

@ -0,0 +1,18 @@
<!doctype html>
<html lang="fa" dir="rtl">
<head>
<meta charset="utf-8">
<title>پنل مدیریت</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<app-root></app-root>
</body>
</html>

+ 12
- 0
src/main.ts View File

@ -0,0 +1,12 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

+ 11
- 0
src/material.empty.ts View File

@ -0,0 +1,11 @@
import { NgModule } from '@angular/core';
const modules: any[] = [
];
@NgModule({
imports: modules,
exports: modules,
})
export class MaterialModule { }

+ 65
- 0
src/polyfills.ts View File

@ -0,0 +1,65 @@
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/**
* IE11 requires the following for NgClass support on SVG elements
*/
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch