Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/assets/background/kinhlup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/background/laptop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/background/tham.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/background/traidat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions public/assets/background/traidat.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/background/vi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/background/vo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions public/assets/background/vutru.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/app/core/models/statistics.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,13 @@ export type SummaryStatisticsAdmin = {
totalSubmissions: number;
totalPassedSubmissions: number;
};
export type PaymentStatisticsAdmin = {
day: string;
totalAmount: number;
};
export type PaymentStatisticsUser = {
day: string;
depositAmount: number;
purchaseAmount: number;
walletBalance: number;
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,19 @@ export function sidebarStatisticsRouter(roles: string[]): SidebarItem[] {
icon: 'fa-solid fa-chart-pie',
isVisible: !roles.includes(auth_lv2[0]),
},
{
id: 'chart-payment-statistics',
path: '/codecampus-statistics/admin-payment-statistics',
label: 'Thống kê doanh thu',
icon: 'fa-solid fa-file-invoice-dollar',
isVisible: !roles.includes(auth_lv2[0]),
},
{
id: 'chart-user-payment-statistics',
path: '/codecampus-statistics/user-payment-statistics',
label: 'Thống kê nạp & mua',
icon: 'fa-solid fa-credit-card',
isVisible: !roles.includes(auth_lv2[0]),
},
];
}
12 changes: 12 additions & 0 deletions src/app/core/services/api-service/statistics.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { ApiMethod } from '../config-service/api.methods';
import { ApiResponse, IPaginationResponse } from '../../models/api-response';
import {
ExerciseStatisticsResponse,
PaymentStatisticsAdmin,
PaymentStatisticsUser,
SummaryStatisticsAdmin,
} from '../../models/statistics.model';
import { API_CONFIG } from '../config-service/api.enpoints';
Expand All @@ -24,4 +26,14 @@ export class StatisticsService {
API_CONFIG.ENDPOINTS.GET.GET_SUMMARY_STATISTICS_ADMIN
);
}
getAdminPaymentStats(year: number, month: number) {
return this.api.get<ApiResponse<PaymentStatisticsAdmin[]>>(
API_CONFIG.ENDPOINTS.GET.GET_PAYMENT_STATISTICS_ADMIN(year, month)
);
}
getUserPaymentStats(year: number, month: number) {
return this.api.get<ApiResponse<PaymentStatisticsUser[]>>(
API_CONFIG.ENDPOINTS.GET.GET_USER_PAYMENT_STATISTICS_ADMIN(year, month)
);
}
}
4 changes: 4 additions & 0 deletions src/app/core/services/config-service/api.enpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ export const API_CONFIG = {

GET_EXERCISE_STATISTICS_ADMIN: (page: number, size: number) =>
`/submission/stats/admin/exercises?page=${page}&size=${size}`,
GET_PAYMENT_STATISTICS_ADMIN: (year: number, month: number) =>
`/payment/payment-statistics/daily-deposit?year=${year}&month=${month}`,
GET_USER_PAYMENT_STATISTICS_ADMIN: (year: number, month: number) =>
`/payment/payment-statistics/daily-statistic?year=${year}&month=${month}`,
GET_SUMMARY_STATISTICS_ADMIN: '/submission/stats/admin/summary',
},
POST: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
<div class="interactive-container">
<!-- Parallax layers -->
<div class="parallax parallax-bg"></div>
<div class="parallax parallax-earth"></div>
<div class="parallax parallax-rocket"></div>
<div class="parallax parallax-robot"></div>

<!-- New elements -->
<div class="parallax parallax-laptop"></div>
<div class="parallax parallax-kinhlup"></div>
<div class="parallax parallax-tham"></div>
<div class="parallax parallax-vo"></div>
<div class="parallax parallax-vi"></div>

<!-- Sticky content -->
<div class="sticky-wrapper">
<canvas #animationCanvas></canvas>
<div class="overlay-text">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,219 @@
.interactive-container {
// Tạo không gian để cuộn, chiều cao gấp 3 lần màn hình
height: 200vh;
height: 150vh;
position: relative;
background-color: #0a0a1a; // Nền tối để nổi bật animation
overflow: hidden;

background-image:
/* lớp overlay đen fade trong suốt ở trên/dưới */ linear-gradient(
to bottom,
rgba(0, 0, 0, 0) 0%,
rgba(0, 0, 0, 0.6) 20%,
rgba(0, 0, 0, 0.6) 80%,
rgba(0, 0, 0, 0) 100%
),
/* lớp ảnh vũ trụ có gradient để mờ dần */
linear-gradient(
to bottom,
rgba(0, 0, 0, 0.6) 0%,
rgba(0, 0, 0, 0) 20%,
rgba(0, 0, 0, 0) 80%,
rgba(0, 0, 0, 0.6) 100%
),
url("../../../../../../public/assets/background/vutru.svg");

background-size: cover;
background-position: center;
background-repeat: no-repeat;

.parallax,
.sticky-wrapper {
position: relative;
z-index: 1;
}

.parallax {
position: absolute;
background-repeat: no-repeat;
background-size: contain;
background-position: center;
will-change: transform;
}

.parallax-earth {
top: 50%;
left: 50%;
width: 60vw;
height: 60vh;
transform: translate(-50%, -50%);
position: absolute;
z-index: 1;

background: url("../../../../../../public/assets/background/traidat.png")
center/contain no-repeat;

-webkit-mask-image: url("../../../../../../public/assets/background/traidat.png");
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
mask-image: url("../../../../../../public/assets/background/traidat.png");
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;

&::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(
135deg,
rgba(255, 255, 249, 0.6),
rgba(3, 18, 181, 0.6)
);
opacity: 0.6;
pointer-events: none;

-webkit-mask-image: url("../../../../../../public/assets/background/traidat.png");
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
mask-image: url("../../../../../../public/assets/background/traidat.png");
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
}
}

/* Gom cụm về góc dưới bên phải */
.parallax-laptop,
.parallax-kinhlup,
.parallax-tham,
.parallax-vo,
.parallax-vi {
position: absolute;
top: auto;
left: auto;
bottom: 0;
right: -20%;
transform: translate(-50%, -50%);
background-repeat: no-repeat;
background-size: contain;
will-change: transform;

/* overlay sáng giống parallax-earth */
&::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(
135deg,
rgba(255, 241, 241, 0.4),
rgba(26, 5, 118, 0.5)
);
pointer-events: none;
}
}

/* Laptop chính, to và nghiêng nhẹ */
.parallax-laptop {
width: 65vw;
height: 65vh;
background-image: url("../../../../../../public/assets/background/laptop.png");
transform: translate(-50%, -50%) rotate(-20deg);
top: 70%;
bottom: 10%;
z-index: 5;

&::before {
-webkit-mask-image: url("../../../../../../public/assets/background/laptop.png");
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
mask-image: url("../../../../../../public/assets/background/laptop.png");
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
}
}

.parallax-vo {
width: 55vw;
height: 50vh;
background-image: url("../../../../../../public/assets/background/vo.png");
bottom: 55%;
right: 50%;
z-index: 4;

&::before {
-webkit-mask-image: url("../../../../../../public/assets/background/vo.png");
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
mask-image: url("../../../../../../public/assets/background/vo.png");
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
}
}

.parallax-tham {
width: 55vw;
height: 40vh;
background-image: url("../../../../../../public/assets/background/tham.png");
bottom: 10%;
right: 40%;
z-index: 3;

&::before {
-webkit-mask-image: url("../../../../../../public/assets/background/tham.png");
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
mask-image: url("../../../../../../public/assets/background/tham.png");
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
}
}

.parallax-kinhlup {
width: 28vw;
height: 28vh;
background-image: url("../../../../../../public/assets/background/kinhlup.png");
bottom: 80%;
right: 0;
z-index: 6;

&::before {
-webkit-mask-image: url("../../../../../../public/assets/background/kinhlup.png");
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
mask-image: url("../../../../../../public/assets/background/kinhlup.png");
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
}
}

.parallax-vi {
width: 38vw;
height: 32vh;
background-image: url("../../../../../../public/assets/background/vi.png");
bottom: 40%;
right: -10%;
z-index: 4;

&::before {
-webkit-mask-image: url("../../../../../../public/assets/background/vi.png");
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
mask-image: url("../../../../../../public/assets/background/vi.png");
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
}
}

.sticky-wrapper {
position: sticky;
Expand All @@ -11,24 +222,15 @@
width: 100%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
z-index: 1;

canvas {
width: 80%;
height: 80%;
object-fit: contain;
}
align-items: flex-start;
z-index: 3;

.overlay-text {
position: absolute;
color: white;
text-align: center;
max-width: 600px;
// Hiệu ứng chữ mờ dần khi cuộn
opacity: 1;
transition: opacity 0.5s ease;
transition: opacity 0.5s ease, transform 0.5s ease;
}
}
}
Loading
Loading