From 10d6e22cec9795d03e2441e9789360e48fbb68cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96ZT=C3=9CRK?= <76204082+iamsedatozturk@users.noreply.github.com> Date: Wed, 13 Aug 2025 10:00:10 +0300 Subject: [PATCH] About Countable and Seed --- .../Seeds/SeederData.json | 4 +- ui/src/utils/hooks/useCountUp.ts | 62 +++++++++++++++++++ ui/src/views/public/About.tsx | 44 ++++++++----- 3 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 ui/src/utils/hooks/useCountUp.ts diff --git a/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json b/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json index bbfef0e6..8d6cbff5 100644 --- a/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json +++ b/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json @@ -5710,7 +5710,7 @@ { "resourceName": "Platform", "key": "Public.common.company", - "tr": "Kurum", + "tr": "Kurum Adı", "en": "Organization Name" }, { @@ -6244,7 +6244,7 @@ { "resourceName": "Platform", "key": "Public.login.organizationPlaceholder", - "tr": "Kurum", + "tr": "Kurum Adı", "en": "Organization name" }, { diff --git a/ui/src/utils/hooks/useCountUp.ts b/ui/src/utils/hooks/useCountUp.ts new file mode 100644 index 00000000..ebcff86b --- /dev/null +++ b/ui/src/utils/hooks/useCountUp.ts @@ -0,0 +1,62 @@ +import { useState, useEffect, useRef } from 'react' + +interface UseCountUpOptions { + start?: number + end: number + duration?: number + suffix?: string + prefix?: string +} + +export const useCountUp = ({ + start = 0, + end, + duration = 2000, + suffix = '', + prefix = '', +}: UseCountUpOptions) => { + const [count, setCount] = useState(start) + const [isInView, setIsInView] = useState(false) + const elementRef = useRef(null) + + useEffect(() => { + const observer = new IntersectionObserver( + ([entry]) => { + if (entry.isIntersecting && !isInView) { + setIsInView(true) + } + }, + { threshold: 0.1 }, + ) + + if (elementRef.current) { + observer.observe(elementRef.current) + } + + return () => observer.disconnect() + }, [isInView]) + + useEffect(() => { + if (!isInView) return + + let startTime: number + const animateCount = (timestamp: number) => { + if (!startTime) startTime = timestamp + + const progress = Math.min((timestamp - startTime) / duration, 1) + const currentCount = Math.floor(progress * (end - start) + start) + + setCount(currentCount) + + if (progress < 1) { + requestAnimationFrame(animateCount) + } + } + + requestAnimationFrame(animateCount) + }, [isInView, start, end, duration]) + + const displayValue = `${prefix}${count}${suffix}` + + return { count, displayValue, elementRef } +} diff --git a/ui/src/views/public/About.tsx b/ui/src/views/public/About.tsx index 6d3398e3..6a0fadcf 100644 --- a/ui/src/views/public/About.tsx +++ b/ui/src/views/public/About.tsx @@ -1,10 +1,16 @@ -import React from "react"; -import { Users, Award, Clock, Globe2 } from "lucide-react"; -import { useLocalization } from "@/utils/hooks/useLocalization"; +import React from 'react' +import { Users, Award, Clock, Globe2 } from 'lucide-react' +import { useLocalization } from '@/utils/hooks/useLocalization' +import { useCountUp } from '@/utils/hooks/useCountUp' const About: React.FC = () => { const { translate } = useLocalization() + // Counter animations + const clientsCount = useCountUp({ end: 300, suffix: '+', duration: 2500 }) + const experienceCount = useCountUp({ end: 20, suffix: '+', duration: 2000 }) + const countriesCount = useCountUp({ end: 3, duration: 1500 }) + return (
{/* Hero Section */} @@ -14,12 +20,14 @@ const About: React.FC = () => { style={{ backgroundImage: 'url("https://images.pexels.com/photos/3183183/pexels-photo-3183183.jpeg?auto=compress&cs=tinysrgb&w=1920")', - backgroundSize: "cover", - backgroundPosition: "center", + backgroundSize: 'cover', + backgroundPosition: 'center', }} >
-

{translate('::Public.about.title')}

+

+ {translate('::Public.about.title')} +

{translate('::Public.about.subtitle')}

@@ -28,14 +36,18 @@ const About: React.FC = () => {
-
+
-
300+
+
+ {clientsCount.displayValue} +
{translate('::Public.about.stats.clients')}
-
+
-
20+
+
+ {experienceCount.displayValue} +
{translate('::Public.about.stats.experience')}
@@ -43,9 +55,11 @@ const About: React.FC = () => {
7/24
{translate('::Public.about.stats.support')}
-
+
-
3
+
+ {countriesCount.displayValue} +
{translate('::Public.about.stats.countries')}
@@ -89,7 +103,7 @@ const About: React.FC = () => {
- ); -}; + ) +} -export default About; +export default About