This commit is contained in:
Iliyan Angelov
2025-11-24 08:42:03 +02:00
parent 136f75a859
commit d7ff5c71e6
15 changed files with 697 additions and 43 deletions

View File

@@ -0,0 +1,27 @@
"use client";
import Header from "@/components/shared/layout/header/Header";
import AboutBanner from "@/components/pages/about/AboutBanner";
import AboutServiceComponent from "@/components/pages/about/AboutService";
import Footer from "@/components/shared/layout/footer/Footer";
import AboutScrollProgressButton from "@/components/pages/about/AboutScrollProgressButton";
import AboutInitAnimations from "@/components/pages/about/AboutInitAnimations";
import AboutStarter from "@/components/pages/about/AboutStarter";
const AboutUsClient = () => {
return (
<div className="enterprise-about-page">
<Header />
<main>
<AboutBanner />
<AboutServiceComponent />
<AboutStarter />
</main>
<Footer />
<AboutScrollProgressButton />
<AboutInitAnimations />
</div>
);
};
export default AboutUsClient;

View File

@@ -1,35 +1,26 @@
"use client";
import { useEffect } from 'react';
import Header from "@/components/shared/layout/header/Header";
import AboutBanner from "@/components/pages/about/AboutBanner";
import AboutServiceComponent from "@/components/pages/about/AboutService";
import Footer from "@/components/shared/layout/footer/Footer";
import AboutScrollProgressButton from "@/components/pages/about/AboutScrollProgressButton";
import AboutInitAnimations from "@/components/pages/about/AboutInitAnimations";
import AboutStarter from "@/components/pages/about/AboutStarter";
// Server Component - metadata export is allowed here
import { Metadata } from 'next';
import { generateMetadata as createMetadata } from "@/lib/seo/metadata";
import AboutUsClient from "./AboutUsClient";
export const metadata: Metadata = createMetadata({
title: "About Us - Enterprise Software Development Company",
description: "Learn about GNX Soft - a leading enterprise software development company founded in 2020, specializing in custom software solutions, data replication, AI business intelligence, incident management, and comprehensive IT solutions for modern businesses.",
keywords: [
"About GNX Soft",
"Software Development Company",
"Enterprise Solutions Provider",
"IT Services Company",
"Custom Software Development",
"Technology Company",
"Software Engineering Team",
"Digital Transformation Experts",
],
url: "/about-us",
});
// Note: Since this is a client component, we'll set metadata via useEffect
const AboutUsPage = () => {
useEffect(() => {
document.title = "About Us - Enterprise Software Development Company | GNX Soft";
const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) {
metaDescription.setAttribute('content', 'Learn about GNX Soft - a leading enterprise software development company with expertise in custom software, data replication, AI business intelligence, and comprehensive IT solutions.');
}
}, []);
return (
<div className="enterprise-about-page">
<Header />
<main>
<AboutBanner />
<AboutServiceComponent />
<AboutStarter />
</main>
<Footer />
<AboutScrollProgressButton />
<AboutInitAnimations />
</div>
);
return <AboutUsClient />;
};
export default AboutUsPage;

View File

@@ -1,18 +1,48 @@
"use client";
import { useParams } from "next/navigation";
import { useEffect } from "react";
import Header from "@/components/shared/layout/header/Header";
import JobSingle from "@/components/pages/career/JobSingle";
import Footer from "@/components/shared/layout/footer/Footer";
import CareerScrollProgressButton from "@/components/pages/career/CareerScrollProgressButton";
import CareerInitAnimations from "@/components/pages/career/CareerInitAnimations";
import { useJob } from "@/lib/hooks/useCareer";
import { generateCareerMetadata } from "@/lib/seo/metadata";
const JobPage = () => {
const params = useParams();
const slug = params?.slug as string;
const { job, loading, error } = useJob(slug);
// Update metadata dynamically for client component
useEffect(() => {
if (job) {
const metadata = generateCareerMetadata(job);
const title = typeof metadata.title === 'string' ? metadata.title : `Career - ${job.title} | GNX Soft`;
document.title = title;
// Update meta description
let metaDescription = document.querySelector('meta[name="description"]');
if (!metaDescription) {
metaDescription = document.createElement('meta');
metaDescription.setAttribute('name', 'description');
document.head.appendChild(metaDescription);
}
const description = typeof metadata.description === 'string' ? metadata.description : `Apply for ${job.title} at GNX Soft. ${job.location || 'Remote'} position.`;
metaDescription.setAttribute('content', description);
// Update canonical URL
let canonical = document.querySelector('link[rel="canonical"]');
if (!canonical) {
canonical = document.createElement('link');
canonical.setAttribute('rel', 'canonical');
document.head.appendChild(canonical);
}
canonical.setAttribute('href', `${window.location.origin}/career/${job.slug}`);
}
}, [job]);
if (loading) {
return (
<div className="tp-app">

View File

@@ -1,11 +1,64 @@
import { Metadata } from 'next';
import { notFound } from 'next/navigation';
import Header from "@/components/shared/layout/header/Header";
import BlogSingle from "@/components/pages/blog/BlogSingle";
import LatestPost from "@/components/pages/blog/LatestPost";
import Footer from "@/components/shared/layout/footer/Footer";
import BlogScrollProgressButton from "@/components/pages/blog/BlogScrollProgressButton";
import BlogInitAnimations from "@/components/pages/blog/BlogInitAnimations";
import { generateBlogMetadata } from "@/lib/seo/metadata";
import { API_CONFIG } from "@/lib/config/api";
const page = () => {
interface PageProps {
params: Promise<{
slug: string;
}>;
}
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const { slug } = await params;
try {
const response = await fetch(
`${API_CONFIG.BASE_URL}/api/blog/posts/${slug}/`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
next: { revalidate: 3600 },
}
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const post = await response.json();
return generateBlogMetadata({
title: post.title,
description: post.meta_description || post.excerpt || post.content?.substring(0, 160),
excerpt: post.excerpt,
slug: post.slug,
image: post.featured_image || post.thumbnail,
published_at: post.published_at,
updated_at: post.updated_at,
author: post.author ? { name: post.author.name } : undefined,
category: post.category ? { name: post.category.title } : undefined,
tags: post.tags?.map((tag: any) => tag.name) || [],
});
} catch (error) {
return {
title: 'Insight Not Found | GNX Soft',
description: 'The requested insight article could not be found.',
};
}
}
const page = async ({ params }: PageProps) => {
const { slug } = await params;
return (
<div className="tp-app">
<Header />

View File

@@ -1,3 +1,4 @@
import { Metadata } from 'next';
import Header from "@/components/shared/layout/header/Header";
import HomeBanner from "@/components/pages/home/HomeBanner";
import Overview from "@/components/pages/home/Overview";
@@ -7,6 +8,27 @@ import HomeLatestPost from "@/components/pages/home/HomeLatestPost";
import Footer from "@/components/shared/layout/footer/Footer";
import HomeScrollProgressButton from "@/components/pages/home/HomeScrollProgressButton";
import HomeInitAnimations from "@/components/pages/home/HomeInitAnimations";
import { generateMetadata as createMetadata } from "@/lib/seo/metadata";
export const metadata: Metadata = createMetadata({
title: "Enterprise Software Development & IT Solutions",
description: "GNX Soft - Leading enterprise software development company specializing in custom software solutions, data replication, incident management, AI business intelligence, backend & frontend engineering, and comprehensive system integrations for modern businesses.",
keywords: [
"Enterprise Software Development",
"Custom Software Solutions",
"Data Replication Services",
"Incident Management SaaS",
"AI Business Intelligence",
"Backend Engineering",
"Frontend Development",
"Systems Integration",
"Cloud Solutions",
"DevOps Services",
"API Development",
"Digital Transformation",
],
url: "/",
});
const page = () => {
return (

View File

@@ -1,9 +1,11 @@
"use client";
import { useSearchParams } from 'next/navigation';
import { useEffect } from 'react';
import Header from "@/components/shared/layout/header/Header";
import Footer from "@/components/shared/layout/footer/Footer";
import { Suspense } from 'react';
import { usePolicy } from '@/lib/hooks/usePolicy';
import { generateMetadata as createMetadata } from "@/lib/seo/metadata";
const PolicyContent = () => {
const searchParams = useSearchParams();
@@ -12,6 +14,44 @@ const PolicyContent = () => {
const { data: policy, isLoading, error } = usePolicy(type);
// Update metadata based on policy type
useEffect(() => {
const policyTitles = {
privacy: 'Privacy Policy - Data Protection & Privacy',
terms: 'Terms of Use - Terms & Conditions',
support: 'Support Policy - Support Terms & Guidelines',
};
const policyDescriptions = {
privacy: 'Read GNX Soft\'s Privacy Policy to understand how we collect, use, and protect your personal information and data.',
terms: 'Review GNX Soft\'s Terms of Use and Conditions for using our software services and platforms.',
support: 'Learn about GNX Soft\'s Support Policy, including support terms, response times, and service level agreements.',
};
const metadata = createMetadata({
title: policyTitles[type],
description: policyDescriptions[type],
keywords: [
type === 'privacy' ? 'Privacy Policy' : type === 'terms' ? 'Terms of Use' : 'Support Policy',
'Legal Documents',
'Company Policies',
'Data Protection',
'Terms and Conditions',
],
url: `/policy?type=${type}`,
});
document.title = metadata.title || `${policyTitles[type]} | GNX Soft`;
let metaDescription = document.querySelector('meta[name="description"]');
if (!metaDescription) {
metaDescription = document.createElement('meta');
metaDescription.setAttribute('name', 'description');
document.head.appendChild(metaDescription);
}
metaDescription.setAttribute('content', metadata.description || policyDescriptions[type]);
}, [type]);
if (isLoading) {
return (
<section className="policy-section section-padding">

View File

@@ -13,19 +13,59 @@ export default function robots(): MetadataRoute.Robots {
'/admin/',
'/_next/',
'/private/',
'/static/',
'/*.json$',
'/*?*',
],
},
{
userAgent: 'Googlebot',
allow: '/',
disallow: ['/api/', '/admin/', '/private/'],
allow: [
'/',
'/services',
'/services/*',
'/about-us',
'/contact-us',
'/career',
'/career/*',
'/case-study',
'/case-study/*',
'/insights',
'/insights/*',
'/support-center',
'/policy',
],
disallow: [
'/api/',
'/admin/',
'/private/',
'/_next/',
'/static/',
],
},
{
userAgent: 'Bingbot',
allow: '/',
disallow: ['/api/', '/admin/', '/private/'],
allow: [
'/',
'/services',
'/services/*',
'/about-us',
'/contact-us',
'/career',
'/career/*',
'/case-study',
'/case-study/*',
'/insights',
'/insights/*',
'/support-center',
'/policy',
],
disallow: [
'/api/',
'/admin/',
'/private/',
'/_next/',
'/static/',
],
},
],
sitemap: `${baseUrl}/sitemap.xml`,

View File

@@ -1,13 +1,43 @@
"use client";
import { useEffect } from "react";
import Header from "@/components/shared/layout/header/Header";
import Footer from "@/components/shared/layout/footer/Footer";
import SupportCenterHero from "@/components/pages/support/SupportCenterHero";
import SupportCenterContent from "@/components/pages/support/SupportCenterContent";
import { useState } from "react";
import { generateMetadata as createMetadata } from "@/lib/seo/metadata";
type ModalType = 'create' | 'knowledge' | 'status' | null;
const SupportCenterPage = () => {
// Set metadata for client component
useEffect(() => {
const metadata = createMetadata({
title: "Support Center - Enterprise Support & Help Desk",
description: "Get 24/7 enterprise support from GNX Soft. Access our knowledge base, create support tickets, check ticket status, and get help with our software solutions and services.",
keywords: [
"Support Center",
"Customer Support",
"Help Desk",
"Technical Support",
"Knowledge Base",
"Support Tickets",
"Enterprise Support",
"IT Support",
],
url: "/support-center",
});
document.title = metadata.title || "Support Center | GNX Soft";
let metaDescription = document.querySelector('meta[name="description"]');
if (!metaDescription) {
metaDescription = document.createElement('meta');
metaDescription.setAttribute('name', 'description');
document.head.appendChild(metaDescription);
}
metaDescription.setAttribute('content', metadata.description || 'Get enterprise support from GNX Soft');
}, []);
const [activeModal, setActiveModal] = useState<ModalType>(null);
return (