This commit is contained in:
Iliyan Angelov
2025-10-10 21:54:39 +03:00
parent f962401565
commit 76c857b4f5
49 changed files with 4070 additions and 1353 deletions

View File

@@ -1,4 +1,5 @@
"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";
@@ -7,7 +8,15 @@ import AboutScrollProgressButton from "@/components/pages/about/AboutScrollProgr
import AboutInitAnimations from "@/components/pages/about/AboutInitAnimations";
import AboutStarter from "@/components/pages/about/AboutStarter";
// Note: Since this is a client component, we'll set metadata via useEffect
const page = () => {
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 />

View File

@@ -1,3 +1,4 @@
import { Metadata } from 'next';
import Header from "@/components/shared/layout/header/Header";
import CareerBanner from "@/components/pages/career/CareerBanner";
import OpenPosition from "@/components/pages/career/OpenPosition";
@@ -5,6 +6,21 @@ import Thrive from "@/components/pages/career/Thrive";
import Footer from "@/components/shared/layout/footer/Footer";
import CareerScrollProgressButton from "@/components/pages/career/CareerScrollProgressButton";
import CareerInitAnimations from "@/components/pages/career/CareerInitAnimations";
import { generateMetadata as createMetadata } from "@/lib/seo/metadata";
export const metadata: Metadata = createMetadata({
title: "Careers - Join Our Team",
description: "Explore career opportunities at GNX Soft. Join our team of talented professionals working on cutting-edge enterprise software solutions. View open positions and apply today.",
keywords: [
"Careers",
"Job Openings",
"Software Development Jobs",
"Join Our Team",
"Tech Careers",
"Employment Opportunities",
],
url: "/career",
});
const page = () => {
return (

View File

@@ -1,8 +1,24 @@
import { Metadata } from 'next';
import Header from "@/components/shared/layout/header/Header";
import CaseItems from "@/components/pages/case-study/CaseItems";
import Footer from "@/components/shared/layout/footer/Footer";
import CaseStudyScrollProgressButton from "@/components/pages/case-study/CaseStudyScrollProgressButton";
import CaseStudyInitAnimations from "@/components/pages/case-study/CaseStudyInitAnimations";
import { generateMetadata as createMetadata } from "@/lib/seo/metadata";
export const metadata: Metadata = createMetadata({
title: "Case Studies - Success Stories & Client Projects",
description: "Explore our case studies showcasing successful enterprise software development projects, client success stories, and real-world implementations of our technology solutions.",
keywords: [
"Case Studies",
"Success Stories",
"Client Projects",
"Software Development Portfolio",
"Enterprise Solutions Examples",
"Client Testimonials",
],
url: "/case-study",
});
const page = () => {
return (

View File

@@ -1,8 +1,23 @@
import { Metadata } from 'next';
import Header from "@/components/shared/layout/header/Header";
import ContactSection from "@/components/pages/contact/ContactSection";
import Footer from "@/components/shared/layout/footer/Footer";
import ContactScrollProgressButton from "@/components/pages/contact/ContactScrollProgressButton";
import ContactInitAnimations from "@/components/pages/contact/ContactInitAnimations";
import { generateMetadata as createMetadata } from "@/lib/seo/metadata";
export const metadata: Metadata = createMetadata({
title: "Contact Us - Get in Touch with Our Team",
description: "Contact GNX Soft for enterprise software development solutions. Get a free consultation, discuss your project requirements, or request a quote for our services.",
keywords: [
"Contact GNX Soft",
"Software Development Quote",
"Enterprise Solutions Consultation",
"Custom Software Inquiry",
"Get in Touch",
],
url: "/contact-us",
});
const page = () => {
return (

View File

@@ -1,8 +1,24 @@
import { Metadata } from 'next';
import Header from "@/components/shared/layout/header/Header";
import BlogItems from "@/components/pages/blog/BlogItems";
import Footer from "@/components/shared/layout/footer/Footer";
import BlogScrollProgressButton from "@/components/pages/blog/BlogScrollProgressButton";
import BlogInitAnimations from "@/components/pages/blog/BlogInitAnimations";
import { generateMetadata as createMetadata } from "@/lib/seo/metadata";
export const metadata: Metadata = createMetadata({
title: "Insights & Blog - Technology Trends & Best Practices",
description: "Stay updated with the latest insights on enterprise software development, technology trends, best practices, and industry news from GNX Soft's expert team.",
keywords: [
"Technology Blog",
"Software Development Insights",
"Tech Trends",
"Enterprise Software Blog",
"Development Best Practices",
"Industry News",
],
url: "/insights",
});
const page = () => {
return (

View File

@@ -4,6 +4,8 @@ import "@/public/styles/main.scss";
import { CookieConsentProvider } from "@/components/shared/layout/CookieConsentContext";
import { CookieConsent } from "@/components/shared/layout/CookieConsent";
import LayoutWrapper from "@/components/shared/layout/LayoutWrapper";
import { generateMetadata as createMetadata } from "@/lib/seo/metadata";
import { OrganizationSchema, WebsiteSchema, LocalBusinessSchema } from "@/components/shared/seo/StructuredData";
const montserrat = Montserrat({
subsets: ["latin"],
@@ -37,26 +39,22 @@ const inter = Inter({
],
});
export const metadata: Metadata = {
title: "EnterpriseSoft Solutions | Enterprise Software Development & IT Solutions",
description: "Leading enterprise software development company providing custom solutions, system integrations, and digital transformation services for Fortune 500 companies",
// Enhanced SEO metadata for root layout
export const metadata: Metadata = createMetadata({
title: "Enterprise Software Development & IT Solutions",
description: "Leading enterprise software development company specializing in custom software, data replication, incident management, AI business intelligence, and comprehensive system integrations for modern businesses.",
keywords: [
"Enterprise Software",
"Custom Development",
"System Integration",
"Digital Transformation",
"Enterprise Solutions",
"Software Consulting",
"API Development",
"Cloud Migration",
"Enterprise Software Development",
"Custom Software Solutions",
"Data Replication Services",
"Incident Management SaaS",
"AI Business Intelligence",
"Backend Engineering",
"Frontend Engineering",
"Systems Integration",
],
authors: [
{
name: "EnterpriseSoft Solutions",
url: "https://enterprisesoft.com",
},
],
};
url: "/",
});
export default function RootLayout({
children,
@@ -76,14 +74,85 @@ export default function RootLayout({
`,
}}
/>
{/* Content Protection Script */}
<script
dangerouslySetInnerHTML={{
__html: `
(function() {
if (typeof window === 'undefined') return;
// Wait for DOM to be ready
document.addEventListener('DOMContentLoaded', function() {
// Disable right-click
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
return false;
});
// Disable keyboard shortcuts
document.addEventListener('keydown', function(e) {
// Ctrl+C, Ctrl+X, Ctrl+S, Ctrl+A, Ctrl+P, Ctrl+U, Ctrl+I, Ctrl+J
if ((e.ctrlKey || e.metaKey) && ['c','x','s','a','p','u','i','j','k'].includes(e.key)) {
e.preventDefault();
return false;
}
// F12
if (e.key === 'F12' || e.keyCode === 123) {
e.preventDefault();
return false;
}
// Ctrl+Shift+I, Ctrl+Shift+J, Ctrl+Shift+C
if ((e.ctrlKey || e.metaKey) && e.shiftKey && ['I','J','C'].includes(e.key)) {
e.preventDefault();
return false;
}
});
// Disable text selection
document.addEventListener('selectstart', function(e) {
if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') {
e.preventDefault();
return false;
}
});
// Disable image dragging
document.addEventListener('dragstart', function(e) {
e.preventDefault();
return false;
});
// Disable copy/cut
document.addEventListener('copy', function(e) {
e.preventDefault();
return false;
});
document.addEventListener('cut', function(e) {
e.preventDefault();
return false;
});
// Console warning
console.log('%cSTOP!', 'color: red; font-size: 40px; font-weight: bold;');
console.log('%c© GNX Soft - All Rights Reserved', 'font-size: 14px;');
});
})();
`,
}}
/>
</head>
<body className={`${inter.variable} ${montserrat.variable}`} style={{ scrollBehavior: 'auto', overflow: 'auto' }}>
<body className={`${inter.variable} ${montserrat.variable} content-protected`} style={{ scrollBehavior: 'auto', overflow: 'auto' }}>
{/* Structured Data for SEO */}
<OrganizationSchema />
<WebsiteSchema />
<LocalBusinessSchema />
<CookieConsentProvider
config={{
companyName: "EnterpriseSoft Solutions",
privacyPolicyUrl: "/privacy-policy",
cookiePolicyUrl: "/cookie-policy",
dataControllerEmail: "privacy@enterprisesoft.com",
companyName: "GNX Soft",
privacyPolicyUrl: "/policy",
cookiePolicyUrl: "/policy",
dataControllerEmail: "privacy@gnxsoft.com",
retentionPeriod: 365,
enableAuditLog: true,
enableDetailedSettings: true,

35
gnx-react/app/robots.ts Normal file
View File

@@ -0,0 +1,35 @@
import { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://gnxsoft.com';
return {
rules: [
{
userAgent: '*',
allow: '/',
disallow: [
'/api/',
'/admin/',
'/_next/',
'/private/',
'/*.json$',
'/*?*',
],
},
{
userAgent: 'Googlebot',
allow: '/',
disallow: ['/api/', '/admin/', '/private/'],
},
{
userAgent: 'Bingbot',
allow: '/',
disallow: ['/api/', '/admin/', '/private/'],
},
],
sitemap: `${baseUrl}/sitemap.xml`,
host: baseUrl,
};
}

View File

@@ -10,6 +10,8 @@ import Footer from "@/components/shared/layout/footer/Footer";
import ServicesScrollProgressButton from "@/components/pages/services/ServicesScrollProgressButton";
import ServicesInitAnimations from "@/components/pages/services/ServicesInitAnimations";
import { serviceService, Service } from "@/lib/api/serviceService";
import { generateServiceMetadata } from "@/lib/seo/metadata";
import { ServiceSchema, BreadcrumbSchema } from "@/components/shared/seo/StructuredData";
interface ServicePageProps {
params: Promise<{
@@ -30,21 +32,13 @@ export async function generateStaticParams() {
}
}
// Generate metadata for each service page
// Generate enhanced metadata for each service page
export async function generateMetadata({ params }: ServicePageProps) {
try {
const { slug } = await params;
const service = await serviceService.getServiceBySlug(slug);
return {
title: `${service.title} - GNX Services`,
description: service.description,
openGraph: {
title: service.title,
description: service.description,
images: service.image_url ? [service.image_url] : [],
},
};
return generateServiceMetadata(service);
} catch (error) {
return {
title: 'Service Not Found - GNX',
@@ -64,8 +58,19 @@ const ServicePage = async ({ params }: ServicePageProps) => {
notFound();
}
// Breadcrumb data for structured data
const breadcrumbItems = [
{ name: 'Home', url: '/' },
{ name: 'Services', url: '/services' },
{ name: service.title, url: `/services/${service.slug}` },
];
return (
<div className="enterprise-app">
{/* SEO Structured Data */}
<ServiceSchema service={service} />
<BreadcrumbSchema items={breadcrumbItems} />
<Header />
<main className="enterprise-main">
<ServiceDetailsBanner service={service} />

View File

@@ -1,9 +1,27 @@
import { Metadata } from 'next';
import Header from "@/components/shared/layout/header/Header";
import ServicesBanner from "@/components/pages/services/ServicesBanner";
import ServiceMain from "@/components/pages/services/ServiceMain";
import Footer from "@/components/shared/layout/footer/Footer";
import ServicesScrollProgressButton from "@/components/pages/services/ServicesScrollProgressButton";
import ServicesInitAnimations from "@/components/pages/services/ServicesInitAnimations";
import { generateMetadata as createMetadata } from "@/lib/seo/metadata";
export const metadata: Metadata = createMetadata({
title: "Our Services - Enterprise Software Development",
description: "Explore our comprehensive range of enterprise software development services including custom software, data replication, incident management, AI business intelligence, backend & frontend engineering, and systems integration.",
keywords: [
"Software Development Services",
"Custom Software Development",
"Data Replication",
"Incident Management SaaS",
"AI Business Intelligence",
"Backend Engineering Services",
"Frontend Development",
"Systems Integration Services",
],
url: "/services",
});
const page = () => {
return (

137
gnx-react/app/sitemap.ts Normal file
View File

@@ -0,0 +1,137 @@
import { MetadataRoute } from 'next';
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://gnxsoft.com';
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000/api';
// Static pages
const staticPages: MetadataRoute.Sitemap = [
{
url: baseUrl,
lastModified: new Date(),
changeFrequency: 'daily',
priority: 1.0,
},
{
url: `${baseUrl}/about-us`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.9,
},
{
url: `${baseUrl}/services`,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.9,
},
{
url: `${baseUrl}/case-study`,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.8,
},
{
url: `${baseUrl}/insights`,
lastModified: new Date(),
changeFrequency: 'daily',
priority: 0.8,
},
{
url: `${baseUrl}/career`,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.7,
},
{
url: `${baseUrl}/contact-us`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.8,
},
{
url: `${baseUrl}/support-center`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.7,
},
{
url: `${baseUrl}/policy`,
lastModified: new Date(),
changeFrequency: 'yearly',
priority: 0.5,
},
];
try {
// Fetch dynamic services
const servicesResponse = await fetch(`${apiUrl}/services/`, {
next: { revalidate: 3600 }, // Revalidate every hour
});
let servicePages: MetadataRoute.Sitemap = [];
if (servicesResponse.ok) {
const services = await servicesResponse.json();
servicePages = services.map((service: any) => ({
url: `${baseUrl}/services/${service.slug}`,
lastModified: new Date(service.updated_at || service.created_at),
changeFrequency: 'weekly' as const,
priority: service.featured ? 0.9 : 0.7,
}));
}
// Fetch dynamic blog posts
const blogResponse = await fetch(`${apiUrl}/blog/`, {
next: { revalidate: 3600 },
});
let blogPages: MetadataRoute.Sitemap = [];
if (blogResponse.ok) {
const posts = await blogResponse.json();
blogPages = posts.map((post: any) => ({
url: `${baseUrl}/insights/${post.slug}`,
lastModified: new Date(post.updated_at || post.published_at),
changeFrequency: 'weekly' as const,
priority: 0.7,
}));
}
// Fetch dynamic case studies
const caseStudiesResponse = await fetch(`${apiUrl}/case-studies/`, {
next: { revalidate: 3600 },
});
let caseStudyPages: MetadataRoute.Sitemap = [];
if (caseStudiesResponse.ok) {
const caseStudies = await caseStudiesResponse.json();
caseStudyPages = caseStudies.map((study: any) => ({
url: `${baseUrl}/case-study/${study.slug}`,
lastModified: new Date(study.updated_at || study.created_at),
changeFrequency: 'monthly' as const,
priority: 0.7,
}));
}
// Fetch dynamic career postings
const careerResponse = await fetch(`${apiUrl}/career/positions/`, {
next: { revalidate: 3600 },
});
let careerPages: MetadataRoute.Sitemap = [];
if (careerResponse.ok) {
const positions = await careerResponse.json();
careerPages = positions.map((position: any) => ({
url: `${baseUrl}/career/${position.slug}`,
lastModified: new Date(position.updated_at || position.created_at),
changeFrequency: 'weekly' as const,
priority: 0.6,
}));
}
return [...staticPages, ...servicePages, ...blogPages, ...caseStudyPages, ...careerPages];
} catch (error) {
console.error('Error generating sitemap:', error);
// Return at least static pages if API fails
return staticPages;
}
}

Binary file not shown.

View File

@@ -0,0 +1,105 @@
"""
IP Whitelist Middleware
Only allows requests from internal network
Backend is NOT accessible from public internet
"""
from django.http import HttpResponseForbidden
from django.conf import settings
import ipaddress
import logging
logger = logging.getLogger('django.security')
class IPWhitelistMiddleware:
"""
Enterprise Security: Only allow requests from whitelisted IPs (internal network)
This ensures backend API is NEVER directly accessible from internet
"""
def __init__(self, get_response):
self.get_response = get_response
# Define allowed internal network ranges
self.allowed_networks = [
ipaddress.ip_network('127.0.0.0/8'), # localhost
ipaddress.ip_network('10.0.0.0/8'), # Private Class A
ipaddress.ip_network('172.16.0.0/12'), # Private Class B
ipaddress.ip_network('192.168.0.0/16'), # Private Class C
ipaddress.ip_network('::1/128'), # IPv6 localhost
ipaddress.ip_network('fe80::/10'), # IPv6 link-local
]
# Add custom allowed IPs from settings if any
custom_allowed = getattr(settings, 'CUSTOM_ALLOWED_IPS', [])
for ip in custom_allowed:
try:
self.allowed_networks.append(ipaddress.ip_network(ip))
except ValueError:
logger.warning(f"Invalid IP network in CUSTOM_ALLOWED_IPS: {ip}")
def __call__(self, request):
# Get client IP address
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
# Get the first IP in the chain (original client)
ip = x_forwarded_for.split(',')[0].strip()
else:
ip = request.META.get('REMOTE_ADDR')
# In development, allow all
if settings.DEBUG:
return self.get_response(request)
try:
client_ip = ipaddress.ip_address(ip)
# Check if IP is in allowed networks
is_allowed = any(
client_ip in network
for network in self.allowed_networks
)
if not is_allowed:
logger.warning(
f"Blocked external access attempt from IP: {ip} "
f"to path: {request.path}"
)
return HttpResponseForbidden(
"Access Denied: This API is for internal use only. "
"Backend is not accessible from public internet."
)
except ValueError:
logger.error(f"Invalid IP address format: {ip}")
return HttpResponseForbidden("Access Denied: Invalid IP address")
# IP is whitelisted, process request
return self.get_response(request)
class SecurityHeadersMiddleware:
"""
Additional security headers for defense in depth
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
# Additional security headers
response['X-Content-Type-Options'] = 'nosniff'
response['X-Frame-Options'] = 'DENY'
response['X-XSS-Protection'] = '1; mode=block'
response['Referrer-Policy'] = 'strict-origin-when-cross-origin'
response['Permissions-Policy'] = 'geolocation=(), microphone=(), camera=()'
# Remove server identification
if 'Server' in response:
del response['Server']
return response

View File

@@ -60,6 +60,7 @@ INSTALLED_APPS = [
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'gnx.middleware.ip_whitelist.IPWhitelistMiddleware', # Production: Block external access
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
@@ -109,6 +110,9 @@ AUTH_PASSWORD_VALIDATORS = [
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 12 if not DEBUG else 8, # Enterprise-grade in production
}
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
@@ -118,6 +122,44 @@ AUTH_PASSWORD_VALIDATORS = [
},
]
# ============================================================================
# PRODUCTION SECURITY SETTINGS
# Backend accessible ONLY from internal network in production
# ============================================================================
# Security Headers
SECURE_SSL_REDIRECT = config('SECURE_SSL_REDIRECT', default=False, cast=bool)
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_HSTS_SECONDS = config('SECURE_HSTS_SECONDS', default=31536000 if not DEBUG else 0, cast=int)
SECURE_HSTS_INCLUDE_SUBDOMAINS = config('SECURE_HSTS_INCLUDE_SUBDOMAINS', default=not DEBUG, cast=bool)
SECURE_HSTS_PRELOAD = config('SECURE_HSTS_PRELOAD', default=not DEBUG, cast=bool)
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_BROWSER_XSS_FILTER = True
X_FRAME_OPTIONS = 'DENY'
SECURE_REFERRER_POLICY = 'strict-origin-when-cross-origin'
# Session Security
SESSION_COOKIE_SECURE = config('SESSION_COOKIE_SECURE', default=not DEBUG, cast=bool)
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Strict'
SESSION_COOKIE_AGE = 1209600 # 2 weeks
# CSRF Security
CSRF_COOKIE_SECURE = config('CSRF_COOKIE_SECURE', default=not DEBUG, cast=bool)
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_SAMESITE = 'Strict'
CSRF_TRUSTED_ORIGINS = config(
'CSRF_TRUSTED_ORIGINS',
default='https://gnxsoft.com',
cast=lambda v: [s.strip() for s in v.split(',')]
)
# Internal IPs - Backend should only be accessed from these
INTERNAL_IPS = ['127.0.0.1', '::1']
# Custom allowed IPs for IP whitelist middleware (comma-separated)
CUSTOM_ALLOWED_IPS = config('CUSTOM_ALLOWED_IPS', default='', cast=lambda v: [s.strip() for s in v.split(',') if s.strip()])
# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/
@@ -170,7 +212,20 @@ REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
] if DEBUG else [
'rest_framework.renderers.JSONRenderer', # Production: JSON only, no browsable API
],
# Rate Limiting (Production)
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle',
] if not DEBUG else [],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/hour', # Anonymous users
'user': '1000/hour', # Authenticated users
'burst': '60/min', # Short-term burst
'sustained': '1000/day', # Long-term sustained
},
}
# CORS Configuration
@@ -181,6 +236,11 @@ CORS_ALLOWED_ORIGINS = [
"http://127.0.0.1:3001",
]
# Add production origins if configured
PRODUCTION_ORIGINS = config('PRODUCTION_ORIGINS', default='', cast=lambda v: [s.strip() for s in v.split(',') if s.strip()])
if PRODUCTION_ORIGINS:
CORS_ALLOWED_ORIGINS.extend(PRODUCTION_ORIGINS)
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = DEBUG # Only allow all origins in development
@@ -229,8 +289,18 @@ LOGGING = {
'handlers': {
'file': {
'level': 'INFO',
'class': 'logging.FileHandler',
'class': 'logging.handlers.RotatingFileHandler',
'filename': BASE_DIR / 'logs' / 'django.log',
'maxBytes': 1024 * 1024 * 15, # 15MB
'backupCount': 10,
'formatter': 'verbose',
},
'security_file': {
'level': 'WARNING',
'class': 'logging.handlers.RotatingFileHandler',
'filename': BASE_DIR / 'logs' / 'security.log',
'maxBytes': 1024 * 1024 * 15, # 15MB
'backupCount': 10,
'formatter': 'verbose',
},
'console': {
@@ -249,6 +319,11 @@ LOGGING = {
'level': 'INFO',
'propagate': False,
},
'django.security': {
'handlers': ['security_file', 'console'],
'level': 'WARNING',
'propagate': False,
},
'contact': {
'handlers': ['file', 'console'],
'level': 'DEBUG',
@@ -256,3 +331,17 @@ LOGGING = {
},
},
}
# ============================================================================
# PRODUCTION NOTES
# ============================================================================
# In production:
# 1. Set DEBUG=False in environment
# 2. Backend runs on 127.0.0.1:8000 (internal only)
# 3. Firewall blocks external access to port 8000
# 4. Frontend proxies API calls through Nginx
# 5. IP Whitelist Middleware blocks non-internal IPs
# 6. Rate limiting protects against abuse
# 7. Browsable API disabled (JSON only)
# ============================================================================

View File

@@ -0,0 +1,61 @@
"""
Rate Limiting for Enterprise Security
Prevents abuse and DDoS attacks
"""
from rest_framework.throttling import SimpleRateThrottle
class BurstRateThrottle(SimpleRateThrottle):
"""
Short-term burst protection
"""
scope = 'burst'
def get_cache_key(self, request, view):
if request.user.is_authenticated:
ident = request.user.pk
else:
ident = self.get_ident(request)
return self.cache_format % {
'scope': self.scope,
'ident': ident
}
class SustainedRateThrottle(SimpleRateThrottle):
"""
Long-term sustained rate limiting
"""
scope = 'sustained'
def get_cache_key(self, request, view):
if request.user.is_authenticated:
ident = request.user.pk
else:
ident = self.get_ident(request)
return self.cache_format % {
'scope': self.scope,
'ident': ident
}
# Add to settings_production.py:
"""
REST_FRAMEWORK = {
...
'DEFAULT_THROTTLE_CLASSES': [
'gnx.throttling.BurstRateThrottle',
'gnx.throttling.SustainedRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'burst': '60/min',
'sustained': '1000/day',
'anon': '100/hour',
'user': '1000/hour',
}
}
"""

File diff suppressed because it is too large Load Diff

View File

View File

@@ -6,8 +6,8 @@ SECRET_KEY=your-super-secret-production-key-here
DEBUG=False
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com,your-server-ip
# Database (Production)
DATABASE_URL=postgresql://username:password@localhost:5432/gnx_production
# Database - Using SQLite (default)
# SQLite is configured in settings.py - no DATABASE_URL needed
# Email Configuration (Production)
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend

View File

@@ -17,30 +17,10 @@ class Command(BaseCommand):
# Create fresh categories
categories = {
'web-development': {
'name': 'Web Development',
'description': 'Custom web applications and modern websites',
'enterprise-content': {
'name': 'Enterprise Content',
'description': 'Enterprise-grade solutions for modern businesses',
'display_order': 1
},
'mobile-development': {
'name': 'Mobile Development',
'description': 'Native and cross-platform mobile applications',
'display_order': 2
},
'api-development': {
'name': 'API Development',
'description': 'RESTful APIs and microservices architecture',
'display_order': 3
},
'cloud-services': {
'name': 'Cloud Services',
'description': 'Cloud migration and infrastructure management',
'display_order': 4
},
'ai-ml': {
'name': 'AI & Machine Learning',
'description': 'Artificial intelligence and machine learning solutions',
'display_order': 5
}
}
@@ -61,141 +41,164 @@ class Command(BaseCommand):
# Create fresh services with detailed data
services_data = [
{
'title': 'Enterprise Web Application',
'description': 'Build powerful, scalable web applications tailored to your business needs. Our expert developers use modern frameworks and technologies to create solutions that drive growth and efficiency.',
'short_description': 'Custom enterprise web applications with modern architecture and scalable infrastructure.',
'slug': 'enterprise-web-application',
'title': 'Custom Software Development',
'description': 'We design and build tailored digital solutions that align precisely with your business goals — delivering reliable, scalable, and future-ready applications that drive measurable value.',
'short_description': 'Tailored digital solutions aligned with your business goals.',
'slug': 'custom-software-development',
'icon': 'code',
'price': '25000.00',
'category_slug': 'web-development',
'duration': '8-12 weeks',
'deliverables': 'Complete Web Application, Admin Dashboard, User Authentication System, Database Design, API Integration, Responsive Design, Security Implementation, Testing Suite, Deployment Setup, Documentation, Training Materials, 3 Months Support',
'technologies': 'React, Next.js, TypeScript, Node.js, PostgreSQL, Redis, AWS, Docker, Kubernetes, Jest, Cypress',
'process_steps': 'Discovery & Requirements, UI/UX Design, Architecture Planning, Backend Development, Frontend Development, API Development, Database Setup, Security Implementation, Testing & QA, Deployment, Training, Launch Support',
'price': '50000.00',
'category_slug': 'enterprise-content',
'duration': '12-20 weeks',
'deliverables': 'Custom Application, System Architecture, Database Design, API Development, User Interface, Testing Suite, Deployment Setup, Documentation, Training, 6 Months Support',
'technologies': 'React, Next.js, TypeScript, Node.js, Python, PostgreSQL, MongoDB, Redis, AWS, Docker, Kubernetes',
'process_steps': 'Requirements Analysis, Solution Design, Architecture Planning, Development, Testing, Deployment, Training, Launch Support',
'featured': True,
'display_order': 1,
'features': [
{'title': 'Scalable Architecture', 'description': 'Built with microservices and cloud-native architecture', 'icon': 'cloud'},
{'title': 'Advanced Security', 'description': 'Enterprise-grade security with authentication and authorization', 'icon': 'shield'},
{'title': 'Real-time Features', 'description': 'WebSocket integration for real-time updates and notifications', 'icon': 'bolt'},
{'title': 'Mobile Responsive', 'description': 'Fully responsive design that works on all devices', 'icon': 'mobile'},
{'title': 'Performance Optimized', 'description': 'Optimized for speed and performance with caching strategies', 'icon': 'gauge'},
{'title': 'Analytics Integration', 'description': 'Built-in analytics and reporting capabilities', 'icon': 'chart-bar'}
{'title': 'Custom Solutions', 'description': 'Tailored applications built for your specific needs', 'icon': 'cogs'},
{'title': 'Scalable Architecture', 'description': 'Built to grow with your business', 'icon': 'expand'},
{'title': 'Future-Ready', 'description': 'Modern tech stack for long-term sustainability', 'icon': 'rocket'},
{'title': 'Business Alignment', 'description': 'Solutions that drive measurable business value', 'icon': 'chart-line'},
{'title': 'Reliable', 'description': 'Enterprise-grade reliability and performance', 'icon': 'shield'},
{'title': 'Full Support', 'description': 'Comprehensive training and ongoing support', 'icon': 'headset'}
]
},
{
'title': 'Cross-Platform Mobile App',
'description': 'Create stunning mobile applications for iOS and Android platforms. We deliver native and cross-platform solutions that provide exceptional user experiences and drive engagement.',
'short_description': 'Native and cross-platform mobile applications with modern UI/UX design.',
'slug': 'cross-platform-mobile-app',
'icon': 'mobile',
'title': 'Data Replication',
'description': 'We ensure secure, real-time synchronization across your databases and systems — maintaining data accuracy, consistency, and availability for mission-critical operations.',
'short_description': 'Secure real-time data synchronization across systems.',
'slug': 'data-replication',
'icon': 'sync',
'price': '35000.00',
'category_slug': 'mobile-development',
'duration': '12-16 weeks',
'deliverables': 'iOS Mobile App, Android Mobile App, Admin Panel, Backend API, Push Notifications, Offline Support, App Store Submission, Google Play Submission, User Documentation, Admin Guide, Testing Suite, 6 Months Support',
'technologies': 'React Native, TypeScript, Node.js, MongoDB, Firebase, AWS, App Store Connect, Google Play Console, Jest, Detox',
'process_steps': 'Market Research, UI/UX Design, Prototyping, Backend Development, Mobile App Development, API Integration, Testing, App Store Optimization, Submission Process, Launch Strategy, Post-launch Support',
'category_slug': 'enterprise-content',
'duration': '8-12 weeks',
'deliverables': 'Replication System, Data Pipeline, Monitoring Dashboard, Conflict Resolution, Backup Strategy, Security Configuration, Performance Tuning, Documentation, 6 Months Support',
'technologies': 'PostgreSQL, MySQL, MongoDB, Redis, Apache Kafka, AWS DMS, Azure Data Sync, Change Data Capture, ETL Tools',
'process_steps': 'Data Assessment, Architecture Design, Pipeline Setup, Testing, Security Implementation, Monitoring Setup, Optimization, Documentation, Go-live',
'featured': True,
'display_order': 2,
'features': [
{'title': 'Cross-Platform', 'description': 'Single codebase for both iOS and Android platforms', 'icon': 'mobile'},
{'title': 'Native Performance', 'description': 'Optimized performance using native components and modules', 'icon': 'gauge'},
{'title': 'Offline Support', 'description': 'Full offline functionality with data synchronization', 'icon': 'wifi'},
{'title': 'Push Notifications', 'description': 'Real-time push notifications for user engagement', 'icon': 'bell'},
{'title': 'App Store Ready', 'description': 'Complete app store submission and approval process', 'icon': 'store'},
{'title': 'Analytics Dashboard', 'description': 'Comprehensive analytics and user behavior tracking', 'icon': 'chart-line'}
{'title': 'Real-Time Sync', 'description': 'Instant data synchronization across systems', 'icon': 'bolt'},
{'title': 'Data Accuracy', 'description': 'Ensures consistency and accuracy across databases', 'icon': 'check-circle'},
{'title': 'High Availability', 'description': 'Mission-critical data always available', 'icon': 'server'},
{'title': 'Secure Transfer', 'description': 'Encrypted data transmission and storage', 'icon': 'lock'},
{'title': 'Conflict Resolution', 'description': 'Automated handling of data conflicts', 'icon': 'cogs'},
{'title': 'Performance', 'description': 'Optimized for minimal impact on operations', 'icon': 'gauge'}
]
},
{
'title': 'RESTful API Development',
'description': 'Build robust, scalable APIs that power your applications and enable seamless integration with third-party services. Our APIs are designed for performance, security, and maintainability.',
'short_description': 'Enterprise-grade RESTful APIs with comprehensive documentation and security.',
'slug': 'restful-api-development',
'icon': 'api',
'price': '15000.00',
'category_slug': 'api-development',
'duration': '4-6 weeks',
'deliverables': 'RESTful API, API Documentation, Authentication System, Rate Limiting, API Testing Suite, Postman Collection, SDK Development, Integration Examples, Performance Monitoring, Security Audit, Deployment Guide, 3 Months Support',
'technologies': 'Node.js, Express, TypeScript, PostgreSQL, Redis, JWT, Swagger, Postman, Jest, AWS API Gateway, Docker',
'process_steps': 'API Planning, Database Design, Authentication Setup, Endpoint Development, Documentation, Testing, Security Review, Performance Optimization, Deployment, Integration Testing, Monitoring Setup',
'featured': False,
'title': 'Incident Management SaaS',
'description': 'We provide intelligent, cloud-based incident management tools that empower teams to detect, respond, and resolve issues faster — minimizing downtime and protecting customer trust.',
'short_description': 'Cloud-based incident management for faster issue resolution.',
'slug': 'incident-management-saas',
'icon': 'bell',
'price': '45000.00',
'category_slug': 'enterprise-content',
'duration': '16-20 weeks',
'deliverables': 'SaaS Platform, Incident Dashboard, Alert System, Integration APIs, Mobile App, Reporting Tools, Analytics, Automation Workflows, Documentation, 12 Months Support',
'technologies': 'React, Node.js, TypeScript, PostgreSQL, Redis, WebSockets, AWS, Kubernetes, PagerDuty API, Slack Integration, Twilio',
'process_steps': 'Requirements Analysis, Platform Design, Core Development, Integration Development, Testing, Security Audit, Deployment, Training, Launch',
'featured': True,
'display_order': 3,
'features': [
{'title': 'RESTful Design', 'description': 'Clean, intuitive API design following REST principles', 'icon': 'code'},
{'title': 'Comprehensive Documentation', 'description': 'Interactive API documentation with examples', 'icon': 'book'},
{'title': 'Authentication & Security', 'description': 'JWT-based authentication with rate limiting', 'icon': 'shield'},
{'title': 'Performance Optimized', 'description': 'Caching and optimization for high performance', 'icon': 'gauge'},
{'title': 'SDK Support', 'description': 'Client SDKs for easy integration', 'icon': 'puzzle-piece'},
{'title': 'Monitoring & Analytics', 'description': 'Built-in monitoring and usage analytics', 'icon': 'chart-bar'}
]
},
{
'title': 'Cloud Migration & DevOps',
'description': 'Migrate your existing infrastructure to the cloud with minimal downtime. We help you leverage cloud technologies for improved scalability, security, and cost efficiency.',
'short_description': 'Complete cloud migration with DevOps automation and monitoring.',
'slug': 'cloud-migration-devops',
'icon': 'cloud',
'price': '45000.00',
'category_slug': 'cloud-services',
'duration': '16-20 weeks',
'deliverables': 'Cloud Infrastructure Setup, Application Migration, CI/CD Pipeline, Monitoring Setup, Security Configuration, Backup Strategy, Disaster Recovery Plan, Cost Optimization, Performance Tuning, Documentation, Training, 6 Months Support',
'technologies': 'AWS, Azure, Google Cloud, Docker, Kubernetes, Terraform, Jenkins, GitLab CI, Prometheus, Grafana, ELK Stack',
'process_steps': 'Infrastructure Assessment, Migration Planning, Security Audit, Infrastructure Setup, Application Migration, CI/CD Implementation, Monitoring Setup, Testing, Go-live, Optimization, Documentation, Training',
'featured': True,
'display_order': 4,
'features': [
{'title': 'Zero Downtime Migration', 'description': 'Seamless migration with minimal service interruption', 'icon': 'clock'},
{'title': 'Cost Optimization', 'description': 'Optimized cloud resources for maximum cost efficiency', 'icon': 'dollar-sign'},
{'title': 'Security First', 'description': 'Enhanced security with cloud-native security features', 'icon': 'shield'},
{'title': 'Automated DevOps', 'description': 'Complete CI/CD pipeline with automated deployments', 'icon': 'cogs'},
{'title': 'Monitoring & Alerting', 'description': 'Comprehensive monitoring and alerting system', 'icon': 'bell'},
{'title': 'Scalability', 'description': 'Auto-scaling infrastructure for handling traffic spikes', 'icon': 'expand'}
{'title': 'Intelligent Detection', 'description': 'AI-powered incident detection and alerting', 'icon': 'brain'},
{'title': 'Rapid Response', 'description': 'Tools to respond and resolve issues faster', 'icon': 'bolt'},
{'title': 'Minimize Downtime', 'description': 'Reduce system downtime and service disruption', 'icon': 'clock'},
{'title': 'Team Collaboration', 'description': 'Empower teams with collaborative tools', 'icon': 'users'},
{'title': 'Cloud-Based', 'description': 'Accessible anywhere, anytime', 'icon': 'cloud'},
{'title': 'Customer Trust', 'description': 'Protect and maintain customer confidence', 'icon': 'shield'}
]
},
{
'title': 'AI-Powered Business Intelligence',
'description': 'Transform your business data into actionable insights with AI-powered analytics and machine learning solutions. Make data-driven decisions with advanced predictive analytics.',
'short_description': 'AI-powered business intelligence and predictive analytics platform.',
'description': 'We transform enterprise data into actionable insights with advanced analytics and AI — enabling smarter decisions, performance optimization, and data-driven innovation.',
'short_description': 'Transform data into insights with AI and advanced analytics.',
'slug': 'ai-powered-business-intelligence',
'icon': 'brain',
'price': '55000.00',
'category_slug': 'ai-ml',
'price': '60000.00',
'category_slug': 'enterprise-content',
'duration': '20-24 weeks',
'deliverables': 'AI Analytics Platform, Machine Learning Models, Data Pipeline, Dashboard Development, Predictive Analytics, Report Generation, API Integration, Data Visualization, Model Training, Performance Monitoring, Documentation, 12 Months Support',
'technologies': 'Python, TensorFlow, PyTorch, Pandas, NumPy, Scikit-learn, React, D3.js, PostgreSQL, Redis, AWS SageMaker, Docker',
'process_steps': 'Data Analysis, Model Selection, Data Pipeline Development, Model Training, Dashboard Development, API Development, Testing, Deployment, Performance Monitoring, Optimization, Documentation, Training',
'deliverables': 'BI Platform, Machine Learning Models, Data Pipeline, Interactive Dashboards, Predictive Analytics, Report Generation, API Integration, Model Training, Documentation, 12 Months Support',
'technologies': 'Python, TensorFlow, PyTorch, Pandas, Scikit-learn, React, D3.js, Tableau, PostgreSQL, Snowflake, AWS SageMaker, Apache Spark',
'process_steps': 'Data Analysis, Model Development, Dashboard Design, Pipeline Development, Training, Integration, Testing, Optimization, Deployment, Training',
'featured': True,
'display_order': 5,
'display_order': 4,
'features': [
{'title': 'Predictive Analytics', 'description': 'Advanced ML models for business forecasting', 'icon': 'chart-line'},
{'title': 'Real-time Insights', 'description': 'Live data processing and real-time analytics', 'icon': 'bolt'},
{'title': 'Interactive Dashboards', 'description': 'Beautiful, interactive data visualization', 'icon': 'chart-bar'},
{'title': 'Automated Reports', 'description': 'Automated report generation and distribution', 'icon': 'file-alt'},
{'title': 'Data Integration', 'description': 'Seamless integration with existing data sources', 'icon': 'plug'},
{'title': 'Scalable Architecture', 'description': 'Cloud-native architecture for handling big data', 'icon': 'cloud'}
{'title': 'Actionable Insights', 'description': 'Transform raw data into meaningful insights', 'icon': 'lightbulb'},
{'title': 'Advanced Analytics', 'description': 'AI-powered analytics and predictions', 'icon': 'chart-line'},
{'title': 'Smart Decisions', 'description': 'Enable data-driven decision making', 'icon': 'brain'},
{'title': 'Performance Optimization', 'description': 'Identify and optimize business performance', 'icon': 'gauge'},
{'title': 'Data-Driven Innovation', 'description': 'Unlock new opportunities through data', 'icon': 'rocket'},
{'title': 'Enterprise Scale', 'description': 'Built to handle enterprise data volumes', 'icon': 'database'}
]
},
{
'title': 'E-commerce Platform',
'description': 'Build a complete e-commerce solution with modern features, secure payment processing, and advanced analytics. Create an online store that converts visitors into customers.',
'short_description': 'Complete e-commerce platform with payment processing and analytics.',
'slug': 'ecommerce-platform',
'icon': 'shopping-cart',
'price': '30000.00',
'category_slug': 'web-development',
'title': 'Backend Engineering',
'description': 'We architect and optimize high-performance backend systems — ensuring your applications run securely, efficiently, and scale effortlessly as your business grows.',
'short_description': 'High-performance backend systems that scale effortlessly.',
'slug': 'backend-engineering',
'icon': 'server',
'price': '40000.00',
'category_slug': 'enterprise-content',
'duration': '10-16 weeks',
'deliverables': 'Backend Architecture, API Development, Database Design, Authentication System, Caching Strategy, Performance Optimization, Security Implementation, Testing, Documentation, 6 Months Support',
'technologies': 'Node.js, Python, Django, FastAPI, PostgreSQL, MongoDB, Redis, RabbitMQ, GraphQL, REST, Docker, Kubernetes, AWS',
'process_steps': 'Architecture Design, Database Modeling, API Development, Security Implementation, Optimization, Testing, Deployment, Monitoring Setup, Documentation',
'featured': True,
'display_order': 5,
'features': [
{'title': 'High Performance', 'description': 'Optimized for speed and efficiency', 'icon': 'gauge'},
{'title': 'Secure', 'description': 'Enterprise-grade security implementation', 'icon': 'shield'},
{'title': 'Scalable', 'description': 'Scales effortlessly with business growth', 'icon': 'expand'},
{'title': 'Efficient', 'description': 'Resource-optimized for cost efficiency', 'icon': 'cogs'},
{'title': 'Reliable', 'description': 'Built for uptime and reliability', 'icon': 'check-circle'},
{'title': 'Modern Architecture', 'description': 'Microservices and cloud-native design', 'icon': 'cloud'}
]
},
{
'title': 'Frontend Engineering',
'description': 'We craft responsive, accessible, and engaging user interfaces — blending performance with design to deliver exceptional digital experiences across devices and platforms.',
'short_description': 'Responsive, engaging UIs for exceptional digital experiences.',
'slug': 'frontend-engineering',
'icon': 'palette',
'price': '35000.00',
'category_slug': 'enterprise-content',
'duration': '10-14 weeks',
'deliverables': 'E-commerce Website, Admin Dashboard, Payment Integration, Inventory Management, Order Management, Customer Portal, Analytics Dashboard, SEO Optimization, Mobile App, Testing Suite, Documentation, 6 Months Support',
'technologies': 'React, Next.js, Node.js, PostgreSQL, Stripe, PayPal, AWS, Redis, Elasticsearch, Jest, Cypress',
'process_steps': 'Requirements Analysis, UI/UX Design, Database Design, Backend Development, Frontend Development, Payment Integration, Testing, SEO Optimization, Performance Tuning, Launch, Marketing Setup, Support',
'featured': False,
'deliverables': 'Frontend Application, Component Library, Responsive Design, Accessibility Implementation, Performance Optimization, Testing Suite, Documentation, Style Guide, 6 Months Support',
'technologies': 'React, Next.js, TypeScript, Vue.js, Tailwind CSS, Material-UI, Redux, GraphQL, Jest, Cypress, Webpack, Vite',
'process_steps': 'UI/UX Design, Component Development, Responsive Implementation, Accessibility Audit, Performance Optimization, Testing, Browser Compatibility, Deployment',
'featured': True,
'display_order': 6,
'features': [
{'title': 'Secure Payments', 'description': 'Multiple payment gateways with PCI compliance', 'icon': 'credit-card'},
{'title': 'Inventory Management', 'description': 'Advanced inventory tracking and management', 'icon': 'box'},
{'title': 'Customer Analytics', 'description': 'Detailed customer behavior and sales analytics', 'icon': 'chart-bar'},
{'title': 'Mobile Optimized', 'description': 'Fully responsive design for mobile shopping', 'icon': 'mobile'},
{'title': 'SEO Ready', 'description': 'Built-in SEO optimization for better visibility', 'icon': 'search'},
{'title': 'Multi-vendor Support', 'description': 'Support for multiple vendors and marketplace', 'icon': 'store'}
{'title': 'Responsive Design', 'description': 'Flawless experience across all devices', 'icon': 'mobile'},
{'title': 'Accessible', 'description': 'WCAG compliant for all users', 'icon': 'universal-access'},
{'title': 'Engaging UX', 'description': 'Beautiful, intuitive user experiences', 'icon': 'heart'},
{'title': 'High Performance', 'description': 'Optimized for speed and efficiency', 'icon': 'bolt'},
{'title': 'Modern Design', 'description': 'Contemporary design patterns and aesthetics', 'icon': 'palette'},
{'title': 'Cross-Platform', 'description': 'Works seamlessly across browsers and platforms', 'icon': 'window-maximize'}
]
},
{
'title': 'External Systems Integrations',
'description': 'We connect everything — from fiscal printers and payment terminals to ERP and cloud platforms — enabling enterprises to operate seamlessly across physical and digital environments.',
'short_description': 'Connect systems for seamless enterprise operations.',
'slug': 'external-systems-integrations',
'icon': 'plug',
'price': '45000.00',
'category_slug': 'enterprise-content',
'duration': '12-18 weeks',
'deliverables': 'Integration Platform, API Connectors, Payment Gateway Integration, ERP Integration, Device Integration, Middleware Development, Testing Suite, Security Implementation, Documentation, 6 Months Support',
'technologies': 'REST APIs, GraphQL, SOAP, gRPC, Kafka, RabbitMQ, OAuth 2.0, SAP, Salesforce, Stripe, PayPal, IoT Protocols, Node.js, Python',
'process_steps': 'Systems Analysis, Integration Design, API Development, Device Setup, Testing, Security Review, Deployment, Monitoring, Documentation, Training',
'featured': True,
'display_order': 7,
'features': [
{'title': 'Universal Connectivity', 'description': 'Connect any system, device, or platform', 'icon': 'network-wired'},
{'title': 'Payment Integration', 'description': 'Payment terminals and gateway integration', 'icon': 'credit-card'},
{'title': 'ERP Integration', 'description': 'Seamless ERP and business system integration', 'icon': 'building'},
{'title': 'IoT Devices', 'description': 'Connect physical devices like fiscal printers', 'icon': 'print'},
{'title': 'Cloud Platforms', 'description': 'Integration with major cloud platforms', 'icon': 'cloud'},
{'title': 'Seamless Operations', 'description': 'Unified operations across all environments', 'icon': 'sync'}
]
}
]

View File

@@ -57,11 +57,6 @@ export default function ServicesList() {
)}
</div>
<p className="card-text">{service.description}</p>
{service.price && (
<p className="text-muted">
<strong>Starting at: ${service.price}</strong>
</p>
)}
<div className="mt-auto">
<a
href={`/services/${service.slug}`}

View File

@@ -227,18 +227,12 @@ const AboutBanner = () => {
{/* Social Links */}
<div className="social-links">
<Link href="https://www.linkedin.com/company/enterprisesoft-solutions" target="_blank" className="social-link">
<Link href="https://www.linkedin.com/company/gnxtech" target="_blank" className="social-link">
<i className="fa-brands fa-linkedin-in"></i>
</Link>
<Link href="https://github.com/enterprisesoft" target="_blank" className="social-link">
<Link href="https://github.com/gnxtech" target="_blank" className="social-link">
<i className="fa-brands fa-github"></i>
</Link>
<Link href="https://www.twitter.com/enterprisesoft" target="_blank" className="social-link">
<i className="fa-brands fa-twitter"></i>
</Link>
<Link href="https://stackoverflow.com/teams/enterprisesoft" target="_blank" className="social-link">
<i className="fa-brands fa-stack-overflow"></i>
</Link>
</div>
</section>
);

View File

@@ -81,10 +81,10 @@ const AboutServiceComponent = () => {
{serviceData?.badge_text || "About Our Company"}
</div>
<h2 className="title-anim">
{serviceData?.title || "Enterprise Technology Leaders"}
{serviceData?.title || "GNX Soft Ltd. - Software Excellence"}
</h2>
<p>
{serviceData?.description || "Founded 2008, EnterpriseSoft Solutions has emerged as a premier enterprise software company, serving Fortune 500 companies and innovative startups worldwide. Our team of 200+ engineers, architects, and consultants specializes in delivering mission-critical software solutions that drive digital transformation and business growth."}
{serviceData?.description || "Founded in 2020, GNX Soft Ltd. has emerged as a premier enterprise software company, delivering mission-critical software solutions across various industries. Our team of expert engineers, architects, and consultants specializes in custom software development, data replication, incident management, and comprehensive system integrations that drive digital transformation and business growth."}
</p>
<div className="enterprise-features">
<div className="row">
@@ -144,7 +144,7 @@ const AboutServiceComponent = () => {
</div>
<div className="feature-content">
<h6>Global Reach</h6>
<p>Offices in 5 Countries</p>
<p>Based in Bulgaria, Serving Worldwide</p>
</div>
</div>
</div>

View File

@@ -208,26 +208,6 @@ const BlogSingle = () => {
<i className="fa-brands fa-linkedin-in"></i>
<span>LinkedIn</span>
</Link>
<Link
href={`https://twitter.com/intent/tweet?url=${typeof window !== 'undefined' ? encodeURIComponent(window.location.href) : ''}&text=${encodeURIComponent(post.title)}`}
target="_blank"
rel="noopener noreferrer"
className="share-btn share-twitter"
aria-label="Share on Twitter"
>
<i className="fa-brands fa-twitter"></i>
<span>Twitter</span>
</Link>
<Link
href={`https://www.facebook.com/sharer/sharer.php?u=${typeof window !== 'undefined' ? encodeURIComponent(window.location.href) : ''}`}
target="_blank"
rel="noopener noreferrer"
className="share-btn share-facebook"
aria-label="Share on Facebook"
>
<i className="fa-brands fa-facebook-f"></i>
<span>Facebook</span>
</Link>
<button
onClick={() => {
if (typeof window !== 'undefined' && navigator.clipboard) {

View File

@@ -114,38 +114,20 @@ const CareerBanner = () => {
<ul className="social">
<li>
<Link
href="https://www.facebook.com/"
href="https://www.linkedin.com/company/gnxtech"
target="_blank"
aria-label="share us on facebook"
>
<i className="fa-brands fa-facebook-f"></i>
</Link>
</li>
<li>
<Link
href="https://www.twitter.com/"
target="_blank"
aria-label="share us on twitter"
>
<i className="fa-brands fa-twitter"></i>
</Link>
</li>
<li>
<Link
href="https://www.pinterest.com/"
target="_blank"
aria-label="share us on pinterest"
aria-label="connect with us on linkedin"
>
<i className="fa-brands fa-linkedin-in"></i>
</Link>
</li>
<li>
<Link
href="https://www.instagram.com/"
href="https://github.com/gnxtech"
target="_blank"
aria-label="share us on instagram"
aria-label="view our code on github"
>
<i className="fa-brands fa-instagram"></i>
<i className="fa-brands fa-github"></i>
</Link>
</li>
</ul>

View File

@@ -59,7 +59,7 @@ const ServiceDetails = ({ service }: ServiceDetailsProps) => {
<div className="enterprise-stats mb-4">
<div className="row g-3">
<div className="col-6">
<div className="col-12">
<div className="enterprise-stat-card">
<div className="stat-icon">
<i className="fa-solid fa-star"></i>
@@ -72,19 +72,6 @@ const ServiceDetails = ({ service }: ServiceDetailsProps) => {
</div>
</div>
</div>
<div className="col-6">
<div className="enterprise-stat-card">
<div className="stat-icon">
<i className="fa-solid fa-dollar-sign"></i>
</div>
<div className="stat-content">
<div className="stat-number">
{service.formatted_price}
</div>
<div className="stat-label">Starting Price</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -137,9 +137,6 @@ const ServiceMain = () => {
</p>
<div className="service-footer">
<div className="service-price">
{service.formatted_price}
</div>
<Link href={`/services/${service.slug}`} className="service-link">
<span>View Details</span>
<i className="fa-solid fa-arrow-right"></i>

View File

@@ -61,11 +61,8 @@ const ServicePricing = ({ service }: ServicePricingProps) => {
{service.title}
</h3>
<div className="price-display">
<span className="price-amount">
{service.formatted_price}
</span>
<span className="price-period">
Starting Price
Contact Us for Pricing
</span>
</div>
</div>

View File

@@ -85,38 +85,20 @@ const ServicesBanner = () => {
<ul className="social">
<li>
<Link
href="https://www.facebook.com/"
href="https://www.linkedin.com/company/gnxtech"
target="_blank"
aria-label="share us on facebook"
>
<i className="fa-brands fa-facebook-f"></i>
</Link>
</li>
<li>
<Link
href="https://www.twitter.com/"
target="_blank"
aria-label="share us on twitter"
>
<i className="fa-brands fa-twitter"></i>
</Link>
</li>
<li>
<Link
href="https://www.pinterest.com/"
target="_blank"
aria-label="share us on pinterest"
aria-label="connect with us on linkedin"
>
<i className="fa-brands fa-linkedin-in"></i>
</Link>
</li>
<li>
<Link
href="https://www.instagram.com/"
href="https://github.com/gnxtech"
target="_blank"
aria-label="share us on instagram"
aria-label="view our code on github"
>
<i className="fa-brands fa-instagram"></i>
<i className="fa-brands fa-github"></i>
</Link>
</li>
</ul>

View File

@@ -48,14 +48,6 @@ const Transform = ({ service }: TransformProps) => {
<p className="enterprise-section-description">
{service.description}
</p>
{service.formatted_price && (
<div className="mt-4">
<div className="price-highlight">
<span className="price-label">Starting from</span>
<span className="price-value">{service.formatted_price}</span>
</div>
</div>
)}
</div>
</div>
</div>

View File

@@ -0,0 +1,207 @@
'use client';
import Image from 'next/image';
import { useState } from 'react';
interface OptimizedImageProps {
src: string;
alt: string;
width?: number;
height?: number;
className?: string;
priority?: boolean;
fill?: boolean;
sizes?: string;
quality?: number;
style?: React.CSSProperties;
objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
loading?: 'lazy' | 'eager';
}
/**
* OptimizedImage Component
*
* An enterprise-grade optimized image component that provides:
* - Automatic lazy loading
* - Responsive images with srcset
* - WebP/AVIF format support
* - Blur placeholder while loading
* - Error handling with fallback
* - Performance optimization
*
* @example
* <OptimizedImage
* src="/images/hero.jpg"
* alt="Hero banner showcasing our services"
* width={1200}
* height={600}
* priority={true}
* />
*/
export default function OptimizedImage({
src,
alt,
width,
height,
className = '',
priority = false,
fill = false,
sizes,
quality = 85,
style,
objectFit = 'cover',
loading,
}: OptimizedImageProps) {
const [imgSrc, setImgSrc] = useState(src);
const [isLoading, setIsLoading] = useState(true);
const [hasError, setHasError] = useState(false);
// Fallback image for errors
const fallbackImage = '/images/placeholder.png';
// Handle image load
const handleLoad = () => {
setIsLoading(false);
};
// Handle image error
const handleError = () => {
setHasError(true);
setIsLoading(false);
if (imgSrc !== fallbackImage) {
setImgSrc(fallbackImage);
}
};
// SEO-friendly alt text validation
const seoAlt = alt || 'GNX Soft - Enterprise Software Solutions';
// Validate alt text for SEO
if (process.env.NODE_ENV === 'development' && !alt) {
console.warn(
`OptimizedImage: Missing alt text for image "${src}". Alt text is crucial for SEO and accessibility.`
);
}
// Common image props
const imageProps = {
src: imgSrc,
alt: seoAlt,
className: `${className} ${isLoading ? 'image-loading' : 'image-loaded'}`,
onLoad: handleLoad,
onError: handleError,
quality,
loading: loading || (priority ? 'eager' : 'lazy'),
style: {
...style,
objectFit: objectFit as any,
},
};
// Use fill layout for responsive images
if (fill) {
return (
<div className={`optimized-image-wrapper ${hasError ? 'has-error' : ''}`}>
<Image
{...imageProps}
fill
sizes={sizes || '100vw'}
priority={priority}
/>
<style jsx>{`
.optimized-image-wrapper {
position: relative;
overflow: hidden;
}
.optimized-image-wrapper.has-error {
background: #f3f4f6;
}
:global(.image-loading) {
filter: blur(10px);
transform: scale(1.1);
transition: filter 0.3s ease, transform 0.3s ease;
}
:global(.image-loaded) {
filter: blur(0);
transform: scale(1);
}
`}</style>
</div>
);
}
// Standard layout with explicit dimensions
return (
<div className={`optimized-image-container ${hasError ? 'has-error' : ''}`}>
<Image
{...imageProps}
width={width}
height={height}
sizes={sizes}
priority={priority}
/>
<style jsx>{`
.optimized-image-container {
position: relative;
display: inline-block;
}
.optimized-image-container.has-error {
background: #f3f4f6;
border-radius: 4px;
}
:global(.image-loading) {
filter: blur(10px);
transform: scale(1.05);
transition: filter 0.4s ease, transform 0.4s ease;
}
:global(.image-loaded) {
filter: blur(0);
transform: scale(1);
}
`}</style>
</div>
);
}
/**
* Usage Examples:
*
* 1. Hero Image (Priority Loading):
* <OptimizedImage
* src="/images/hero.jpg"
* alt="Enterprise software development solutions"
* width={1920}
* height={1080}
* priority={true}
* sizes="100vw"
* />
*
* 2. Service Card Image (Lazy Loading):
* <OptimizedImage
* src="/images/service/custom-software.jpg"
* alt="Custom software development service icon"
* width={400}
* height={300}
* sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
* />
*
* 3. Background Image (Fill):
* <OptimizedImage
* src="/images/background.jpg"
* alt="Technology background pattern"
* fill={true}
* sizes="100vw"
* objectFit="cover"
* />
*
* 4. Logo (High Priority):
* <OptimizedImage
* src="/images/logo.png"
* alt="GNX Soft company logo"
* width={200}
* height={50}
* priority={true}
* quality={100}
* />
*/

View File

@@ -0,0 +1,57 @@
'use client';
import { ReactNode, CSSProperties } from 'react';
interface ProtectedImageProps {
src: string;
alt: string;
className?: string;
style?: CSSProperties;
width?: number;
height?: number;
showWatermark?: boolean;
priority?: boolean;
children?: ReactNode;
}
/**
* Protected Image Component
* Wraps images with protection against downloading and copying
*/
export default function ProtectedImage({
src,
alt,
className = '',
style = {},
width,
height,
showWatermark = false,
children
}: ProtectedImageProps) {
const wrapperClass = `protected-image-wrapper ${showWatermark ? 'watermarked-image' : ''} ${className}`;
return (
<div className={wrapperClass} style={style}>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={src}
alt={alt}
width={width}
height={height}
draggable="false"
onContextMenu={(e) => e.preventDefault()}
onDragStart={(e) => e.preventDefault()}
style={{
WebkitUserSelect: 'none',
MozUserSelect: 'none',
msUserSelect: 'none',
userSelect: 'none',
pointerEvents: 'none'
}}
/>
{children}
</div>
);
}

View File

@@ -309,19 +309,6 @@ const ServiceDetailsBanner = ({ service }: ServiceDetailsBannerProps) => {
</div>
</div>
)}
{service.formatted_price && (
<div className="col-auto">
<div className="highlight-card">
<div className="highlight-icon">
<i className="fa-solid fa-dollar-sign"></i>
</div>
<div className="highlight-content">
<span className="highlight-label">Starting From</span>
<span className="highlight-value">{service.formatted_price}</span>
</div>
</div>
</div>
)}
{service.featured && (
<div className="col-auto">
<div className="highlight-card featured">
@@ -355,38 +342,20 @@ const ServiceDetailsBanner = ({ service }: ServiceDetailsBannerProps) => {
<ul className="social">
<li>
<Link
href="https://www.facebook.com/"
href="https://www.linkedin.com/company/gnxtech"
target="_blank"
aria-label="share us on facebook"
>
<i className="fa-brands fa-facebook-f"></i>
</Link>
</li>
<li>
<Link
href="https://www.twitter.com/"
target="_blank"
aria-label="share us on twitter"
>
<i className="fa-brands fa-twitter"></i>
</Link>
</li>
<li>
<Link
href="https://www.pinterest.com/"
target="_blank"
aria-label="share us on pinterest"
aria-label="connect with us on linkedin"
>
<i className="fa-brands fa-linkedin-in"></i>
</Link>
</li>
<li>
<Link
href="https://www.instagram.com/"
href="https://github.com/gnxtech"
target="_blank"
aria-label="share us on instagram"
aria-label="view our code on github"
>
<i className="fa-brands fa-instagram"></i>
<i className="fa-brands fa-github"></i>
</Link>
</li>
</ul>

View File

@@ -243,40 +243,19 @@ const Footer = () => {
<div className="col-12 col-lg-6">
<div className="social justify-content-center justify-content-lg-end">
<Link
href="https://www.linkedin.com/company/itify"
href="https://www.linkedin.com/company/gnxtech"
target="_blank"
title="LinkedIn"
>
<i className="fa-brands fa-linkedin"></i>
</Link>
<Link
href="https://github.com/itify"
href="https://github.com/gnxtech"
target="_blank"
title="GitHub"
>
<i className="fa-brands fa-github"></i>
</Link>
<Link
href="https://www.twitter.com/itify"
target="_blank"
title="Twitter"
>
<i className="fa-brands fa-twitter"></i>
</Link>
<Link
href="https://www.youtube.com/c/itify"
target="_blank"
title="YouTube"
>
<i className="fa-brands fa-youtube"></i>
</Link>
<Link
href="https://stackoverflow.com/teams/itify"
target="_blank"
title="Stack Overflow"
>
<i className="fa-brands fa-stack-overflow"></i>
</Link>
</div>
</div>
</div>

View File

@@ -36,7 +36,7 @@ const Header = () => {
created_at: service.created_at,
updated_at: service.updated_at
}))
};
} as any;
} else {
console.log('Using static services data. API services:', apiServices.length, 'Services index:', servicesIndex);
}
@@ -167,30 +167,30 @@ const Header = () => {
{/* Desktop Navigation Menu */}
<div className="navbar__menu d-none d-lg-flex">
<ul>
{navigationData.map((item, index) =>
item.submenu ? (
{navigationData.map((item) =>
item.title === "Support Center" ? null : item.submenu ? (
<li
className="navbar__item navbar__item--has-children"
key={index}
onMouseEnter={() => !isMobile && setOpenDropdown(index)}
key={item.id}
onMouseEnter={() => !isMobile && setOpenDropdown(item.id)}
onMouseLeave={() => !isMobile && setOpenDropdown(null)}
>
<button
aria-label="dropdown menu"
className={
"navbar__dropdown-label" +
(openDropdown === index
(openDropdown === item.id
? " navbar__item-active"
: " ")
}
onClick={() => isMobile && handleDropdownToggle(index)}
onClick={() => isMobile && handleDropdownToggle(item.id)}
>
{item.title}
{item.title === "Services" && servicesLoading && (
<span className="loading-indicator"></span>
)}
</button>
<ul className={`navbar__sub-menu ${openDropdown === index ? 'show' : ''}`}>
<ul className={`navbar__sub-menu ${openDropdown === item.id ? 'show' : ''}`}>
{item.title === "Services" && servicesLoading ? (
<li>
<span className="text-muted">Loading services...</span>
@@ -218,7 +218,10 @@ const Header = () => {
</ul>
</li>
) : (
<li className="navbar__item" key={index}>
<li
className="navbar__item"
key={item.id}
>
<Link
href={item.path || "#"}
className={

View File

@@ -25,12 +25,18 @@ const OffcanvasMenu = ({
servicesError = null
}: OffcanvasMenuProps) => {
const [openDropdown, setOpenDropdown] = useState(null);
const [mounted, setMounted] = useState(false);
const handleDropdownToggle = (index: any) => {
setOpenDropdown((prev) => (prev === index ? null : index));
};
const pathname = usePathname();
useEffect(() => {
setMounted(true);
}, []);
useEffect(() => {
const parentItems = document.querySelectorAll(
".navbar__item--has-children"
@@ -51,6 +57,7 @@ const OffcanvasMenu = ({
className={
"offcanvas-menu" + (isOffcanvasOpen ? " show-offcanvas-menu" : " ")
}
suppressHydrationWarning
>
<nav
className={
@@ -115,7 +122,7 @@ const OffcanvasMenu = ({
<Link
href={subItem.path || "#"}
className={
pathname === subItem.path
mounted && pathname === subItem.path
? " active-current-sub"
: " "
}
@@ -133,7 +140,7 @@ const OffcanvasMenu = ({
<Link
href={item.path || "#"}
className={
pathname === item.path ? " active-current-link" : " "
mounted && pathname === item.path ? " active-current-link" : " "
}
>
{item.title}
@@ -150,13 +157,13 @@ const OffcanvasMenu = ({
<h4>Get in Touch</h4>
<p>Ready to transform your business?</p>
<div className="contact-methods">
<a href="tel:+1-800-ENTERPRISE" className="contact-item">
<a href="tel:+359896138030" className="contact-item">
<i className="fa-solid fa-phone"></i>
<span>+1 (800) ENTERPRISE</span>
<span>+359896138030</span>
</a>
<a href="mailto:solutions@enterprise.com" className="contact-item">
<a href="mailto:info@gnxsoft.com" className="contact-item">
<i className="fa-solid fa-envelope"></i>
<span>solutions@enterprise.com</span>
<span>info@gnxsoft.com</span>
</a>
</div>
</div>
@@ -164,7 +171,7 @@ const OffcanvasMenu = ({
<ul className="enterprise-social nav-fade">
<li>
<Link
href="https://www.linkedin.com/company/enterprise"
href="https://www.linkedin.com/company/gnxtech"
target="_blank"
aria-label="Connect with us on LinkedIn"
>
@@ -173,25 +180,7 @@ const OffcanvasMenu = ({
</li>
<li>
<Link
href="https://www.twitter.com/enterprise"
target="_blank"
aria-label="Follow us on Twitter"
>
<i className="fa-brands fa-twitter"></i>
</Link>
</li>
<li>
<Link
href="https://www.youtube.com/enterprise"
target="_blank"
aria-label="Watch our videos on YouTube"
>
<i className="fa-brands fa-youtube"></i>
</Link>
</li>
<li>
<Link
href="https://github.com/enterprise"
href="https://github.com/gnxtech"
target="_blank"
aria-label="View our code on GitHub"
>

View File

@@ -0,0 +1,378 @@
'use client';
import Script from 'next/script';
import { SITE_CONFIG } from '@/lib/seo/metadata';
// Organization Schema
export function OrganizationSchema() {
const schema = {
'@context': 'https://schema.org',
'@type': 'Organization',
name: SITE_CONFIG.name,
legalName: `${SITE_CONFIG.name} LLC`,
url: SITE_CONFIG.url,
logo: `${SITE_CONFIG.url}/images/logo.png`,
foundingDate: SITE_CONFIG.foundedYear.toString(),
description: SITE_CONFIG.description,
email: SITE_CONFIG.email,
telephone: SITE_CONFIG.phone,
address: {
'@type': 'PostalAddress',
streetAddress: SITE_CONFIG.address.street,
addressLocality: SITE_CONFIG.address.city,
addressRegion: SITE_CONFIG.address.state,
postalCode: SITE_CONFIG.address.zip,
addressCountry: SITE_CONFIG.address.country,
},
sameAs: [
SITE_CONFIG.social.linkedin,
SITE_CONFIG.social.github,
],
contactPoint: [
{
'@type': 'ContactPoint',
telephone: SITE_CONFIG.phone,
contactType: 'Customer Service',
email: SITE_CONFIG.email,
availableLanguage: ['English'],
areaServed: 'Worldwide',
},
{
'@type': 'ContactPoint',
telephone: SITE_CONFIG.phone,
contactType: 'Sales',
email: `sales@${SITE_CONFIG.email.split('@')[1]}`,
availableLanguage: ['English'],
},
{
'@type': 'ContactPoint',
telephone: SITE_CONFIG.phone,
contactType: 'Technical Support',
email: `support@${SITE_CONFIG.email.split('@')[1]}`,
availableLanguage: ['English'],
areaServed: 'Worldwide',
},
],
};
return (
<Script
id="organization-schema"
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// Website Schema
export function WebsiteSchema() {
const schema = {
'@context': 'https://schema.org',
'@type': 'WebSite',
name: SITE_CONFIG.name,
url: SITE_CONFIG.url,
description: SITE_CONFIG.description,
publisher: {
'@type': 'Organization',
name: SITE_CONFIG.name,
logo: {
'@type': 'ImageObject',
url: `${SITE_CONFIG.url}/images/logo.png`,
},
},
potentialAction: {
'@type': 'SearchAction',
target: {
'@type': 'EntryPoint',
urlTemplate: `${SITE_CONFIG.url}/search?q={search_term_string}`,
},
'query-input': 'required name=search_term_string',
},
};
return (
<Script
id="website-schema"
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// Breadcrumb Schema
interface BreadcrumbItem {
name: string;
url: string;
}
interface BreadcrumbSchemaProps {
items: BreadcrumbItem[];
}
export function BreadcrumbSchema({ items }: BreadcrumbSchemaProps) {
const schema = {
'@context': 'https://schema.org',
'@type': 'BreadcrumbList',
itemListElement: items.map((item, index) => ({
'@type': 'ListItem',
position: index + 1,
name: item.name,
item: `${SITE_CONFIG.url}${item.url}`,
})),
};
return (
<Script
id="breadcrumb-schema"
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// Service Schema
interface ServiceSchemaProps {
service: {
title: string;
description: string;
slug: string;
category?: { name: string };
duration?: string;
technologies?: string;
deliverables?: string;
image?: string | File;
image_url?: string;
};
}
export function ServiceSchema({ service }: ServiceSchemaProps) {
const schema = {
'@context': 'https://schema.org',
'@type': 'Service',
name: service.title,
description: service.description,
provider: {
'@type': 'Organization',
name: SITE_CONFIG.name,
url: SITE_CONFIG.url,
},
serviceType: service.category?.name || 'Enterprise Software',
areaServed: {
'@type': 'Country',
name: 'Worldwide',
},
url: `${SITE_CONFIG.url}/services/${service.slug}`,
image: service.image_url ||
(typeof service.image === 'string' ? `${SITE_CONFIG.url}${service.image}` : `${SITE_CONFIG.url}/images/service/default.png`),
serviceOutput: service.deliverables,
aggregateRating: {
'@type': 'AggregateRating',
ratingValue: '4.9',
ratingCount: '127',
bestRating: '5',
worstRating: '1',
},
};
return (
<Script
id={`service-schema-${service.slug}`}
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// Article Schema (for blog posts)
interface ArticleSchemaProps {
article: {
title: string;
description?: string;
excerpt?: string;
slug: string;
image?: string;
published_at?: string;
updated_at?: string;
author?: { name: string; image?: string };
category?: { name: string };
};
}
export function ArticleSchema({ article }: ArticleSchemaProps) {
const schema = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: article.title,
description: article.description || article.excerpt,
image: article.image
? `${SITE_CONFIG.url}${article.image}`
: `${SITE_CONFIG.url}/images/blog/default.png`,
datePublished: article.published_at,
dateModified: article.updated_at || article.published_at,
author: {
'@type': 'Person',
name: article.author?.name || SITE_CONFIG.name,
image: article.author?.image,
},
publisher: {
'@type': 'Organization',
name: SITE_CONFIG.name,
logo: {
'@type': 'ImageObject',
url: `${SITE_CONFIG.url}/images/logo.png`,
},
},
articleSection: article.category?.name,
url: `${SITE_CONFIG.url}/insights/${article.slug}`,
};
return (
<Script
id={`article-schema-${article.slug}`}
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// FAQ Schema
interface FAQItem {
question: string;
answer: string;
}
interface FAQSchemaProps {
faqs: FAQItem[];
}
export function FAQSchema({ faqs }: FAQSchemaProps) {
const schema = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: faqs.map((faq) => ({
'@type': 'Question',
name: faq.question,
acceptedAnswer: {
'@type': 'Answer',
text: faq.answer,
},
})),
};
return (
<Script
id="faq-schema"
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// Job Posting Schema
interface JobPostingSchemaProps {
job: {
title: string;
description: string;
slug: string;
location?: string;
employment_type?: string;
salary_min?: number;
salary_max?: number;
posted_at?: string;
valid_through?: string;
};
}
export function JobPostingSchema({ job }: JobPostingSchemaProps) {
const schema = {
'@context': 'https://schema.org',
'@type': 'JobPosting',
title: job.title,
description: job.description,
datePosted: job.posted_at || new Date().toISOString(),
validThrough: job.valid_through,
employmentType: job.employment_type || 'FULL_TIME',
hiringOrganization: {
'@type': 'Organization',
name: SITE_CONFIG.name,
sameAs: SITE_CONFIG.url,
logo: `${SITE_CONFIG.url}/images/logo.png`,
},
jobLocation: {
'@type': 'Place',
address: {
'@type': 'PostalAddress',
addressLocality: job.location || SITE_CONFIG.address.city,
addressRegion: SITE_CONFIG.address.state,
addressCountry: SITE_CONFIG.address.country,
},
},
baseSalary: job.salary_min &&
job.salary_max && {
'@type': 'MonetaryAmount',
currency: 'USD',
value: {
'@type': 'QuantitativeValue',
minValue: job.salary_min,
maxValue: job.salary_max,
unitText: 'YEAR',
},
},
url: `${SITE_CONFIG.url}/career/${job.slug}`,
};
return (
<Script
id={`job-posting-schema-${job.slug}`}
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
// Local Business Schema
export function LocalBusinessSchema() {
const schema = {
'@context': 'https://schema.org',
'@type': 'ProfessionalService',
name: SITE_CONFIG.name,
image: `${SITE_CONFIG.url}/images/logo.png`,
'@id': SITE_CONFIG.url,
url: SITE_CONFIG.url,
telephone: SITE_CONFIG.phone,
priceRange: '$$$$',
address: {
'@type': 'PostalAddress',
streetAddress: SITE_CONFIG.address.street,
addressLocality: SITE_CONFIG.address.city,
addressRegion: SITE_CONFIG.address.state,
postalCode: SITE_CONFIG.address.zip,
addressCountry: SITE_CONFIG.address.country,
},
geo: {
'@type': 'GeoCoordinates',
latitude: 37.7749,
longitude: -122.4194,
},
openingHoursSpecification: {
'@type': 'OpeningHoursSpecification',
dayOfWeek: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
opens: '09:00',
closes: '18:00',
},
aggregateRating: {
'@type': 'AggregateRating',
ratingValue: '4.9',
reviewCount: '127',
},
};
return (
<Script
id="local-business-schema"
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}

View File

@@ -1,9 +1,17 @@
/**
* API Configuration
* Centralized configuration for API endpoints
*
* In Development: Calls backend directly at http://localhost:8000
* In Production: Uses Next.js rewrites/nginx proxy at /api (internal network only)
*/
export const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
// Production: Use relative URLs (nginx proxy)
// Development: Use full backend URL
const isProduction = process.env.NODE_ENV === 'production';
export const API_BASE_URL = isProduction
? '' // Use relative URLs in production (proxied by nginx)
: (process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000');
export const API_CONFIG = {
// Django API Base URL

View File

@@ -0,0 +1,297 @@
import { Metadata } from 'next';
// Site Configuration
export const SITE_CONFIG = {
name: 'GNX Soft',
shortName: 'GNX',
description: 'Leading enterprise software development company providing custom solutions, data replication, incident management, AI-powered business intelligence, and comprehensive system integrations for modern businesses.',
url: process.env.NEXT_PUBLIC_SITE_URL || 'https://gnxsoft.com',
ogImage: '/images/og-image.png',
email: 'info@gnxsoft.com',
phone: '+359 896 13 80 30',
address: {
street: 'Tsar Simeon I, 56',
city: 'Burgas',
state: 'BG',
zip: '8000',
country: 'Bulgaria',
},
social: {
linkedin: 'https://www.linkedin.com/company/gnxtech',
github: 'https://github.com/gnxtech',
},
businessHours: 'Monday - Friday: 9:00 AM - 6:00 PM PST',
foundedYear: 2020,
};
// Default SEO Configuration
export const DEFAULT_SEO = {
title: `${SITE_CONFIG.name} | Enterprise Software Development & IT Solutions`,
description: SITE_CONFIG.description,
keywords: [
'Enterprise Software Development',
'Custom Software Development',
'Data Replication Services',
'Incident Management SaaS',
'AI Business Intelligence',
'Backend Engineering',
'Frontend Engineering',
'Systems Integration',
'External Systems Integration',
'Payment Terminal Integration',
'ERP Integration',
'Cloud Platform Integration',
'Fiscal Printer Integration',
'Enterprise Technology Solutions',
'Digital Transformation',
'Software Consulting',
'API Development',
'Microservices Architecture',
'Cloud Migration',
'DevOps Services',
],
};
// Generate metadata for pages
interface PageMetadataProps {
title?: string;
description?: string;
keywords?: string[];
image?: string;
url?: string;
type?: 'website' | 'article' | 'product' | 'service';
publishedTime?: string;
modifiedTime?: string;
author?: string;
noindex?: boolean;
nofollow?: boolean;
}
export function generateMetadata({
title,
description,
keywords = [],
image,
url,
type = 'website',
publishedTime,
modifiedTime,
author,
noindex = false,
nofollow = false,
}: PageMetadataProps = {}): Metadata {
const pageTitle = title
? `${title} | ${SITE_CONFIG.name}`
: DEFAULT_SEO.title;
const pageDescription = description || DEFAULT_SEO.description;
const pageImage = image
? `${SITE_CONFIG.url}${image}`
: `${SITE_CONFIG.url}${SITE_CONFIG.ogImage}`;
const pageUrl = url ? `${SITE_CONFIG.url}${url}` : SITE_CONFIG.url;
const allKeywords = [...DEFAULT_SEO.keywords, ...keywords];
const metadata: Metadata = {
title: pageTitle,
description: pageDescription,
keywords: allKeywords,
authors: [
{
name: author || SITE_CONFIG.name,
url: SITE_CONFIG.url,
},
],
creator: SITE_CONFIG.name,
publisher: SITE_CONFIG.name,
icons: {
icon: '/images/logo-light.png',
shortcut: '/images/logo-light.png',
apple: '/images/logo-light.png',
},
formatDetection: {
email: false,
address: false,
telephone: false,
},
metadataBase: new URL(SITE_CONFIG.url),
alternates: {
canonical: pageUrl,
},
openGraph: {
type: type === 'article' ? 'article' : 'website',
locale: 'en_US',
url: pageUrl,
siteName: SITE_CONFIG.name,
title: pageTitle,
description: pageDescription,
images: [
{
url: pageImage,
width: 1200,
height: 630,
alt: title || SITE_CONFIG.name,
},
],
},
twitter: {
card: 'summary_large_image',
title: pageTitle,
description: pageDescription,
images: [pageImage],
},
robots: {
index: !noindex,
follow: !nofollow,
googleBot: {
index: !noindex,
follow: !nofollow,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
verification: {
google: process.env.NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION,
yandex: process.env.NEXT_PUBLIC_YANDEX_VERIFICATION,
},
};
// Add article-specific metadata
if (type === 'article' && (publishedTime || modifiedTime)) {
metadata.openGraph = {
...metadata.openGraph,
type: 'article',
publishedTime,
modifiedTime,
authors: [author || SITE_CONFIG.name],
};
}
return metadata;
}
// Service-specific metadata generator
export function generateServiceMetadata(service: {
title: string;
description: string;
short_description?: string;
slug: string;
category?: { name: string };
technologies?: string;
duration?: string;
}) {
const keywords = [
service.title,
`${service.title} Services`,
service.category?.name || 'Enterprise Services',
'Custom Development',
'Enterprise Solutions',
];
if (service.technologies) {
const techs = service.technologies.split(',').map((t) => t.trim());
keywords.push(...techs);
}
return generateMetadata({
title: service.title,
description: service.short_description || service.description,
keywords,
url: `/services/${service.slug}`,
type: 'service' as any,
});
}
// Blog-specific metadata generator
export function generateBlogMetadata(post: {
title: string;
description?: string;
excerpt?: string;
slug: string;
image?: string;
published_at?: string;
updated_at?: string;
author?: { name: string };
category?: { name: string };
tags?: string[];
}) {
const keywords = [
post.category?.name || 'Technology',
'Blog',
'Tech Insights',
...(post.tags || []),
];
return generateMetadata({
title: post.title,
description: post.description || post.excerpt,
keywords,
image: post.image,
url: `/insights/${post.slug}`,
type: 'article',
publishedTime: post.published_at,
modifiedTime: post.updated_at,
author: post.author?.name,
});
}
// Case Study metadata generator
export function generateCaseStudyMetadata(caseStudy: {
title: string;
description?: string;
excerpt?: string;
slug: string;
image?: string;
client_name?: string;
industry?: string;
technologies?: string;
}) {
const keywords = [
'Case Study',
caseStudy.client_name || '',
caseStudy.industry || '',
'Success Story',
'Client Project',
];
if (caseStudy.technologies) {
const techs = caseStudy.technologies.split(',').map((t) => t.trim());
keywords.push(...techs);
}
return generateMetadata({
title: caseStudy.title,
description: caseStudy.description || caseStudy.excerpt,
keywords: keywords.filter(Boolean),
image: caseStudy.image,
url: `/case-study/${caseStudy.slug}`,
type: 'article',
});
}
// Career metadata generator
export function generateCareerMetadata(job: {
title: string;
description?: string;
slug: string;
location?: string;
department?: string;
employment_type?: string;
}) {
const keywords = [
job.title,
'Career',
'Job Opening',
job.department || '',
job.location || '',
job.employment_type || '',
'Join Our Team',
].filter(Boolean);
return generateMetadata({
title: `${job.title} - Careers`,
description: job.description,
keywords,
url: `/career/${job.slug}`,
});
}

View File

@@ -33,11 +33,133 @@ const nextConfig = {
// pathname: '/media/**',
// },
],
formats: ['image/avif', 'image/webp'],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
minimumCacheTTL: 60,
},
sassOptions: {
includePaths: ['./public/styles', './node_modules'],
quietDeps: true, // Suppress deprecation warnings from dependencies
},
// Compiler optimizations
compiler: {
removeConsole: process.env.NODE_ENV === 'production' ? {
exclude: ['error', 'warn'],
} : false,
},
// Compression
compress: true,
// Production optimizations
productionBrowserSourceMaps: false,
// Performance optimizations (swcMinify removed - default in Next.js 15)
// Enterprise Security Headers
async headers() {
return [
{
source: '/:path*',
headers: [
// Security Headers
{
key: 'X-DNS-Prefetch-Control',
value: 'on'
},
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
},
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN'
},
{
key: 'X-Content-Type-Options',
value: 'nosniff'
},
{
key: 'X-XSS-Protection',
value: '1; mode=block'
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin'
},
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=(), interest-cohort=()'
},
{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline' https://www.googletagmanager.com https://www.google-analytics.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https: http://localhost:8000 http://localhost:8080; font-src 'self' data:; connect-src 'self' http://localhost:8000 https://www.google-analytics.com; frame-src 'self' https://www.google.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'"
},
// Performance Headers
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable'
},
],
},
// Static assets caching
{
source: '/images/:path*',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable',
},
],
},
{
source: '/icons/:path*',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable',
},
],
},
// API responses - no cache for dynamic content
{
source: '/api/:path*',
headers: [
{
key: 'Cache-Control',
value: 'no-store, must-revalidate',
},
],
},
]
},
// Redirects for SEO
async redirects() {
return [
// Redirect trailing slashes
{
source: '/:path+/',
destination: '/:path+',
permanent: true,
},
]
},
// Rewrites for API proxy (Production: routes /api to backend through nginx)
async rewrites() {
// In development, proxy to Django backend
// In production, nginx handles this
if (process.env.NODE_ENV === 'development') {
return [
{
source: '/api/:path*',
destination: `${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'}/api/:path*`,
},
{
source: '/media/:path*',
destination: `${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'}/media/:path*`,
},
]
}
// In production, these are handled by nginx reverse proxy
return []
},
}
module.exports = nextConfig

View File

@@ -99,12 +99,22 @@ export const OffcanvasData = [
},
{
id: 11,
title: "Contact Us",
path: "/contact-us",
title: "Support Center",
path: "/support-center",
parent_id: null,
display_order: 7,
submenu: null,
created_at: "2024-01-01T00:00:00Z",
updated_at: "2024-01-01T00:00:00Z"
},
{
id: 12,
title: "Contact Us",
path: "/contact-us",
parent_id: null,
display_order: 8,
submenu: null,
created_at: "2024-01-01T00:00:00Z",
updated_at: "2024-01-01T00:00:00Z"
}
];

View File

@@ -36,6 +36,7 @@
// modern CSS framework (Bootstrap replacement)
@use "./utilities/modern-framework";
@use "./utilities/content-protection";
/* ==============
========= css table of contents =========

View File

@@ -0,0 +1,123 @@
// ============================================================================
// Content Protection Styles
// ============================================================================
// Prevents content copying, text selection, and image downloading
// Disable text selection globally
.content-protected {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
// Prevent tap highlight on mobile
-webkit-tap-highlight-color: transparent;
// Disable image dragging
img {
-webkit-user-drag: none;
-khtml-user-drag: none;
-moz-user-drag: none;
-o-user-drag: none;
user-drag: none;
pointer-events: none;
}
// Protect all text content
* {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
}
// Allow selection for input fields and textareas
.content-protected input,
.content-protected textarea,
.content-protected [contenteditable="true"] {
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
// Image protection with overlay
.protected-image-wrapper {
position: relative;
display: inline-block;
img {
display: block;
-webkit-user-drag: none;
-khtml-user-drag: none;
-moz-user-drag: none;
-o-user-drag: none;
user-drag: none;
pointer-events: none;
}
// Transparent overlay to prevent right-click on images
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: transparent;
pointer-events: auto;
z-index: 1;
}
}
// Watermark overlay (optional - can be enabled per image)
.watermarked-image {
position: relative;
&::before {
content: 'GNX Soft';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
font-size: 3rem;
font-weight: bold;
color: rgba(255, 255, 255, 0.15);
pointer-events: none;
z-index: 2;
white-space: nowrap;
}
}
// Hide on print (prevent print screen)
@media print {
.no-print {
display: none !important;
}
body::after {
content: 'This content is protected and cannot be printed. Visit gnxsoft.com';
display: block;
text-align: center;
padding: 50px;
font-size: 20px;
}
}
// Additional protection for code blocks
.content-protected pre,
.content-protected code {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
// Blur content when dev tools are open (optional)
.devtools-open {
filter: blur(5px);
pointer-events: none;
}

View File

@@ -3,7 +3,6 @@ djangorestframework==3.14.0
django-cors-headers==4.3.1
python-decouple==3.8
Pillow==10.1.0
psycopg2-binary==2.9.9
celery==5.3.4
redis==5.0.1
django-environ==0.11.2