Skip to content

Commit 159b7ba

Browse files
committed
update
1 parent 0dcea7f commit 159b7ba

File tree

14 files changed

+258
-66
lines changed

14 files changed

+258
-66
lines changed

dot-api/JassWebApi.Base/Controllers/BlogController.cs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
using JassWebApi.Base.Filters;
22
using JassWebApi.Data;
3-
using JassWebApi.Entities;
4-
using Microsoft.AspNetCore.Http;
53
using Microsoft.AspNetCore.Mvc;
6-
using Microsoft.EntityFrameworkCore;
74

85
namespace JassWebApi.Base.Controllers
96
{
@@ -15,20 +12,12 @@ public class BlogController(IBlogRepository blogRepository) : JsmtBaseController
1512

1613
// POST: api/blog/filter
1714
[HttpPost("filter")]
18-
public IActionResult GetBlogs([FromBody] BlogFilter filter)
15+
public async Task<IActionResult> GetBlogs([FromBody] BlogFilter filter)
1916
{
2017
var blogs = _blogRepository.GetBlogs(filter);
2118
return RESP_Success(blogs);
2219
}
2320

24-
// POST: api/blog
25-
//[HttpPost]
26-
//public IActionResult Insert([FromBody] Blog blog)
27-
//{
28-
// var inserted = _blogRepository.Insert(blog);
29-
// return RESP_Success(inserted, "Inserted successfully");
30-
//}
31-
3221
// GET: api/blog/{id}
3322
[HttpGet("id/{id}")]
3423
public IActionResult GetById(int id)
@@ -42,7 +31,7 @@ public IActionResult GetById(int id)
4231

4332
[Persist(10)]
4433
[HttpGet("view/{slug}")]
45-
public IActionResult GetBySlug(string slug)
34+
public async Task<IActionResult> GetBySlug(string slug)
4635
{
4736
var blog = _blogRepository.GetBySlug(slug);
4837
if (blog == null)
@@ -63,13 +52,13 @@ public IActionResult Delete(int id)
6352
public IActionResult GetCategories()
6453
{
6554
var categories = _blogRepository.GetAll()
66-
.Select(c => new
67-
{
68-
c.Id,
69-
c.Name,
70-
c.Slug
71-
})
72-
.ToList();
55+
.Select(c => new
56+
{
57+
c.Id,
58+
c.Name,
59+
c.Slug
60+
})
61+
.ToList();
7362

7463
return RESP_Success(categories);
7564
}

ui/package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@angular/forms": "^20.0.0",
1818
"@angular/platform-browser": "^20.0.0",
1919
"@angular/router": "^20.0.0",
20+
"gsap": "^3.13.0",
2021
"highlight.js": "^11.11.1",
2122
"marked": "^16.0.0",
2223
"rxjs": "~7.8.0",

ui/src/app/components/animations/logo/logo.css

Whitespace-only changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<svg #svg xmlns="http://www.w3.org/2000/svg" width="220" height="400" viewBox="00 200 960 100"
2+
preserveAspectRatio="xMidYMid meet" style="margin-left: 0px;">
3+
<g transform="translate(0,275) scale(0.1,-0.1)" fill="none" stroke="currentColor" stroke-width="40">
4+
<path
5+
d="M520 2725 c0 -3 0 -104 0 -225 0 -121 0 -224 0 -230 0 -6 84 -10 230 -10 l231 0 -3 -787 c-4 -900 0 -858 -87 -944 -71 -71 -168 -85 -263 -38 -43 22 -73 62 -104 138 l-23 56 -250 3 c-138 1 -251 -1 -251 -5 0 -5 11 -48 24 -98 47 -173 117 -297 228 -401 188 -175 476 -231 735 -142 132 45 199 87 281 173 103 108 159 228 187 400 12 75 15 262 15 1103 l0 1012 -475 0 c-261 0 -475 -2 -475 -5z"
6+
opacity="1" pathLength="1" stroke-dashoffset="0px" stroke-dasharray="1px 1px"></path>
7+
<path
8+
d="M2305 2734 c-326 -53 -572 -272 -639 -571 -21 -92 -21 -270 0 -371 33 -164 134 -314 272 -405 79 -53 217 -116 397 -182 201 -74 271 -111 341 -180 74 -73 96 -129 96 -242 -1 -96 -31 -162 -107 -231 -73 -67 -154 -97 -260 -96 -102 1 -167 28 -229 94 -61 66 -88 121 -111 232 l-5 28 -256 0 -257 0 7 -60 c21 -187 95 -345 226 -484 176 -186 400 -275 664 -263 198 9 362 65 508 176 127 96 233 262 280 436 31 118 31 338 -1 450 -82 290 -258 442 -689 594 -95 34 -198 74 -230 90 -70 35 -146 115 -161 167 -14 52 -14 147 1 198 18 60 99 138 163 157 100 29 212 9 275 -48 54 -48 76 -86 97 -168 l19 -70 244 0 244 0 -3 49 c-8 132 -80 311 -171 423 -96 119 -250 219 -395 258 -60 16 -263 28 -320 19z"
9+
opacity="1" pathLength="1" stroke-dashoffset="0px" stroke-dasharray="1px 1px"></path>
10+
<path
11+
d="M3447 2481 l-187 -269 2 -417 3 -417 160 233 160 234 3 -907 c1 -533 6 -908 11 -908 5 0 168 233 362 518 775 1134 880 1287 889 1290 7 2 10 -320 10 -912 l0 -916 250 0 250 0 0 1370 0 1370 -232 0 -233 0 -390 -560 c-214 -307 -393 -559 -397 -559 -5 -1 -8 251 -8 559 l0 560 -232 0 -233 -1 -188 -268z"
12+
opacity="1" pathLength="1" stroke-dashoffset="0px" stroke-dasharray="1px 1px"></path>
13+
<path
14+
d="M5445 2727 c-3 -7 -4 -114 -3 -237 l3 -225 483 -3 482 -2 0 -330 0 -330 -272 -2 -273 -3 0 -235 0 -235 273 -3 272 -2 0 -320 c0 -249 -3 -320 -12 -320 -7 0 -220 0 -473 0 -253 0 -466 -4 -473 -8 -9 -7 -12 -61 -10 -238 l3 -229 738 -3 737 -2 -2 1367 -3 1368 -733 3 c-588 2 -734 0 -737 -11z"
15+
opacity="1" pathLength="1" stroke-dashoffset="0px" stroke-dasharray="1px 1px"></path>
16+
<path
17+
d="M7002 2503 l3 -238 478 -3 477 -2 0 -330 0 -330 -267 -2 -268 -3 -3 -237 -2 -238 270 0 270 0 -2 -320 -3 -321 -475 -2 -475 -2 -3 -237 -2 -238 735 0 735 0 0 1370 0 1370 -735 0 -735 0 2 -237z"
18+
opacity="1" pathLength="1" stroke-dashoffset="0px" stroke-dasharray="1px 1px"></path>
19+
<path
20+
d="M8557 2723 c-4 -3 -7 -618 -7 -1365 l0 -1358 255 0 255 0 0 1130 0 1130 253 2 252 3 3 233 2 232 -503 0 c-277 0 -507 -3 -510 -7z"
21+
opacity="1" pathLength="1" stroke-dashoffset="0px" stroke-dasharray="1px 1px"></path>
22+
</g>
23+
</svg>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { Logo } from './logo';
4+
5+
describe('Logo', () => {
6+
let component: Logo;
7+
let fixture: ComponentFixture<Logo>;
8+
9+
beforeEach(async () => {
10+
await TestBed.configureTestingModule({
11+
imports: [Logo]
12+
})
13+
.compileComponents();
14+
15+
fixture = TestBed.createComponent(Logo);
16+
component = fixture.componentInstance;
17+
fixture.detectChanges();
18+
});
19+
20+
it('should create', () => {
21+
expect(component).toBeTruthy();
22+
});
23+
});
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { Component, ElementRef, ViewChild } from '@angular/core';
2+
import { gsap } from 'gsap';
3+
4+
@Component({
5+
selector: 'app-logo',
6+
imports: [],
7+
templateUrl: './logo.html',
8+
styleUrl: './logo.css'
9+
})
10+
export class Logo {
11+
@ViewChild('svg', { static: false }) svg!: ElementRef;
12+
13+
ngAfterViewInit(): void {
14+
if (!this.svg) {
15+
console.error('SVG ViewChild not found');
16+
return;
17+
}
18+
19+
const paths: NodeListOf<SVGPathElement> = this.svg.nativeElement.querySelectorAll('path');
20+
21+
// Initial appear animation for each path sequentially
22+
paths.forEach((path, i) => {
23+
gsap.set(path, {
24+
opacity: 0,
25+
scale: 1,
26+
x: 0,
27+
y: 0,
28+
scaleX: 1,
29+
scaleY: 1,
30+
transformOrigin: 'center center',
31+
filter: 'drop-shadow(0 0 0px #ffd700)'
32+
});
33+
34+
gsap.to(path, {
35+
opacity: 1,
36+
duration: 0.5,
37+
delay: i * 0.2,
38+
ease: 'power3.out'
39+
});
40+
});
41+
42+
// Mousemove scatter + random flip effect
43+
window.addEventListener('mousemove', (e) => {
44+
const mouseX = e.clientX;
45+
const mouseY = e.clientY;
46+
47+
paths.forEach((path) => {
48+
const bbox = path.getBoundingClientRect();
49+
const cx = bbox.left + bbox.width / 2;
50+
const cy = bbox.top + bbox.height / 2;
51+
52+
const dx = mouseX - cx;
53+
const dy = mouseY - cy;
54+
const distance = Math.sqrt(dx * dx + dy * dy);
55+
56+
const maxDist = 150;
57+
const ratio = Math.max(0, 1 - distance / maxDist);
58+
59+
if (ratio > 0) {
60+
// बिखरना और घुमाना
61+
const angle = Math.random() * Math.PI * 2;
62+
const scatterX = Math.cos(angle) * ratio * 20;
63+
const scatterY = Math.sin(angle) * ratio * 20;
64+
65+
// उल्टा घुमाना: आड़ा या सीधा
66+
const flipHorizontally = Math.random() > 0.5;
67+
const flipValue = ratio > 0.5 ? -1 : 1;
68+
69+
const flipProps = flipHorizontally
70+
? { scaleX: flipValue, scaleY: 1 }
71+
: { scaleX: 1, scaleY: flipValue };
72+
73+
gsap.to(path, {
74+
x: scatterX,
75+
y: scatterY,
76+
scale: 1 + ratio * 0.1,
77+
...flipProps,
78+
filter: `drop-shadow(0 0 ${10 + ratio * 20}px #ffd700)`,
79+
duration: 0.4,
80+
ease: 'power2.out'
81+
});
82+
} else {
83+
// माउस के दूर जाने पर वापस असली जगह पर ले जाना
84+
gsap.to(path, {
85+
x: 0,
86+
y: 0,
87+
scale: 1,
88+
scaleX: 1,
89+
scaleY: 1,
90+
filter: 'drop-shadow(0 0 0px #ffd700)',
91+
duration: 0.6,
92+
ease: 'power2.out'
93+
});
94+
}
95+
});
96+
});
97+
}
98+
}

ui/src/app/modules/blog/blog.html

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,48 @@
1313
<!-- Blog posts -->
1414
<div class="col-lg-9 pe-lg-4 pe-xl-5">
1515
<h1 class="pb-3 pb-lg-4">Latest Blogs</h1>
16+
1617
<!-- Clear filters button -->
1718
<div *ngIf="selectedYear || selectedCategoryId" class="mb-3 d-flex justify-content-end">
1819
<button class="btn btn-outline-secondary btn-sm" (click)="clearFilters()">
1920
Clear Filters
2021
</button>
2122
</div>
22-
<!-- Post -->
23-
<article *ngFor="let blog of blogs" class="row g-0 border-0 mb-4">
23+
24+
<!-- Skeleton loader -->
25+
<div *ngIf="isLoading">
26+
<div *ngFor="let skeleton of [1,2]" class="row g-0 border-0 mb-4">
27+
<!-- Left side image placeholder -->
28+
<div class="col-sm-5">
29+
<div class="placeholder-wave w-100 h-100 rounded-5" style="min-height: 14rem;">
30+
<div class="placeholder w-100 h-100 rounded-5"></div>
31+
</div>
32+
</div>
33+
<!-- Right side text placeholders -->
34+
<div class="col-sm-7">
35+
<div class="pt-4 pb-sm-4 ps-sm-4 pe-lg-4">
36+
<h3 class="placeholder-glow">
37+
<span class="placeholder col-8"></span>
38+
</h3>
39+
<p class="placeholder-glow">
40+
<span class="placeholder col-6"></span>
41+
<span class="placeholder col-4"></span>
42+
</p>
43+
<div class="d-flex flex-wrap align-items-center mt-n2 placeholder-glow">
44+
<span class="placeholder col-3 me-2"></span>
45+
<span class="placeholder col-2"></span>
46+
</div>
47+
</div>
48+
</div>
49+
</div>
50+
</div>
51+
52+
53+
<!-- Actual blogs -->
54+
<article *ngFor="let blog of blogs" class="row g-0 border-0 mb-4" [hidden]="isLoading">
2455
<a class="col-sm-5 bg-repeat-0 bg-size-cover bg-position-center rounded-5"
2556
[routerLink]="['/blog', blog.slug]"
26-
[style.backgroundImage]="'url(' + (blog.coverImage || '/assets/img/blog/list/default.jpg') + ')'"
57+
[style.backgroundImage]="'url(' + (blog.coverImage || '/assets/img/blog/list/default.jpg') + ')' "
2758
style="min-height: 14rem" [attr.aria-label]="blog.title"></a>
2859
<div class="col-sm-7">
2960
<div class="pt-4 pb-sm-4 ps-sm-4 pe-lg-4">
@@ -42,12 +73,12 @@ <h3>
4273
</article>
4374

4475
<!-- No blogs found -->
45-
<div *ngIf="blogs.length === 0" class="alert alert-info text-center">
76+
<div *ngIf="!isLoading && blogs.length === 0" class="alert alert-info text-center">
4677
No blogs found.
4778
</div>
4879

4980
<!-- Pagination controls -->
50-
<div class="d-flex justify-content-between align-items-center mt-4">
81+
<div class="d-flex justify-content-between align-items-center mt-4" [hidden]="isLoading">
5182
<div>
5283
<button class="btn btn-secondary me-2" (click)="prevPage()"
5384
[disabled]="currentPage === 1">Prev</button>

ui/src/app/modules/blog/blog.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class Blog {
2727
categories: any[] = [];
2828
selectedCategoryId: number | null = null;
2929
isSideBarOpen: boolean = false;
30-
30+
isLoading: boolean = true; // ✅ added
3131
offcanvasService = inject(OffcanvasService);
3232

3333
years: number[] = [2023, 2024, 2025, 2026, 2027, 2028];
@@ -61,8 +61,8 @@ export class Blog {
6161
fromDate = `${this.selectedYear}-01-01T00:00:00Z`;
6262
toDate = `${this.selectedYear}-12-31T23:59:59Z`;
6363
} else {
64-
fromDate = '1970-01-01T00:00:00Z'; // or your earliest blog date
65-
toDate = '2100-12-31T23:59:59Z'; // or your future end date
64+
fromDate = '1970-01-01T00:00:00Z';
65+
toDate = '2100-12-31T23:59:59Z';
6666
}
6767

6868
const request: BlogFilterRequest = {
@@ -86,13 +86,18 @@ export class Blog {
8686
}
8787

8888
fetchBlogs(request: BlogFilterRequest): void {
89+
this.isLoading = true; // ✅ set loading before request
8990
this.httpApiService.post<any>(`${this.apiUrl}/blog/filter`, request)
9091
.subscribe(res => {
92+
this.isLoading = false; // ✅ stop loading after response
9193
this.blogs = res.data.items || [];
9294
this.totalPages = res.data.totalPages || 100;
95+
}, err => {
96+
this.isLoading = false; // ✅ stop loading on error
97+
console.error('API error:', err);
98+
this.blogs = [];
9399
});
94100
}
95-
96101
selectCategory(categoryId: number | null): void {
97102
const queryParams = { ...this.route.snapshot.queryParams };
98103

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
p {
22
font-size: calc(var(--ar-body-font-size) * 1.125) !important
33
}
4+
5+
.cropped-image {
6+
width: 1280px;
7+
height: 768px;
8+
object-fit: cover;
9+
object-position: center;
10+
}

0 commit comments

Comments
 (0)