Initial commit

This commit is contained in:
blessyjackulin17-dot 2026-03-18 20:07:20 +05:30
parent bd602f0d9f
commit 30972d601e
44 changed files with 3849 additions and 348 deletions

View File

@ -24,14 +24,16 @@
"input": "public"
}
],
"styles": [
"src/styles.css"
],
"server": "src/main.server.ts",
"outputMode": "server",
"security": {
"allowedHosts": []
},
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/bootstrap-icons/font/bootstrap-icons.css",
"src/styles.css"
],
"ssr": {
"entry": "src/server.ts"
}

50
package-lock.json generated
View File

@ -16,6 +16,8 @@
"@angular/platform-server": "^21.2.0",
"@angular/router": "^21.2.0",
"@angular/ssr": "^21.2.2",
"bootstrap": "^5.3.8",
"bootstrap-icons": "^1.13.1",
"express": "^5.1.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0"
@ -745,6 +747,7 @@
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.29.0",
"@babel/generator": "^7.29.0",
@ -3222,6 +3225,17 @@
"license": "MIT",
"optional": true
},
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
"license": "MIT",
"peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@rolldown/binding-android-arm64": {
"version": "1.0.0-rc.4",
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.4.tgz",
@ -4424,6 +4438,41 @@
"dev": true,
"license": "ISC"
},
"node_modules/bootstrap": {
"version": "5.3.8",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz",
"integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"license": "MIT",
"peerDependencies": {
"@popperjs/core": "^2.11.8"
}
},
"node_modules/bootstrap-icons": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.13.1.tgz",
"integrity": "sha512-ijombt4v6bv5CLeXvRWKy7CuM3TRTuPEuGaGKvTV5cz65rQSY8RQ2JcHt6b90cBBAC7s8fsf2EkQDldzCoXUjw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"license": "MIT"
},
"node_modules/brace-expansion": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
@ -6057,6 +6106,7 @@
"integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"cli-truncate": "^5.0.0",
"colorette": "^2.0.20",

View File

@ -20,6 +20,8 @@
"@angular/platform-server": "^21.2.0",
"@angular/router": "^21.2.0",
"@angular/ssr": "^21.2.2",
"bootstrap": "^5.3.8",
"bootstrap-icons": "^1.13.1",
"express": "^5.1.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0"

View File

@ -0,0 +1,218 @@
/* =========================
NAVBAR STYLING
========================= */
:root {
--primary-color: #3b3c7a;
--primary-dark: #322e7d;
--primary-light: #353d76;
--secondary-color: #ec4899;
--text-dark: #1f2937;
--text-light: #f3f4f6;
--border-color: #e5e7eb;
}
/* Navbar Container */
.navbar-custom {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-dark) 100%);
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.15);
padding: 1rem 0;
position: sticky;
top: 0;
z-index: 1000;
transition: all 0.3s ease;
}
.navbar-custom:hover {
box-shadow: 0 6px 16px rgba(99, 102, 241, 0.25);
}
/* Brand/Logo Styling */
.navbar-brand {
font-size: 1.6rem;
font-weight: 700;
color: white !important;
display: flex;
align-items: center;
gap: 0.5rem;
transition: all 0.3s ease;
text-decoration: none;
}
.brand-text {
background: linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.brand-icon {
font-size: 2rem;
display: inline-block;
}
.navbar-brand:hover {
transform: scale(1.05);
filter: brightness(1.1);
}
/* Navigation Links */
.nav-link-custom {
color: rgba(255, 255, 255, 0.85) !important;
font-weight: 500;
font-size: 1rem;
padding: 0.5rem 1rem !important;
border-radius: 6px;
transition: all 0.3s ease;
position: relative;
text-decoration: none;
white-space: nowrap;
}
.nav-link-custom::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: white;
border-radius: 2px;
transition: width 0.3s ease;
}
.nav-link-custom:hover {
color: white !important;
background: rgba(255, 255, 255, 0.1);
transform: translateY(-2px);
}
.nav-link-custom:hover::after {
width: calc(100% - 2rem);
}
.nav-link-custom.active {
color: white !important;
background: rgba(255, 255, 255, 0.2);
font-weight: 600;
}
.nav-link-custom.active::after {
width: calc(100% - 2rem);
background: #fbbf24;
}
/* Action Buttons */
.btn-signup,
.btn-login {
border-radius: 20px;
padding: 0.5rem 1.2rem !important;
font-weight: 600;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.btn-signup {
background: rgba(255, 255, 255, 0.2);
color: white !important;
border-color: white;
}
.btn-signup:hover {
background: white;
color: var(--primary-color) !important;
transform: translateY(-3px);
box-shadow: 0 4px 12px rgba(255, 255, 255, 0.3);
}
.btn-login {
background: white;
color: var(--primary-color) !important;
border-color: white;
}
.btn-login:hover {
background: var(--primary-light);
color: white !important;
transform: translateY(-3px);
box-shadow: 0 6px 16px rgba(129, 140, 248, 0.4);
}
/* Mobile Responsive */
@media (max-width: 991px) {
.navbar-brand {
font-size: 1.3rem;
}
.nav-link-custom {
padding: 0.75rem 1rem !important;
}
.navbar-custom {
padding: 0.75rem 0;
}
.collapse.navbar-collapse {
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
}
/* Navbar Toggler */
.navbar-toggler {
border-color: rgba(255, 255, 255, 0.5) !important;
}
.navbar-toggler:focus {
box-shadow: 0 0 0 0.25rem rgba(255, 255, 255, 0.25) !important;
}
.navbar-toggler-icon {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.85%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") !important;
}
/* =========================
MAIN CONTENT AREA
========================= */
.main-content {
min-height: calc(100vh - 70px);
padding: 2rem 0;
background: linear-gradient(135deg, #f9fafb 0%, #f3f4f6 100%);
}
.container {
max-width: 1200px;
}
/* =========================
SMOOTH SCROLL & ANIMATIONS
========================= */
html {
scroll-behavior: smooth;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: var(--text-dark);
background-color: #f9fafb;
}
/* Fade in animation */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
router-outlet~* {
animation: fadeIn 0.5s ease-out;
}

View File

@ -1,344 +1,46 @@
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
<!-- * * * * * * * * * * * The content below * * * * * * * * * * * -->
<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * -->
<!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * -->
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
<!-- * * * * * * * * * Delete the template below * * * * * * * * * -->
<!-- * * * * * * * to get started with your project! * * * * * * * -->
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
<style>
:host {
--bright-blue: oklch(51.01% 0.274 263.83);
--electric-violet: oklch(53.18% 0.28 296.97);
--french-violet: oklch(47.66% 0.246 305.88);
--vivid-pink: oklch(69.02% 0.277 332.77);
--hot-red: oklch(61.42% 0.238 15.34);
--orange-red: oklch(63.32% 0.24 31.68);
--gray-900: oklch(19.37% 0.006 300.98);
--gray-700: oklch(36.98% 0.014 302.71);
--gray-400: oklch(70.9% 0.015 304.04);
--red-to-pink-to-purple-vertical-gradient: linear-gradient(
180deg,
var(--orange-red) 0%,
var(--vivid-pink) 50%,
var(--electric-violet) 100%
);
--red-to-pink-to-purple-horizontal-gradient: linear-gradient(
90deg,
var(--orange-red) 0%,
var(--vivid-pink) 50%,
var(--electric-violet) 100%
);
--pill-accent: var(--bright-blue);
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol";
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: block;
height: 100dvh;
}
h1 {
font-size: 3.125rem;
color: var(--gray-900);
font-weight: 500;
line-height: 100%;
letter-spacing: -0.125rem;
margin: 0;
font-family: "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol";
}
p {
margin: 0;
color: var(--gray-700);
}
main {
width: 100%;
min-height: 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 1rem;
box-sizing: inherit;
position: relative;
}
.angular-logo {
max-width: 9.2rem;
}
.content {
display: flex;
justify-content: space-around;
width: 100%;
max-width: 700px;
margin-bottom: 3rem;
}
.content h1 {
margin-top: 1.75rem;
}
.content p {
margin-top: 1.5rem;
}
.divider {
width: 1px;
background: var(--red-to-pink-to-purple-vertical-gradient);
margin-inline: 0.5rem;
}
.pill-group {
display: flex;
flex-direction: column;
align-items: start;
flex-wrap: wrap;
gap: 1.25rem;
}
.pill {
display: flex;
align-items: center;
--pill-accent: var(--bright-blue);
background: color-mix(in srgb, var(--pill-accent) 5%, transparent);
color: var(--pill-accent);
padding-inline: 0.75rem;
padding-block: 0.375rem;
border-radius: 2.75rem;
border: 0;
transition: background 0.3s ease;
font-family: var(--inter-font);
font-size: 0.875rem;
font-style: normal;
font-weight: 500;
line-height: 1.4rem;
letter-spacing: -0.00875rem;
text-decoration: none;
white-space: nowrap;
}
.pill:hover {
background: color-mix(in srgb, var(--pill-accent) 15%, transparent);
}
.pill-group .pill:nth-child(6n + 1) {
--pill-accent: var(--bright-blue);
}
.pill-group .pill:nth-child(6n + 2) {
--pill-accent: var(--electric-violet);
}
.pill-group .pill:nth-child(6n + 3) {
--pill-accent: var(--french-violet);
}
.pill-group .pill:nth-child(6n + 4),
.pill-group .pill:nth-child(6n + 5),
.pill-group .pill:nth-child(6n + 6) {
--pill-accent: var(--hot-red);
}
.pill-group svg {
margin-inline-start: 0.25rem;
}
.social-links {
display: flex;
align-items: center;
gap: 0.73rem;
margin-top: 1.5rem;
}
.social-links path {
transition: fill 0.3s ease;
fill: var(--gray-400);
}
.social-links a:hover svg path {
fill: var(--gray-900);
}
@media screen and (max-width: 650px) {
.content {
flex-direction: column;
width: max-content;
}
.divider {
height: 1px;
width: 100%;
background: var(--red-to-pink-to-purple-horizontal-gradient);
margin-block: 1.5rem;
}
}
</style>
<main class="main">
<div class="content">
<div class="left-side">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 982 239"
fill="none"
class="angular-logo"
>
<g clip-path="url(#a)">
<path
fill="url(#b)"
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.602 64.311h-44.431Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.039-7.037 7.037 0 12.846 1.145 17.347 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.745 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.618 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.009 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.092 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.814 58.814 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
/>
<path
fill="url(#c)"
d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.602 64.311h-44.431Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.039-7.037 7.037 0 12.846 1.145 17.347 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.745 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.618 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.009 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.092 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.814 58.814 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
/>
</g>
<defs>
<radialGradient
id="c"
cx="0"
cy="0"
r="1"
gradientTransform="rotate(118.122 171.182 60.81) scale(205.794)"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#FF41F8" />
<stop offset=".707" stop-color="#FF41F8" stop-opacity=".5" />
<stop offset="1" stop-color="#FF41F8" stop-opacity="0" />
</radialGradient>
<linearGradient
id="b"
x1="0"
x2="982"
y1="192"
y2="192"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#F0060B" />
<stop offset="0" stop-color="#F0070C" />
<stop offset=".526" stop-color="#CC26D5" />
<stop offset="1" stop-color="#7702FF" />
</linearGradient>
<clipPath id="a"><path fill="#fff" d="M0 0h982v239H0z" /></clipPath>
</defs>
</svg>
<h1>Hello, {{ title() }}</h1>
<p>Congratulations! Your app is running. 🎉</p>
</div>
<div class="divider" role="separator" aria-label="Divider"></div>
<div class="right-side">
<div class="pill-group">
@for (item of [
{ title: 'Explore the Docs', link: 'https://angular.dev' },
{ title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' },
{ title: 'Prompt and best practices for AI', link: 'https://angular.dev/ai/develop-with-ai'},
{ title: 'CLI Docs', link: 'https://angular.dev/tools/cli' },
{ title: 'Angular Language Service', link: 'https://angular.dev/tools/language-service' },
{ title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' },
]; track item.title) {
<a
class="pill"
[href]="item.link"
target="_blank"
rel="noopener"
>
<span>{{ item.title }}</span>
<svg
xmlns="http://www.w3.org/2000/svg"
height="14"
viewBox="0 -960 960 960"
width="14"
fill="currentColor"
>
<path
d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z"
/>
</svg>
<nav class="navbar navbar-expand-lg navbar-custom">
<div class="container-fluid">
<!-- Brand/Logo -->
<a routerLink="/landing" class="navbar-brand brand-text">
<span class="brand-icon">📚</span>
NextGen Learning Hub
</a>
}
</div>
<div class="social-links">
<a
href="https://github.com/angular/angular"
aria-label="Github"
target="_blank"
rel="noopener"
>
<svg
width="25"
height="24"
viewBox="0 0 25 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
alt="Github"
>
<path
d="M12.3047 0C5.50634 0 0 5.50942 0 12.3047C0 17.7423 3.52529 22.3535 8.41332 23.9787C9.02856 24.0946 9.25414 23.7142 9.25414 23.3871C9.25414 23.0949 9.24389 22.3207 9.23876 21.2953C5.81601 22.0377 5.09414 19.6444 5.09414 19.6444C4.53427 18.2243 3.72524 17.8449 3.72524 17.8449C2.61064 17.082 3.81137 17.0973 3.81137 17.0973C5.04697 17.1835 5.69604 18.3647 5.69604 18.3647C6.79321 20.2463 8.57636 19.7029 9.27978 19.3881C9.39052 18.5924 9.70736 18.0499 10.0591 17.7423C7.32641 17.4347 4.45429 16.3765 4.45429 11.6618C4.45429 10.3185 4.9311 9.22133 5.72065 8.36C5.58222 8.04931 5.16694 6.79833 5.82831 5.10337C5.82831 5.10337 6.85883 4.77319 9.2121 6.36459C10.1965 6.09082 11.2424 5.95546 12.2883 5.94931C13.3342 5.95546 14.3801 6.09082 15.3644 6.36459C17.7023 4.77319 18.7328 5.10337 18.7328 5.10337C19.3942 6.79833 18.9789 8.04931 18.8559 8.36C19.6403 9.22133 20.1171 10.3185 20.1171 11.6618C20.1171 16.3888 17.2409 17.4296 14.5031 17.7321C14.9338 18.1012 15.3337 18.8559 15.3337 20.0084C15.3337 21.6552 15.3183 22.978 15.3183 23.3779C15.3183 23.7009 15.5336 24.0854 16.1642 23.9623C21.0871 22.3484 24.6094 17.7341 24.6094 12.3047C24.6094 5.50942 19.0999 0 12.3047 0Z"
/>
</svg>
<!-- Toggler for mobile -->
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<!-- Nav links -->
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto gap-2">
<li class="nav-item">
<a routerLink="/landing" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}"
class="nav-link nav-link-custom">
🏠 Home
</a>
<a
href="https://x.com/angular"
aria-label="X"
target="_blank"
rel="noopener"
>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
alt="X"
>
<path
d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"
/>
</svg>
</li>
<li class="nav-item">
<a routerLink="/courses" routerLinkActive="active" class="nav-link nav-link-custom">
📖 Courses
</a>
<a
href="https://www.youtube.com/channel/UCbn1OgGei-DV7aSRo_HaAiw"
aria-label="Youtube"
target="_blank"
rel="noopener"
>
<svg
width="29"
height="20"
viewBox="0 0 29 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
alt="Youtube"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M27.4896 1.52422C27.9301 1.96749 28.2463 2.51866 28.4068 3.12258C29.0004 5.35161 29.0004 10 29.0004 10C29.0004 10 29.0004 14.6484 28.4068 16.8774C28.2463 17.4813 27.9301 18.0325 27.4896 18.4758C27.0492 18.9191 26.5 19.2389 25.8972 19.4032C23.6778 20 14.8068 20 14.8068 20C14.8068 20 5.93586 20 3.71651 19.4032C3.11363 19.2389 2.56449 18.9191 2.12405 18.4758C1.68361 18.0325 1.36732 17.4813 1.20683 16.8774C0.613281 14.6484 0.613281 10 0.613281 10C0.613281 10 0.613281 5.35161 1.20683 3.12258C1.36732 2.51866 1.68361 1.96749 2.12405 1.52422C2.56449 1.08095 3.11363 0.76113 3.71651 0.596774C5.93586 0 14.8068 0 14.8068 0C14.8068 0 23.6778 0 25.8972 0.596774C26.5 0.76113 27.0492 1.08095 27.4896 1.52422ZM19.3229 10L11.9036 5.77905V14.221L19.3229 10Z"
/>
</svg>
</li>
<li class="nav-item">
<a routerLink="/signup" class="nav-link nav-link-custom btn-signup">
Sign Up
</a>
</li>
<li class="nav-item">
<a routerLink="/login" class="nav-link nav-link-custom btn-login">
Log In
</a>
</li>
</ul>
</div>
</div>
</div>
</nav>
<main class="main-content">
<router-outlet></router-outlet>
</main>
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
<!-- * * * * * * * * * * * The content above * * * * * * * * * * * * -->
<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * * -->
<!-- * * * * * * * * * * and can be replaced. * * * * * * * * * * * -->
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
<!-- * * * * * * * * * * End of Placeholder * * * * * * * * * * * * -->
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
<router-outlet />

View File

@ -1,3 +1,41 @@
import { Routes } from '@angular/router';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LandingComponent } from './landing/landing';
import { SignupComponent } from './signup/signup';
import { LoginComponent } from './login/login';
import { ForgotComponent } from './forgot/forgot';
import { CourseListComponent } from './course-list/course-list';
import { EnrollmentFormComponent } from './enrollment-form/enrollment-form';
import { TermsComponent } from './terms/terms';
import { PaymentComponent } from './payment/payment';
import { PaymentSuccessComponent } from './payment-success/payment-success';
export const routes: Routes = [
{path: '', redirectTo: 'login', pathMatch: 'full'},
{ path: 'landing', component: LandingComponent },
{ path: 'signup', component: SignupComponent },
{ path: 'login', component: LoginComponent },
{ path: 'forgot', component: ForgotComponent },
{ path: 'courses', component: CourseListComponent },
{ path: 'enroll', component: EnrollmentFormComponent },
{ path: 'terms', component: TermsComponent },
{ path: 'payment', component: PaymentComponent },
{ path: 'success', component: PaymentSuccessComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
export const routes: Routes = [];

View File

@ -1,9 +1,10 @@
import { Component, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
imports: [RouterOutlet],
imports: [RouterOutlet, RouterLink, RouterLinkActive, CommonModule],
templateUrl: './app.html',
styleUrl: './app.css'
})

View File

@ -0,0 +1,274 @@
/* ===== COURSE LIST PAGE STYLING ===== */
.courses-page {
min-height: 100vh;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}
/* Header Section */
.courses-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 4rem 0;
text-align: center;
}
.header-content h1 {
font-size: 2.8rem;
font-weight: 800;
margin-bottom: 0.5rem;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}
.header-content p {
font-size: 1.2rem;
opacity: 0.95;
}
/* Main Content */
.courses-container {
padding: 3rem 0;
}
.courses-content {
display: grid;
grid-template-columns: 1fr 60px 1fr;
gap: 2rem;
align-items: stretch;
}
/* Column Card Styling */
.column-card {
background: rgb(226, 224, 224);
border-radius: 16px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
overflow: hidden;
display: flex;
flex-direction: column;
animation: slideIn 0.6s ease-out;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.column-header {
padding: 1.5rem;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 600;
border-bottom: 2px solid #f0f0f0;
}
.available-header {
background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
color: #667eea;
}
.selected-header {
background: linear-gradient(135deg, rgba(76, 175, 80, 0.1) 0%, rgba(56, 249, 215, 0.1) 100%);
color: #4caf50;
}
.column-header h3 {
margin: 0;
font-size: 1.3rem;
}
.course-count {
background: rgba(0, 0, 0, 0.1);
padding: 0.3rem 0.8rem;
border-radius: 20px;
font-size: 0.85rem;
font-weight: 700;
}
/* Courses List */
.courses-list {
flex: 1;
padding: 1rem;
overflow-y: auto;
max-height: 400px;
}
.courses-list::-webkit-scrollbar {
width: 6px;
}
.courses-list::-webkit-scrollbar-track {
background: #cbc1c1;
}
.courses-list::-webkit-scrollbar-thumb {
background: #667eea;
border-radius: 3px;
}
.courses-list::-webkit-scrollbar-thumb:hover {
background: #5568d3;
}
/* Course Items */
.course-item-available,
.course-item-selected {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
margin-bottom: 0.5rem;
border-radius: 10px;
background: #f8f9fa;
border: 2px solid transparent;
transition: all 0.3s ease;
}
.course-item-available:hover {
border-color: #667eea;
background: rgba(102, 126, 234, 0.05);
transform: translateX(5px);
}
.course-item-selected:hover {
border-color: #4caf50;
background: rgba(76, 175, 80, 0.05);
transform: translateX(-5px);
}
.course-item-content {
display: flex;
align-items: center;
gap: 1rem;
flex: 1;
}
.course-icon {
font-size: 1.5rem;
}
.course-name {
font-weight: 600;
color: #1f2937;
}
/* Action Buttons */
.btn-add,
.btn-remove {
width: 40px;
height: 40px;
border-radius: 50%;
border: none;
cursor: pointer;
font-size: 1.2rem;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
font-weight: bold;
}
.btn-add {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
}
.btn-add:hover {
transform: scale(1.1) rotate(90deg);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}
.btn-remove {
background: linear-gradient(135deg, #f5576c, #f093fb);
color: white;
}
.btn-remove:hover {
transform: scale(1.1) rotate(90deg);
box-shadow: 0 4px 12px rgba(245, 87, 108, 0.3);
}
/* Column Divider */
.column-divider {
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
color: #667eea;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%,
100% {
opacity: 0.6;
}
50% {
opacity: 1;
}
}
/* Empty State */
.empty-state {
display: flex;
align-items: center;
justify-content: center;
height: 150px;
color: #9ca3af;
font-size: 1.1rem;
text-align: center;
}
/* Proceed Button */
.btn-proceed {
width: 100%;
padding: 1rem;
background: linear-gradient(135deg, #4caf50, #38f9d7);
color: white;
border: none;
font-weight: 700;
font-size: 1.1rem;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
margin-top: auto;
}
.btn-proceed:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(76, 175, 80, 0.3);
}
/* Responsive */
@media (max-width: 992px) {
.courses-content {
grid-template-columns: 1fr;
}
.column-divider {
display: none;
}
.column-card {
margin-bottom: 2rem;
}
}
@media (max-width: 768px) {
.header-content h1 {
font-size: 2rem;
}
.courses-list {
max-height: 300px;
}
}

View File

@ -0,0 +1,77 @@
<div class="courses-page">
<!-- Header Section -->
<div class="courses-header">
<div class="header-content">
<h1>📚 Choose Your Courses</h1>
<p>Select the courses you want to enroll in</p>
</div>
</div>
<!-- Main Content -->
<div class="courses-container">
<div class="container">
<div class="courses-content">
<!-- Available Courses -->
<div class="courses-column">
<div class="column-card">
<div class="column-header available-header">
<h3>🎓 Available Courses</h3>
<span class="course-count">{{ available.length }}</span>
</div>
<div class="courses-list">
<div *ngIf="available.length === 0" class="empty-state">
<p>🎉 All courses selected! Great job!</p>
</div>
<div *ngFor="let c of available" class="course-item-available">
<div class="course-item-content">
<span class="course-icon">📖</span>
<span class="course-name">{{ c }}</span>
</div>
<button (click)="addCourse(c)" class="btn-add">
<span>+</span>
</button>
</div>
</div>
</div>
</div>
<!-- Arrow Divider -->
<div class="column-divider">
<div class="arrow-icon"></div>
</div>
<!-- Selected Courses -->
<div class="courses-column">
<div class="column-card">
<div class="column-header selected-header">
<h3>✅ Selected Courses</h3>
<span class="course-count">{{ selected.length }}</span>
</div>
<div class="courses-list">
<div *ngIf="selected.length === 0" class="empty-state">
<p>👈 Start by selecting courses</p>
</div>
<div *ngFor="let c of selected" class="course-item-selected">
<div class="course-item-content">
<span class="course-icon"></span>
<span class="course-name">{{ c }}</span>
</div>
<button (click)="removeCourse(c)" class="btn-remove">
<span></span>
</button>
</div>
</div>
<button *ngIf="selected.length > 0" (click)="submit()" class="btn-proceed">
💳 Proceed to Payment
</button>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CourseList } from './course-list';
describe('CourseList', () => {
let component: CourseList;
let fixture: ComponentFixture<CourseList>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [CourseList],
}).compileComponents();
fixture = TestBed.createComponent(CourseList);
component = fixture.componentInstance;
await fixture.whenStable();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,46 @@
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-course-list',
standalone: true,
imports: [CommonModule],
templateUrl: './course-list.html',
styleUrls: ['./course-list.css'],
})
export class CourseListComponent {
available = [
'Angular',
'Java',
'Python',
'SQL'
];
selected: string[] = [];
constructor(private router:Router) {}
addCourse(course: string) {
this.selected.push(course);
this.available =
this.available.filter(c => c !== course);
}
removeCourse(course: string) {
this.available.push(course);
this.selected =
this.selected.filter(c => c !== course);
}
submit() {
this.router.navigate(['/payment']);
}
}

View File

@ -0,0 +1,8 @@
.enroll-form {
max-width: 600px;
margin: auto;
padding: 30px;
background: white;
border-radius: 12px;
box-shadow: var(--shadow);
}

View File

@ -0,0 +1,23 @@
<div class="container mt-5">
<h2>Enrollment</h2>
<input class="form-control mb-2"
placeholder="Name">
<input class="form-control mb-2"
placeholder="Email">
<select class="form-control mb-2">
<option>Angular</option>
<option>Java</option>
</select>
<button routerLink="/terms"
class="btn btn-primary">
Submit
</button>
</div>

View File

@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { EnrollmentFormComponent } from './enrollment-form';
describe('EnrollmentFormComponent', () => {
let component: EnrollmentFormComponent;
let fixture: ComponentFixture<EnrollmentFormComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [EnrollmentFormComponent],
}).compileComponents();
fixture = TestBed.createComponent(EnrollmentFormComponent);
component = fixture.componentInstance;
await fixture.whenStable();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,9 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-enrollment-form',
imports: [],
templateUrl: './enrollment-form.html',
styleUrl: './enrollment-form.css',
})
export class EnrollmentFormComponent {}

113
src/app/forgot/forgot.css Normal file
View File

@ -0,0 +1,113 @@
/* ===== FORGOT PASSWORD PAGE ===== */
body {
background: linear-gradient(135deg, #f093fb, #f5576c);
font-family: Poppins, sans-serif;
margin: 0;
padding: 0;
}
.forgot-container {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(135deg, #f093fb, #f5576c);
padding: 20px;
}
.forgot-box {
width: 100%;
max-width: 450px;
background: white;
padding: 40px;
border-radius: 15px;
box-shadow: 0 8px 25px rgba(0,0,0,0.2);
}
.forgot-title {
text-align: center;
margin-bottom: 10px;
color: #0d3b66;
font-size: 28px;
font-weight: 600;
}
.forgot-subtitle {
text-align: center;
color: #666;
font-size: 14px;
margin-bottom: 30px;
line-height: 1.5;
}
.form-group {
margin-bottom: 20px;
}
.form-label {
display: block;
margin-bottom: 8px;
color: #333;
font-weight: 500;
font-size: 14px;
}
.forgot-box input {
width: 100%;
padding: 12px 15px;
border: 2px solid #e0e0e0;
border-radius: 10px;
font-size: 14px;
transition: 0.3s;
}
.forgot-box input:focus {
border-color: #f5576c;
box-shadow: 0 0 8px rgba(245, 87, 108, 0.2);
outline: none;
}
.reset-btn {
width: 100%;
background: #f5576c;
border: none;
padding: 12px;
border-radius: 10px;
color: white;
font-weight: 600;
font-size: 15px;
transition: 0.3s;
margin-top: 10px;
}
.reset-btn:hover {
background: #f093fb;
box-shadow: 0 5px 15px rgba(245, 87, 108, 0.3);
transform: translateY(-2px);
}
.back-to-login {
text-align: center;
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #e0e0e0;
}
.back-to-login p {
color: #666;
font-size: 14px;
margin: 0;
}
.login-link-text {
color: #f5576c;
text-decoration: none;
font-weight: 600;
transition: 0.3s;
}
.login-link-text:hover {
color: #f093fb;
text-decoration: underline;
}

View File

@ -0,0 +1,32 @@
<div class="forgot-container">
<div class="forgot-box">
<h3 class="forgot-title">Reset Password</h3>
<p class="forgot-subtitle">Enter your email to receive password reset instructions</p>
<div class="form-group">
<label for="email" class="form-label">Email Address</label>
<input type="email" class="form-control" id="email" placeholder="Enter your registered email">
</div>
<div class="form-group">
<label for="newPassword" class="form-label">New Password</label>
<input type="password" class="form-control" id="newPassword" placeholder="Enter new password">
</div>
<div class="form-group">
<label for="confirmPassword" class="form-label">Confirm Password</label>
<input type="password" class="form-control" id="confirmPassword" placeholder="Confirm your password">
</div>
<button routerLink="/login" class="btn btn-primary w-100 reset-btn">
Reset Password
</button>
<div class="back-to-login">
<p>Remember your password? <a routerLink="/login" class="login-link-text">Back to Sign In</a></p>
</div>
</div>
</div>

View File

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

12
src/app/forgot/forgot.ts Normal file
View File

@ -0,0 +1,12 @@
import { Component } from '@angular/core';
import { RouterModule } from '@angular/router';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-forgot',
standalone: true,
imports: [RouterModule, FormsModule],
templateUrl: './forgot.html',
styleUrl: './forgot.css',
})
export class ForgotComponent {}

282
src/app/landing/landing.css Normal file
View File

@ -0,0 +1,282 @@
/* ===== LANDING PAGE STYLING ===== */
/* Hero Section */
.hero-section {
position: relative;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
}
.hero-section::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 600"><defs><pattern id="grid" width="60" height="60" patternUnits="userSpaceOnUse"><path d="M 60 0 L 0 0 0 60" fill="none" stroke="rgba(255,255,255,0.05)" stroke-width="1"/></pattern></defs><rect width="1200" height="600" fill="url(%23grid)"/></svg>');
opacity: 0.3;
}
.hero-content {
position: relative;
z-index: 2;
text-align: center;
color: white;
max-width: 900px;
padding: 0 20px;
}
.hero-particles {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 1;
}
.hero-text-wrapper {
position: relative;
z-index: 2;
animation: slideInDown 0.8s ease-out;
}
.hero-title {
font-size: 4.5rem;
font-weight: 800;
margin-bottom: 1rem;
text-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
line-height: 1.2;
}
.hero-subtitle {
font-size: 1.3rem;
margin-bottom: 2.5rem;
opacity: 0.95;
font-weight: 300;
letter-spacing: 0.5px;
}
.hero-buttons {
display: flex;
gap: 1rem;
justify-content: center;
flex-wrap: wrap;
animation: fadeInUp 0.8s ease-out 0.3s both;
}
.btn-hero {
padding: 1rem 2rem;
font-size: 1.1rem;
border-radius: 50px;
border: none;
font-weight: 600;
transition: all 0.3s ease;
cursor: pointer;
letter-spacing: 0.5px;
text-decoration: none;
display: inline-block;
}
.btn-hero-primary {
background: white;
color: #667eea;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
}
.btn-hero-primary:hover {
transform: translateY(-3px);
box-shadow: 0 12px 35px rgba(0, 0, 0, 0.3);
}
.btn-hero-secondary {
background: rgba(255, 255, 255, 0.2);
color: white;
border: 2px solid white;
}
.btn-hero-secondary:hover {
background: white;
color: #667eea;
transform: translateY(-3px);
}
/* Features Section */
.features-section {
padding: 5rem 0;
background: linear-gradient(180deg, #f8f9fa 0%, #ffffff 100%);
}
.section-title {
text-align: center;
font-size: 2.8rem;
font-weight: 800;
margin-bottom: 4rem;
color: #1f2937;
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 2rem;
}
.feature-card {
background: white;
padding: 2.5rem;
border-radius: 16px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
transition: all 0.4s ease;
text-align: center;
border: 1px solid rgba(0, 0, 0, 0.05);
}
.feature-card:hover {
transform: translateY(-10px);
box-shadow: 0 12px 35px rgba(0, 0, 0, 0.15);
}
.feature-icon-gradient {
width: 80px;
height: 80px;
margin: 0 auto 1.5rem;
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
font-size: 2.5rem;
}
.gradient-1 {
background: linear-gradient(135deg, #667eea, #764ba2);
}
.gradient-2 {
background: linear-gradient(135deg, #f093fb, #f5576c);
}
.gradient-3 {
background: linear-gradient(135deg, #4facfe, #00f2fe);
}
.gradient-4 {
background: linear-gradient(135deg, #43e97b, #38f9d7);
}
.feature-card h3 {
font-size: 1.5rem;
font-weight: 700;
margin-bottom: 1rem;
color: #1f2937;
}
.feature-card p {
color: #6b7280;
line-height: 1.6;
font-size: 1rem;
}
/* CTA Section */
.cta-section {
padding: 4rem 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.cta-content {
text-align: center;
}
.cta-section h2 {
font-size: 2.5rem;
font-weight: 800;
margin-bottom: 1rem;
}
.cta-section p {
font-size: 1.2rem;
margin-bottom: 2.5rem;
opacity: 0.95;
}
.cta-buttons {
display: flex;
gap: 1rem;
justify-content: center;
flex-wrap: wrap;
}
.btn-cta {
padding: 0.9rem 1.8rem;
border-radius: 10px;
border: none;
font-weight: 600;
transition: all 0.3s ease;
cursor: pointer;
font-size: 1rem;
text-decoration: none;
display: inline-block;
}
.btn-cta-login,
.btn-cta-signup,
.btn-cta-forgot {
background: white;
color: #667eea;
}
.btn-cta-login:hover,
.btn-cta-signup:hover,
.btn-cta-forgot:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
}
/* Animations */
@keyframes slideInDown {
from {
opacity: 0;
transform: translateY(-50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Responsive */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem;
}
.hero-subtitle {
font-size: 1.1rem;
}
.section-title {
font-size: 2rem;
}
.cta-section h2 {
font-size: 1.8rem;
}
}

View File

@ -0,0 +1,84 @@
<!-- Hero Section -->
<section class="hero-section">
<div class="hero-content">
<div class="hero-particles"></div>
<div class="hero-text-wrapper">
<h1 class="hero-title">Welcome to NextGen Learning Hub</h1>
<p class="hero-subtitle">Transform Your Future with World-Class Online Learning</p>
<div class="hero-buttons">
<button routerLink="/signup" class="btn btn-hero btn-hero-primary">
🚀 Get Started
</button>
<button routerLink="/courses" class="btn btn-hero btn-hero-secondary">
📚 Explore Courses
</button>
</div>
</div>
</div>
</section>
<!-- Features Section -->
<section class="features-section">
<div class="container">
<h2 class="section-title">Why Choose Us?</h2>
<div class="features-grid">
<!-- Feature 1 -->
<div class="feature-card">
<div class="feature-icon-gradient gradient-1">
<span class="feature-icon">👨‍🏫</span>
</div>
<h3>Expert Instructors</h3>
<p>Learn from industry professionals with years of experience</p>
</div>
<!-- Feature 2 -->
<div class="feature-card">
<div class="feature-icon-gradient gradient-2">
<span class="feature-icon">⏱️</span>
</div>
<h3>Learn at Your Pace</h3>
<p>Study whenever, wherever suits your schedule best</p>
</div>
<!-- Feature 3 -->
<div class="feature-card">
<div class="feature-icon-gradient gradient-3">
<span class="feature-icon">🏆</span>
</div>
<h3>Recognized Certificates</h3>
<p>Earn industry-recognized certifications upon completion</p>
</div>
<!-- Feature 4 -->
<div class="feature-card">
<div class="feature-icon-gradient gradient-4">
<span class="feature-icon">💼</span>
</div>
<h3>Career Support</h3>
<p>Get job-ready with our comprehensive career guidance</p>
</div>
</div>
</div>
</section>
<!-- CTA Section -->
<section class="cta-section">
<div class="container">
<div class="cta-content">
<h2>Ready to Start Learning?</h2>
<p>Join thousands of students already transforming their careers</p>
<div class="cta-buttons">
<button routerLink="/login" class="btn btn-cta btn-cta-login">
🔐 Sign In
</button>
<button routerLink="/signup" class="btn btn-cta btn-cta-signup">
✨ Create Account
</button>
<button routerLink="/forgot" class="btn btn-cta btn-cta-forgot">
🔑 Forgot Password
</button>
</div>
</div>
</div>
</section>

View File

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

View File

@ -0,0 +1,9 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-landing',
imports: [],
templateUrl: './landing.html',
styleUrl: './landing.css',
})
export class LandingComponent {}

327
src/app/login/login.css Normal file
View File

@ -0,0 +1,327 @@
/* ===== LOGIN PAGE STYLING ===== */
.login-container {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
padding: 20px;
position: relative;
overflow: hidden;
}
.login-container::before {
content: '';
position: absolute;
top: -50%;
right: -10%;
width: 600px;
height: 600px;
background: rgba(255, 255, 255, 0.1);
border-radius: 50%;
animation: float 6s ease-in-out infinite;
}
.login-container::after {
content: '';
position: absolute;
bottom: -50%;
left: -10%;
width: 600px;
height: 600px;
background: rgba(255, 255, 255, 0.1);
border-radius: 50%;
animation: float 8s ease-in-out infinite reverse;
}
@keyframes float {
0%,
100% {
transform: translateY(0px);
}
50% {
transform: translateY(30px);
}
}
.login-card-wrapper {
position: relative;
z-index: 2;
width: 100%;
max-width: 450px;
}
.login-card {
background: white;
border-radius: 20px;
padding: 3rem;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
backdrop-filter: blur(10px);
animation: slideUp 0.6s ease-out;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Header */
.login-header {
text-align: center;
margin-bottom: 2rem;
}
.login-icon {
font-size: 3rem;
display: block;
margin-bottom: 1rem;
animation: bounce 2s infinite;
}
@keyframes bounce {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
.login-title {
font-size: 1.8rem;
font-weight: 700;
color: #1f2937;
margin-bottom: 0.5rem;
}
.login-subtitle {
color: #6b7280;
font-size: 1rem;
margin: 0;
}
/* Form */
.login-form {
margin-bottom: 1.5rem;
}
.form-group-custom {
margin-bottom: 1.5rem;
}
.form-label {
display: block;
font-weight: 600;
color: #1f2937;
margin-bottom: 0.5rem;
font-size: 0.95rem;
}
.input-wrapper {
position: relative;
display: flex;
align-items: center;
}
.form-input {
width: 100%;
padding: 0.9rem 2.5rem 0.9rem 1rem;
border: 2px solid #e5e7eb;
border-radius: 12px;
font-size: 1rem;
transition: all 0.3s ease;
font-family: inherit;
}
.form-input::placeholder {
color: #9ca3af;
}
.form-input:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
background: rgba(102, 126, 234, 0.02);
}
.input-icon {
position: absolute;
right: 1rem;
font-size: 1.2rem;
pointer-events: none;
}
/* Checkbox */
.form-checkbox {
display: flex;
align-items: center;
margin-bottom: 1.5rem;
}
.checkbox-input {
width: 18px;
height: 18px;
cursor: pointer;
accent-color: #667eea;
}
.checkbox-label {
margin-left: 0.5rem;
color: #6b7280;
font-size: 0.95rem;
cursor: pointer;
}
/* Login Button */
.btn-login-submit {
width: 100%;
padding: 1rem;
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
border: none;
border-radius: 12px;
font-size: 1.1rem;
font-weight: 700;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2);
}
.btn-login-submit:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
}
.btn-login-submit:active {
transform: translateY(0);
}
/* Forgot Password */
.forgot-section {
text-align: center;
margin-bottom: 1.5rem;
}
.forgot-link {
color: #667eea;
text-decoration: none;
font-weight: 600;
transition: all 0.3s ease;
font-size: 0.95rem;
}
.forgot-link:hover {
color: #764ba2;
text-decoration: underline;
}
/* Divider */
.divider-section {
text-align: center;
margin-bottom: 1.5rem;
color: #9ca3af;
font-size: 0.9rem;
}
/* Signup Link */
.signup-section-login {
text-align: center;
}
.btn-signup-link {
display: inline-block;
width: 100%;
padding: 0.9rem;
background: rgba(102, 126, 234, 0.1);
color: #667eea;
border: 2px solid #667eea;
border-radius: 12px;
font-size: 1rem;
font-weight: 700;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
}
.btn-signup-link:hover {
background: #667eea;
color: white;
transform: translateY(-2px);
}
/* Decorative Elements */
.decorative-circle {
position: absolute;
border-radius: 50%;
opacity: 0.1;
z-index: 1;
}
.circle-1 {
width: 300px;
height: 300px;
background: white;
top: -100px;
right: -100px;
}
.circle-2 {
width: 200px;
height: 200px;
background: white;
bottom: -50px;
left: -50px;
}
/* Responsive */
@media (max-width: 768px) {
.login-card {
padding: 2rem;
}
.login-title {
font-size: 1.5rem;
}
}
.signup-section {
margin-top: 20px;
padding-top: 10px;
}
.signup-text {
text-align: center;
color: #333;
font-size: 14px;
margin-bottom: 12px;
font-weight: 500;
}
.register-btn {
background: #28a745;
border: none;
border-radius: 10px;
padding: 12px;
color: white;
font-weight: 600;
transition: 0.3s;
}
.register-btn:hover {
background: #218838;
box-shadow: 0 5px 15px rgba(33, 136, 56, 0.3);
transform: translateY(-2px);
}

65
src/app/login/login.html Normal file
View File

@ -0,0 +1,65 @@
<div class="login-container">
<div class="login-card-wrapper">
<div class="login-card">
<!-- Header -->
<div class="login-header">
<div class="login-icon">🔐</div>
<h2 class="login-title">Welcome Back</h2>
<p class="login-subtitle">Sign in to your account</p>
</div>
<!-- Form -->
<form class="login-form">
<!-- Username -->
<div class="form-group-custom">
<label for="username" class="form-label">📧 Username / Email</label>
<div class="input-wrapper">
<input type="text" id="username" class="form-input" placeholder="Enter your username or email" required>
<span class="input-icon">👤</span>
</div>
</div>
<!-- Password -->
<div class="form-group-custom">
<label for="password" class="form-label">🔑 Password</label>
<div class="input-wrapper">
<input type="password" id="password" class="form-input" placeholder="Enter your password" required>
<span class="input-icon">🔒</span>
</div>
</div>
<!-- Remember Me -->
<div class="form-checkbox">
<input type="checkbox" id="remember" class="checkbox-input">
<label for="remember" class="checkbox-label">Remember me</label>
</div>
<!-- Login Button -->
<button routerLink="/courses" type="button" class="btn-login-submit">
🚀 Sign In
</button>
</form>
<!-- Forgot Password Link -->
<div class="forgot-section">
<a routerLink="/forgot" class="forgot-link">Forgot your password?</a>
</div>
<!-- Divider -->
<div class="divider-section">
<span>New here?</span>
</div>
<!-- Signup Link -->
<div class="signup-section-login">
<button routerLink="/signup" type="button" class="btn-signup-link">
✨ Create Account
</button>
</div>
</div>
<!-- Decorative Background Elements -->
<div class="decorative-circle circle-1"></div>
<div class="decorative-circle circle-2"></div>
</div>
</div>

View File

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

12
src/app/login/login.ts Normal file
View File

@ -0,0 +1,12 @@
import { Component } from '@angular/core';
import { RouterModule } from '@angular/router';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-login',
standalone: true,
imports: [RouterModule, FormsModule],
templateUrl: './login.html',
styleUrl: './login.css',
})
export class LoginComponent {}

View File

@ -0,0 +1,460 @@
/* ===== PAYMENT SUCCESS PAGE - FUTURISTIC CELEBRATION THEME ===== */
:root {
--success-gradient: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
--dark-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.success-page {
min-height: 100vh;
background: var(--dark-gradient);
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
}
/* Background Elements */
.stars {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
pointer-events: none;
}
.stars::before,
.stars::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background-image:
radial-gradient(2px 2px at 20px 30px, #eee, rgba(0, 0, 0, 0)),
radial-gradient(2px 2px at 60px 70px, #fff, rgba(0, 0, 0, 0)),
radial-gradient(1px 1px at 50px 50px, #fff, rgba(0, 0, 0, 0)),
radial-gradient(1px 1px at 130px 80px, #fff, rgba(0, 0, 0, 0)),
radial-gradient(2px 2px at 90px 10px, #fff, rgba(0, 0, 0, 0));
background-size: 200px 200px;
animation: twinkle 5s infinite;
}
@keyframes twinkle {
0%,
100% {
opacity: 0.3;
}
50% {
opacity: 1;
}
}
/* Animated Blobs */
.blob {
position: absolute;
border-radius: 50%;
filter: blur(40px);
opacity: 0.15;
animation: float 8s ease-in-out infinite;
}
.success-blob-1 {
width: 400px;
height: 400px;
background: #43e97b;
top: -100px;
left: -100px;
}
.success-blob-2 {
width: 300px;
height: 300px;
background: #38f9d7;
bottom: -50px;
right: -50px;
animation-delay: 3s;
}
.success-blob-3 {
width: 350px;
height: 350px;
background: white;
top: 40%;
left: 50%;
animation-delay: 6s;
}
@keyframes float {
0%,
100% {
transform: translateY(0px) translateX(0px);
}
33% {
transform: translateY(30px) translateX(10px);
}
66% {
transform: translateY(-20px) translateX(-10px);
}
}
/* Container */
.success-container {
position: relative;
z-index: 2;
width: 100%;
max-width: 700px;
}
/* Success Content */
.success-content {
background: rgba(255, 255, 255, 0.08);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 24px;
padding: 3rem;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
animation: slideUp 0.8s ease-out;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Checkmark Animation */
.success-checkmark-wrapper {
display: flex;
justify-content: center;
margin-bottom: 2rem;
}
.success-checkmark {
width: 120px;
height: 120px;
border-radius: 50%;
background: linear-gradient(135deg, #43e97b, #38f9d7);
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 0 50px rgba(67, 233, 123, 0.6),
0 0 100px rgba(56, 249, 215, 0.3);
position: relative;
animation: pulse-glow 2s ease-in-out infinite;
}
@keyframes pulse-glow {
0%,
100% {
box-shadow: 0 0 50px rgba(67, 233, 123, 0.6),
0 0 100px rgba(56, 249, 215, 0.3);
}
50% {
box-shadow: 0 0 70px rgba(67, 233, 123, 0.8),
0 0 150px rgba(56, 249, 215, 0.5);
}
}
.check-icon {
font-size: 4rem;
color: white;
font-weight: bold;
animation: checkbounce 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
@keyframes checkbounce {
0% {
opacity: 0;
transform: scale(0) rotate(-45deg);
}
100% {
opacity: 1;
transform: scale(1) rotate(0deg);
}
}
/* Success Message */
.success-message {
text-align: center;
margin-bottom: 2rem;
color: white;
}
.success-title {
font-size: 2.5rem;
font-weight: 800;
margin-bottom: 0.5rem;
background: linear-gradient(135deg, #43e97b, #38f9d7);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-shadow: 0 0 30px rgba(67, 233, 123, 0.3);
}
.success-subtitle {
font-size: 1.2rem;
opacity: 0.95;
letter-spacing: 0.5px;
}
/* Details Card */
.success-details-card {
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(67, 233, 123, 0.3);
border-radius: 16px;
padding: 1.5rem;
margin-bottom: 1.5rem;
backdrop-filter: blur(10px);
}
.detail-item {
display: flex;
align-items: center;
gap: 1rem;
padding: 0.8rem 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
color: white;
font-size: 0.95rem;
}
.detail-item:last-child {
border-bottom: none;
}
.detail-icon {
font-size: 1.3rem;
min-width: 30px;
}
.detail-label {
flex: 1;
opacity: 0.8;
}
.detail-value {
font-weight: 700;
color: #43e97b;
text-shadow: 0 0 10px rgba(67, 233, 123, 0.5);
}
/* Enrolled Courses Card */
.enrolled-courses-card {
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(67, 233, 123, 0.3);
border-radius: 16px;
padding: 1.5rem;
margin-bottom: 1.5rem;
backdrop-filter: blur(10px);
}
.courses-title {
color: white;
font-size: 1.2rem;
font-weight: 700;
margin-bottom: 1rem;
text-shadow: 0 0 15px rgba(67, 233, 123, 0.3);
}
.enrolled-course {
display: flex;
align-items: center;
gap: 0.8rem;
padding: 0.8rem;
border-radius: 10px;
background: rgba(255, 255, 255, 0.05);
margin-bottom: 0.8rem;
color: white;
transition: all 0.3s ease;
}
.enrolled-course:last-child {
margin-bottom: 0;
}
.enrolled-course:hover {
background: rgba(67, 233, 123, 0.15);
transform: translateX(5px);
}
.course-badge {
width: 40px;
height: 40px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.3rem;
font-weight: bold;
color: white;
}
.course-badge.angular-badge {
background: linear-gradient(135deg, #667eea, #764ba2);
box-shadow: 0 0 15px rgba(102, 126, 234, 0.4);
}
.course-badge.java-badge {
background: linear-gradient(135deg, #f093fb, #f5576c);
box-shadow: 0 0 15px rgba(240, 147, 251, 0.4);
}
.course-badge.python-badge {
background: linear-gradient(135deg, #4facfe, #00f2fe);
box-shadow: 0 0 15px rgba(79, 172, 254, 0.4);
}
.course-name {
font-weight: 600;
}
/* Next Steps Card */
.next-steps-card {
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(67, 233, 123, 0.3);
border-radius: 16px;
padding: 1.5rem;
margin-bottom: 2rem;
backdrop-filter: blur(10px);
}
.steps-title {
color: white;
font-size: 1.2rem;
font-weight: 700;
margin-bottom: 1rem;
text-shadow: 0 0 15px rgba(67, 233, 123, 0.3);
}
.steps-list {
list-style: none;
padding: 0;
}
.steps-list li {
color: white;
padding: 0.7rem 0;
padding-left: 2rem;
position: relative;
opacity: 0.9;
font-size: 0.95rem;
}
.steps-list li::before {
content: '✓';
position: absolute;
left: 0;
color: #43e97b;
font-weight: bold;
text-shadow: 0 0 10px rgba(67, 233, 123, 0.5);
}
/* Action Buttons */
.success-actions {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.btn-action {
padding: 1rem;
border-radius: 12px;
border: none;
font-weight: 700;
font-size: 0.95rem;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
}
.btn-home {
background: linear-gradient(135deg, #43e97b, #38f9d7);
color: white;
box-shadow: 0 0 20px rgba(67, 233, 123, 0.4);
}
.btn-home:hover {
transform: translateY(-3px);
box-shadow: 0 0 40px rgba(67, 233, 123, 0.6);
}
.btn-courses {
background: rgba(255, 255, 255, 0.1);
color: white;
border: 1px solid rgba(255, 255, 255, 0.3);
}
.btn-courses:hover {
background: rgba(255, 255, 255, 0.15);
transform: translateY(-3px);
box-shadow: 0 0 20px rgba(67, 233, 123, 0.3);
}
/* Celebration Particles */
@keyframes float-particle {
0% {
opacity: 1;
transform: translateY(0px) translateX(0px);
}
100% {
opacity: 0;
transform: translateY(-100px) translateX(30px);
}
}
/* Responsive */
@media (max-width: 768px) {
.success-content {
padding: 2rem;
}
.success-title {
font-size: 1.8rem;
}
.success-checkmark {
width: 100px;
height: 100px;
}
.check-icon {
font-size: 3rem;
}
.success-actions {
grid-template-columns: 1fr;
}
.detail-item,
.enrolled-course {
flex-wrap: wrap;
padding: 0.6rem;
}
}

View File

@ -0,0 +1,93 @@
<div class="success-page">
<!-- Animated Background Elements -->
<div class="stars"></div>
<div class="particles"></div>
<div class="success-container">
<!-- Animated Background Blobs -->
<div class="blob success-blob-1"></div>
<div class="blob success-blob-2"></div>
<div class="blob success-blob-3"></div>
<!-- Success Card -->
<div class="success-content">
<!-- Checkmark Animation -->
<div class="success-checkmark-wrapper">
<div class="success-checkmark">
<div class="check-icon"></div>
</div>
</div>
<!-- Success Message -->
<div class="success-message">
<h1 class="success-title">Payment Successful!</h1>
<p class="success-subtitle">🎉 Your enrollment has been confirmed</p>
</div>
<!-- Success Details Card -->
<div class="success-details-card">
<div class="detail-item">
<span class="detail-icon">📋</span>
<span class="detail-label">Enrollment ID:</span>
<span class="detail-value">#ENR-2024-001</span>
</div>
<div class="detail-item">
<span class="detail-icon">💰</span>
<span class="detail-label">Amount Paid:</span>
<span class="detail-value">₹ 7,497</span>
</div>
<div class="detail-item">
<span class="detail-icon">📅</span>
<span class="detail-label">Date & Time:</span>
<span class="detail-value">18 Mar 2026, 2:30 PM</span>
</div>
<div class="detail-item">
<span class="detail-icon">✉️</span>
<span class="detail-label">Confirmation Email:</span>
<span class="detail-value">Sent to your inbox</span>
</div>
</div>
<!-- Course Enrollment Info -->
<div class="enrolled-courses-card">
<h3 class="courses-title">📚 Your Enrolled Courses</h3>
<div class="enrolled-course">
<span class="course-badge angular-badge"></span>
<span class="course-name">Angular - Advanced Concepts</span>
</div>
<div class="enrolled-course">
<span class="course-badge java-badge"></span>
<span class="course-name">Java - Full Stack Development</span>
</div>
<div class="enrolled-course">
<span class="course-badge python-badge">🐍</span>
<span class="course-name">Python - Data Science</span>
</div>
</div>
<!-- Next Steps -->
<div class="next-steps-card">
<h3 class="steps-title">📖 Next Steps</h3>
<ol class="steps-list">
<li>Check your email for course access details</li>
<li>Download the course materials</li>
<li>Join the student community</li>
<li>Start learning at your own pace!</li>
</ol>
</div>
<!-- Action Buttons -->
<div class="success-actions">
<button routerLink="/" class="btn-action btn-home">
🏠 Go to Home
</button>
<button routerLink="/courses" class="btn-action btn-courses">
📚 View My Courses
</button>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PaymentSuccess } from './payment-success';
describe('PaymentSuccess', () => {
let component: PaymentSuccess;
let fixture: ComponentFixture<PaymentSuccess>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [PaymentSuccess],
}).compileComponents();
fixture = TestBed.createComponent(PaymentSuccess);
component = fixture.componentInstance;
await fixture.whenStable();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,9 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-payment-success',
imports: [],
templateUrl: './payment-success.html',
styleUrl: './payment-success.css',
})
export class PaymentSuccessComponent {}

618
src/app/payment/payment.css Normal file
View File

@ -0,0 +1,618 @@
/* ===== PAYMENT PAGE - FUTURISTIC HIGH-TECH THEME ===== */
:root {
--primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
--glass-bg: rgba(255, 255, 255, 0.1);
--glass-border: rgba(255, 255, 255, 0.2);
--glow-primary: #667eea;
--glow-secondary: #f093fb;
}
.payment-page {
min-height: 100vh;
background: var(--primary-gradient);
position: relative;
overflow: hidden;
padding: 2rem 0;
}
/* Animated Background Blobs */
.blob {
position: absolute;
border-radius: 50%;
opacity: 0.1;
filter: blur(40px);
animation: float 8s ease-in-out infinite;
}
.blob-1 {
width: 400px;
height: 400px;
background: white;
top: -100px;
left: -100px;
}
.blob-2 {
width: 300px;
height: 300px;
background: white;
top: 50%;
right: -50px;
animation-delay: 3s;
}
.blob-3 {
width: 350px;
height: 350px;
background: white;
bottom: -50px;
left: 20%;
animation-delay: 6s;
}
@keyframes float {
0%,
100% {
transform: translateY(0px) translateX(0px);
}
33% {
transform: translateY(30px) translateX(10px);
}
66% {
transform: translateY(-20px) translateX(-10px);
}
}
/* Container */
.payment-container {
position: relative;
z-index: 2;
max-width: 1400px;
margin: 0 auto;
padding: 2rem;
}
/* Header */
.payment-header {
text-align: center;
color: white;
margin-bottom: 3rem;
animation: slideDown 0.8s ease-out;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.header-content h1 {
font-size: 3rem;
font-weight: 800;
margin-bottom: 0.5rem;
text-shadow: 0 0 30px rgba(255, 255, 255, 0.3);
}
.header-content p {
font-size: 1.1rem;
opacity: 0.95;
letter-spacing: 1px;
}
/* Main Content Layout */
.payment-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
align-items: start;
}
/* Glassmorphism Card */
.glassmorphism-card {
background: var(--glass-bg);
backdrop-filter: blur(20px);
border: 1px solid var(--glass-border);
border-radius: 24px;
padding: 2rem;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
animation: slideUp 0.8s ease-out;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.glassmorphism-card:hover {
border-color: rgba(255, 255, 255, 0.4);
box-shadow: 0 12px 48px rgba(102, 126, 234, 0.2);
}
/* Card Header */
.card-header {
margin-bottom: 1.5rem;
padding-bottom: 1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.card-header h3 {
color: white;
font-size: 1.5rem;
font-weight: 700;
margin: 0;
text-shadow: 0 0 20px rgba(102, 126, 234, 0.5);
}
.glow-line {
height: 2px;
background: linear-gradient(90deg, transparent, #667eea, transparent);
margin-top: 0.5rem;
animation: glow 3s ease-in-out infinite;
}
@keyframes glow {
0%,
100% {
opacity: 0.3;
}
50% {
opacity: 1;
}
}
/* ===== COURSE SUMMARY ===== */
.course-items {
display: flex;
flex-direction: column;
gap: 1rem;
margin-bottom: 1.5rem;
}
.course-item {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
border-radius: 12px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(102, 126, 234, 0.3);
transition: all 0.3s ease;
}
.course-item:hover {
background: rgba(102, 126, 234, 0.15);
transform: translateX(5px);
box-shadow: 0 0 20px rgba(102, 126, 234, 0.3);
}
.course-icon {
width: 50px;
height: 50px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.8rem;
font-weight: bold;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.course-icon.angular {
background: linear-gradient(135deg, #667eea, #764ba2);
box-shadow: 0 0 15px rgba(102, 126, 234, 0.6);
}
.course-icon.java {
background: linear-gradient(135deg, #f093fb, #f5576c);
box-shadow: 0 0 15px rgba(240, 147, 251, 0.6);
}
.course-icon.python {
background: linear-gradient(135deg, #4facfe, #00f2fe);
box-shadow: 0 0 15px rgba(79, 172, 254, 0.6);
}
.course-icon.sql {
background: linear-gradient(135deg, #43e97b, #38f9d7);
box-shadow: 0 0 15px rgba(67, 233, 123, 0.6);
}
.course-info {
flex: 1;
color: white;
}
.course-info h4 {
margin: 0 0 0.3rem 0;
font-weight: 700;
font-size: 1rem;
}
.course-price {
margin: 0;
font-size: 0.9rem;
opacity: 0.8;
}
.price-tag {
color: #667eea;
font-weight: 700;
font-size: 1.1rem;
text-shadow: 0 0 10px rgba(102, 126, 234, 0.5);
}
.summary-divider {
height: 1px;
background: linear-gradient(90deg, transparent, rgba(102, 126, 234, 0.5), transparent);
margin: 1.5rem 0;
}
.summary-total {
display: flex;
justify-content: space-between;
align-items: center;
color: white;
font-size: 1.2rem;
font-weight: 700;
}
.total-amount {
background: linear-gradient(135deg, #667eea, #f093fb);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-shadow: 0 0 20px rgba(102, 126, 234, 0.5);
font-size: 1.5rem;
}
/* ===== PAYMENT METHODS ===== */
.payment-methods {
display: flex;
flex-direction: column;
gap: 1rem;
margin-bottom: 2rem;
}
.payment-method-item {
position: relative;
}
.radio-input {
position: absolute;
opacity: 0;
cursor: pointer;
}
.payment-method-label {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem;
border-radius: 12px;
background: rgba(255, 255, 255, 0.05);
border: 2px solid rgba(102, 126, 234, 0.3);
cursor: pointer;
transition: all 0.3s ease;
}
.radio-input:checked+.payment-method-label {
background: rgba(102, 126, 234, 0.2);
border-color: #667eea;
box-shadow: 0 0 20px rgba(102, 126, 234, 0.4);
}
.payment-method-label:hover {
border-color: rgba(102, 126, 234, 0.6);
background: rgba(102, 126, 234, 0.1);
}
.method-icon {
width: 50px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
border-radius: 12px;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(102, 126, 234, 0.5);
}
.radio-input:checked+.payment-method-label .method-icon {
background: linear-gradient(135deg, #667eea, #764ba2);
box-shadow: 0 0 20px rgba(102, 126, 234, 0.6);
border-color: #667eea;
}
.method-content {
flex: 1;
}
.method-content h4 {
margin: 0 0 0.2rem 0;
color: white;
font-size: 1rem;
font-weight: 700;
}
.method-content p {
margin: 0;
font-size: 0.85rem;
opacity: 0.7;
color: rgba(255, 255, 255, 0.8);
}
.radio-circle {
width: 24px;
height: 24px;
border: 2px solid rgba(102, 126, 234, 0.5);
border-radius: 50%;
transition: all 0.3s ease;
}
.radio-input:checked+.payment-method-label .radio-circle {
background: linear-gradient(135deg, #667eea, #764ba2);
border-color: #667eea;
box-shadow: 0 0 10px rgba(102, 126, 234, 0.8);
}
.method-details {
display: flex;
flex-direction: column;
gap: 0.8rem;
padding: 1rem;
background: rgba(102, 126, 234, 0.1);
border-radius: 12px;
border: 1px solid rgba(102, 126, 234, 0.3);
margin-top: 0.5rem;
}
.payment-input {
padding: 0.8rem;
background: rgba(255, 255, 255, 0.08);
border: 1px solid rgba(102, 126, 234, 0.4);
border-radius: 8px;
color: white;
font-size: 0.95rem;
transition: all 0.3s ease;
}
.payment-input::placeholder {
color: rgba(255, 255, 255, 0.5);
}
.payment-input:focus {
outline: none;
background: rgba(255, 255, 255, 0.12);
border-color: #667eea;
box-shadow: 0 0 15px rgba(102, 126, 234, 0.3);
}
.input-row {
display: flex;
gap: 1rem;
}
.bank-details-box {
padding: 1rem;
background: rgba(102, 126, 234, 0.15);
border-radius: 8px;
border: 1px solid rgba(102, 126, 234, 0.3);
}
.bank-details-box p {
margin: 0.5rem 0;
color: white;
font-size: 0.95rem;
}
/* ===== ACTION BUTTONS ===== */
.payment-actions {
display: flex;
flex-direction: column;
gap: 1rem;
}
.btn-payment {
padding: 1rem;
border-radius: 12px;
border: none;
font-weight: 700;
font-size: 1rem;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: block;
text-align: center;
}
.btn-complete {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
box-shadow: 0 0 20px rgba(102, 126, 234, 0.4);
}
.btn-complete:hover {
transform: translateY(-3px);
box-shadow: 0 0 40px rgba(102, 126, 234, 0.6);
}
.btn-back {
background: rgba(255, 255, 255, 0.1);
color: white;
border: 1px solid rgba(255, 255, 255, 0.3);
}
.btn-back:hover {
background: rgba(255, 255, 255, 0.15);
border-color: rgba(255, 255, 255, 0.5);
transform: translateY(-2px);
}
/* ===== RESPONSIVE ===== */
@media (max-width: 1024px) {
.payment-content {
grid-template-columns: 1fr;
}
.header-content h1 {
font-size: 2rem;
}
}
@media (max-width: 768px) {
.payment-container {
padding: 1rem;
}
.glassmorphism-card {
padding: 1.5rem;
}
.course-item,
.payment-method-label {
padding: 0.8rem;
}
.header-content h1 {
font-size: 1.5rem;
}
}
font-size: 20px;
color: #1c6dd0;
}
.method-details {
margin-top: 15px;
padding: 15px;
background: #f9f9f9;
border-radius: 10px;
}
.card-input {
margin-bottom: 12px;
}
.payment-box .form-control {
border: 2px solid #e0e0e0;
border-radius: 8px;
padding: 10px 15px;
font-size: 14px;
transition: 0.3s;
}
.payment-box .form-control:focus {
border-color: #1c6dd0;
box-shadow: 0 0 8px rgba(28, 109, 208, 0.1);
outline: none;
}
.bank-info {
background: white;
padding: 15px;
border-radius: 8px;
margin-bottom: 15px;
border-left: 4px solid #6c757d;
}
.bank-info p {
margin: 8px 0;
font-size: 13px;
color: #333;
}
.bank-info strong {
color: #0d3b66;
}
hr {
margin: 25px 0;
border: none;
border-top: 2px solid #e0e0e0;
}
.order-summary {
background: #f5f8ff;
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
}
.order-summary h5 {
margin-top: 0;
margin-bottom: 15px;
color: #0d3b66;
font-weight: 600;
}
.summary-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid #e0e0e0;
font-size: 14px;
}
.summary-item:last-child {
border-bottom: none;
}
.summary-item strong {
color: #1c6dd0;
font-size: 16px;
}
.btn-payment {
background: #28a745;
border: none;
padding: 12px;
font-weight: 600;
border-radius: 10px;
transition: 0.3s;
font-size: 15px;
}
.btn-payment:hover {
background: #218838;
box-shadow: 0 5px 15px rgba(33, 136, 56, 0.3);
transform: translateY(-2px);
}
.btn-outline-secondary {
border: 2px solid #6c757d;
border-radius: 10px;
padding: 10px;
transition: 0.3s;
}
.btn-outline-secondary:hover {
background: #6c757d;
color: white;
}

View File

@ -0,0 +1,171 @@
<div class="payment-page">
<!-- Animated Background Blobs -->
<div class="blob blob-1"></div>
<div class="blob blob-2"></div>
<div class="blob blob-3"></div>
<div class="payment-container">
<!-- Header -->
<div class="payment-header">
<div class="header-content">
<h1>💳 Secure Payment</h1>
<p>Complete your enrollment with our secure payment methods</p>
</div>
</div>
<!-- Main Payment Area -->
<div class="payment-content">
<!-- Left Column: Course Summary -->
<div class="course-summary-column">
<div class="glassmorphism-card summary-card">
<div class="card-header">
<h3>📚 Course Summary</h3>
<div class="glow-line"></div>
</div>
<!-- Course Items -->
<div class="course-items">
<div class="course-item">
<div class="course-icon angular">
<span></span>
</div>
<div class="course-info">
<h4>Angular</h4>
<p class="course-price">₹ 2,999</p>
</div>
<div class="price-tag">₹2,999</div>
</div>
<div class="course-item">
<div class="course-icon java">
<span></span>
</div>
<div class="course-info">
<h4>Java</h4>
<p class="course-price">₹ 2,499</p>
</div>
<div class="price-tag">₹2,499</div>
</div>
<div class="course-item">
<div class="course-icon python">
<span>🐍</span>
</div>
<div class="course-info">
<h4>Python</h4>
<p class="course-price">₹ 1,999</p>
</div>
<div class="price-tag">₹1,999</div>
</div>
</div>
<!-- Summary Footer -->
<div class="summary-divider"></div>
<div class="summary-total">
<span>Total Amount:</span>
<span class="total-amount">₹ 7,497</span>
</div>
</div>
</div>
<!-- Right Column: Payment Methods -->
<div class="payment-methods-column">
<div class="glassmorphism-card payment-card">
<div class="card-header">
<h3>Select Payment Method</h3>
<div class="glow-line"></div>
</div>
<!-- Payment Methods -->
<div class="payment-methods">
<!-- UPI Payment -->
<div class="payment-method-item">
<input type="radio" id="upi" name="paymentMethod" value="upi" class="radio-input">
<label for="upi" class="payment-method-label">
<div class="method-icon upi-icon">📱</div>
<div class="method-content">
<h4>UPI Payment</h4>
<p>Instant transfer via UPI</p>
</div>
<div class="radio-circle"></div>
</label>
<div class="method-details" id="upiDetails" style="display: none;">
<input type="text" class="payment-input" placeholder="Enter UPI ID">
</div>
</div>
<!-- Debit Card -->
<div class="payment-method-item">
<input type="radio" id="debit" name="paymentMethod" value="debit" class="radio-input">
<label for="debit" class="payment-method-label">
<div class="method-icon debit-icon">💳</div>
<div class="method-content">
<h4>Debit Card</h4>
<p>Direct debit from your account</p>
</div>
<div class="radio-circle"></div>
</label>
<div class="method-details" id="debitDetails" style="display: none;">
<input type="text" class="payment-input" placeholder="Card Number" maxlength="16">
<div class="input-row">
<input type="text" class="payment-input" placeholder="MM/YY" style="flex: 1;">
<input type="text" class="payment-input" placeholder="CVV" maxlength="3" style="flex: 1;">
</div>
</div>
</div>
<!-- Credit Card -->
<div class="payment-method-item">
<input type="radio" id="credit" name="paymentMethod" value="credit" class="radio-input">
<label for="credit" class="payment-method-label">
<div class="method-icon credit-icon">💰</div>
<div class="method-content">
<h4>Credit Card</h4>
<p>Fast & secure payments</p>
</div>
<div class="radio-circle"></div>
</label>
<div class="method-details" id="creditDetails" style="display: none;">
<input type="text" class="payment-input" placeholder="Card Number" maxlength="16">
<div class="input-row">
<input type="text" class="payment-input" placeholder="MM/YY" style="flex: 1;">
<input type="text" class="payment-input" placeholder="CVV" maxlength="3" style="flex: 1;">
</div>
</div>
</div>
<!-- Bank Transfer -->
<div class="payment-method-item">
<input type="radio" id="bank" name="paymentMethod" value="bank" class="radio-input">
<label for="bank" class="payment-method-label">
<div class="method-icon bank-icon">🏦</div>
<div class="method-content">
<h4>Bank Transfer</h4>
<p>Direct bank account transfer</p>
</div>
<div class="radio-circle"></div>
</label>
<div class="method-details" id="bankDetails" style="display: none;">
<div class="bank-details-box">
<p><strong>Account:</strong> NextGen Learning</p>
<p><strong>A/C No:</strong> 1234567890</p>
<p><strong>IFSC:</strong> SBIN0001234</p>
</div>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="payment-actions">
<button routerLink="/success" class="btn-payment btn-complete">
✓ Complete Payment
</button>
<button routerLink="/courses" class="btn-payment btn-back">
← Back to Courses
</button>
</div>
</div>
</div>
</div>
</div>
</div>

View File

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

View File

@ -0,0 +1,53 @@
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-payment',
standalone: true,
imports: [CommonModule, RouterModule, FormsModule],
templateUrl: './payment.html',
styleUrl: './payment.css',
})
export class PaymentComponent implements OnInit {
selectedPaymentMethod: string = '';
ngOnInit() {
this.setupPaymentMethodListeners();
}
setupPaymentMethodListeners() {
setTimeout(() => {
const radioButtons = document.querySelectorAll('input[name="paymentMethod"]');
const detailsMap: { [key: string]: string } = {
upi: 'upiDetails',
debit: 'debitDetails',
credit: 'creditDetails',
bank: 'bankDetails'
};
radioButtons.forEach((radio) => {
(radio as HTMLInputElement).addEventListener('change', (e) => {
const target = e.target as HTMLInputElement;
const selectedMethod = target.value;
this.selectedPaymentMethod = selectedMethod;
// Hide all details
Object.values(detailsMap).forEach((detailId) => {
const element = document.getElementById(detailId);
if (element) {
element.style.display = 'none';
}
});
// Show selected method details
const detailElement = document.getElementById(detailsMap[selectedMethod]);
if (detailElement) {
detailElement.style.display = 'block';
}
});
});
}, 100);
}
}

289
src/app/signup/signup.css Normal file
View File

@ -0,0 +1,289 @@
/* ===== SIGNUP PAGE STYLING ===== */
.signup-container {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(135deg, #f093fb 0%, #f5576c 50%, #667eea 100%);
padding: 20px;
position: relative;
overflow: hidden;
}
.signup-container::before {
content: '';
position: absolute;
top: -50%;
left: -10%;
width: 700px;
height: 700px;
background: rgba(255, 255, 255, 0.08);
border-radius: 50%;
animation: float 7s ease-in-out infinite;
}
.signup-container::after {
content: '';
position: absolute;
bottom: -50%;
right: -10%;
width: 500px;
height: 500px;
background: rgba(255, 255, 255, 0.08);
border-radius: 50%;
animation: float 9s ease-in-out infinite reverse;
}
@keyframes float {
0%,
100% {
transform: translateY(0px);
}
50% {
transform: translateY(40px);
}
}
.signup-card-wrapper {
position: relative;
z-index: 2;
width: 100%;
max-width: 500px;
}
.signup-card {
background: white;
border-radius: 24px;
padding: 3.5rem;
box-shadow: 0 25px 75px rgba(0, 0, 0, 0.25);
backdrop-filter: blur(20px);
animation: slideUp 0.7s ease-out;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Header */
.signup-header {
text-align: center;
margin-bottom: 2.5rem;
}
.signup-icon {
font-size: 3.5rem;
display: block;
margin-bottom: 1rem;
animation: spin 3s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.signup-title {
font-size: 2rem;
font-weight: 800;
color: #1f2937;
margin-bottom: 0.5rem;
}
.signup-subtitle {
color: #6b7280;
font-size: 1.05rem;
margin: 0;
}
/* Form */
.signup-form {
margin-bottom: 2rem;
}
.form-group-custom {
margin-bottom: 1.5rem;
}
.form-label {
display: block;
font-weight: 600;
color: #1f2937;
margin-bottom: 0.6rem;
font-size: 0.95rem;
}
.input-wrapper {
position: relative;
display: flex;
align-items: center;
}
.form-input {
width: 100%;
padding: 1rem;
border: 2px solid #e5e7eb;
border-radius: 12px;
font-size: 1rem;
transition: all 0.3s ease;
font-family: inherit;
background: #f9fafb;
}
.form-input::placeholder {
color: #9ca3af;
}
.form-input:focus {
outline: none;
border-color: #f5576c;
box-shadow: 0 0 0 3px rgba(245, 87, 108, 0.1);
background: white;
}
/* Checkbox */
.form-checkbox-signup {
display: flex;
align-items: flex-start;
margin-bottom: 1.5rem;
}
.checkbox-input {
width: 20px;
height: 20px;
cursor: pointer;
accent-color: #f5576c;
margin-top: 0.2rem;
flex-shrink: 0;
}
.checkbox-label-signup {
margin-left: 0.8rem;
color: #6b7280;
font-size: 0.95rem;
cursor: pointer;
line-height: 1.4;
}
.terms-link {
color: #f5576c;
text-decoration: none;
font-weight: 600;
transition: 0.3s;
}
.terms-link:hover {
text-decoration: underline;
}
/* Signup Button */
.btn-signup-submit {
width: 100%;
padding: 1.1rem;
background: linear-gradient(135deg, #f5576c, #f093fb);
color: white;
border: none;
border-radius: 12px;
font-size: 1.1rem;
font-weight: 700;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 6px 20px rgba(245, 87, 108, 0.25);
}
.btn-signup-submit:hover {
transform: translateY(-3px);
box-shadow: 0 10px 30px rgba(245, 87, 108, 0.35);
}
.btn-signup-submit:active {
transform: translateY(0);
}
/* Login Link Section */
.login-section {
text-align: center;
padding-top: 1.5rem;
border-top: 1px solid #e5e7eb;
}
.login-section-text {
color: #9ca3af;
font-size: 0.95rem;
margin-bottom: 1rem;
}
.btn-login-link {
display: inline-block;
width: 100%;
padding: 0.95rem;
background: rgba(245, 87, 108, 0.1);
color: #f5576c;
border: 2px solid #f5576c;
border-radius: 12px;
font-size: 1rem;
font-weight: 700;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
}
.btn-login-link:hover {
background: #f5576c;
color: white;
transform: translateY(-2px);
}
/* Decorative Blobs */
.decorative-blob {
position: absolute;
border-radius: 50%;
opacity: 0.1;
z-index: 1;
}
.blob-1 {
width: 350px;
height: 350px;
background: white;
top: -100px;
left: -100px;
}
.blob-2 {
width: 250px;
height: 250px;
background: white;
bottom: -50px;
right: -50px;
}
/* Responsive */
@media (max-width: 768px) {
.signup-card {
padding: 2rem;
}
.signup-title {
font-size: 1.5rem;
}
.signup-icon {
font-size: 2.5rem;
}
}

View File

@ -0,0 +1,79 @@
<div class="signup-container">
<div class="signup-card-wrapper">
<div class="signup-card">
<!-- Header -->
<div class="signup-header">
<div class="signup-icon"></div>
<h2 class="signup-title">Create Account</h2>
<p class="signup-subtitle">Join NextGen Learning Hub today</p>
</div>
<!-- Form -->
<form class="signup-form">
<!-- First Name -->
<div class="form-group-custom">
<label for="firstName" class="form-label">👤 Full Name</label>
<div class="input-wrapper">
<input type="text" id="firstName" class="form-input" placeholder="Enter your full name" required>
</div>
</div>
<!-- Mobile Number -->
<div class="form-group-custom">
<label for="mobileNo" class="form-label">📱 Mobile Number</label>
<div class="input-wrapper">
<input type="tel" id="mobileNo" class="form-input" placeholder="Enter your mobile number" required>
</div>
</div>
<!-- Email Address -->
<div class="form-group-custom">
<label for="email" class="form-label">📧 Email Address</label>
<div class="input-wrapper">
<input type="email" id="email" class="form-input" placeholder="Enter your email address" required>
</div>
</div>
<!-- Password -->
<div class="form-group-custom">
<label for="password" class="form-label">🔐 Password</label>
<div class="input-wrapper">
<input type="password" id="password" class="form-input" placeholder="Create a strong password" required>
</div>
</div>
<!-- Confirm Password -->
<div class="form-group-custom">
<label for="confirmPassword" class="form-label">🔒 Confirm Password</label>
<div class="input-wrapper">
<input type="password" id="confirmPassword" class="form-input" placeholder="Confirm your password" required>
</div>
</div>
<!-- Terms Checkbox -->
<div class="form-checkbox-signup">
<input type="checkbox" id="terms" class="checkbox-input" required>
<label for="terms" class="checkbox-label-signup">I agree to the <a routerLink="/terms"
class="terms-link">Terms & Conditions</a></label>
</div>
<!-- Signup Button -->
<button routerLink="/login" type="button" class="btn-signup-submit">
🚀 Create Account
</button>
</form>
<!-- Login Link -->
<div class="login-section">
<p class="login-section-text">Already have an account?</p>
<button routerLink="/login" type="button" class="btn-login-link">
🔐 Sign In
</button>
</div>
</div>
<!-- Decorative Background Elements -->
<div class="decorative-blob blob-1"></div>
<div class="decorative-blob blob-2"></div>
</div>
</div>

View File

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

12
src/app/signup/signup.ts Normal file
View File

@ -0,0 +1,12 @@
import { Component } from '@angular/core';
import { RouterModule } from '@angular/router';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-signup',
standalone: true,
imports: [RouterModule, FormsModule],
templateUrl: './signup.html',
styleUrl: './signup.css',
})
export class SignupComponent {}

42
src/app/terms/terms.css Normal file
View File

@ -0,0 +1,42 @@
/* ===== TERMS PAGE ===== */
body {
background: #f4f7fb;
font-family: Poppins, sans-serif;
}
.terms-container {
max-width: 900px;
margin: 40px auto;
}
.terms-box {
background: white;
padding: 30px;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
height: 400px;
overflow-y: scroll;
}
.terms-title {
text-align: center;
color: #0d3b66;
margin-bottom: 20px;
}
.agree-box {
margin-top: 15px;
}
.agree-btn {
background: #1c6dd0;
border: none;
padding: 10px 20px;
border-radius: 10px;
color: white;
}
.agree-btn:hover {
background: #0d3b66;
}

19
src/app/terms/terms.html Normal file
View File

@ -0,0 +1,19 @@
<h3>Terms & Agreement</h3>
<div class="terms-box">
Terms text here...
</div>
<input type="checkbox">
I agree
<br><br>
<button routerLink="/payment"
class="btn btn-primary">
Accept
</button>

View File

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

9
src/app/terms/terms.ts Normal file
View File

@ -0,0 +1,9 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-terms',
imports: [],
templateUrl: './terms.html',
styleUrl: './terms.css',
})
export class TermsComponent {}

View File

@ -1 +1,64 @@
@import url("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css");
/* ===== GLOBAL THEME ===== */
body {
font-family: 'Poppins', sans-serif;
background: #7857ccdc;
color: #1a1a1a;
}
:root {
--primary: #0d3b66;
--secondary: #031b38;
--light: #ffffff;
--gray: #a2aec4;
--shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
--radius: 12px;
}
/* Buttons */
.btn-primary {
background: var(--secondary);
border: none;
border-radius: var(--radius);
padding: 10px 20px;
transition: 0.3s;
}
.btn-primary:hover {
background: var(--primary);
transform: translateY(-2px);
}
/* Card */
.card-ui {
border-radius: var(--radius);
box-shadow: var(--shadow);
transition: 0.3s;
}
.card-ui:hover {
transform: translateY(-5px);
}
/* Form */
.form-ui {
border-radius: var(--radius);
padding: 25px;
background: white;
box-shadow: var(--shadow);
}
/* Input */
input,
select {
border-radius: 10px !important;
padding: 10px !important;
}
/* You can add global styles to this file, and also import other style files */