robottxt
This commit is contained in:
49
package-lock.json
generated
49
package-lock.json
generated
@@ -8,6 +8,8 @@
|
||||
"name": "my-app",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@emailjs/browser": "^4.4.1",
|
||||
"@vercel/analytics": "^1.6.1",
|
||||
"next": "16.0.10",
|
||||
"react": "19.2.1",
|
||||
"react-dom": "19.2.1"
|
||||
@@ -276,6 +278,15 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emailjs/browser": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@emailjs/browser/-/browser-4.4.1.tgz",
|
||||
"integrity": "sha512-DGSlP9sPvyFba3to2A50kDtZ+pXVp/0rhmqs2LmbMS3I5J8FSOgLwzY2Xb4qfKlOVHh29EAutLYwe5yuEZmEFg==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz",
|
||||
@@ -2113,6 +2124,44 @@
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@vercel/analytics": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.6.1.tgz",
|
||||
"integrity": "sha512-oH9He/bEM+6oKlv3chWuOOcp8Y6fo6/PSro8hEkgCW3pu9/OiCXiUpRUogDh3Fs3LH2sosDrx8CxeOLBEE+afg==",
|
||||
"license": "MPL-2.0",
|
||||
"peerDependencies": {
|
||||
"@remix-run/react": "^2",
|
||||
"@sveltejs/kit": "^1 || ^2",
|
||||
"next": ">= 13",
|
||||
"react": "^18 || ^19 || ^19.0.0-rc",
|
||||
"svelte": ">= 4",
|
||||
"vue": "^3",
|
||||
"vue-router": "^4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@remix-run/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@sveltejs/kit": {
|
||||
"optional": true
|
||||
},
|
||||
"next": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"svelte": {
|
||||
"optional": true
|
||||
},
|
||||
"vue": {
|
||||
"optional": true
|
||||
},
|
||||
"vue-router": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
"lint": "eslint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emailjs/browser": "^4.4.1",
|
||||
"@vercel/analytics": "^1.6.1",
|
||||
"next": "16.0.10",
|
||||
"react": "19.2.1",
|
||||
"react-dom": "19.2.1"
|
||||
|
||||
11
public/robots.txt
Normal file
11
public/robots.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
# Sitemap
|
||||
Sitemap: https://zerosixlab.com/sitemap.xml
|
||||
|
||||
# Disallow admin/private areas
|
||||
Disallow: /api/
|
||||
Disallow: /_next/
|
||||
Disallow: /static/
|
||||
@@ -105,3 +105,56 @@ body {
|
||||
z-index: 9999;
|
||||
opacity: 0.15;
|
||||
}
|
||||
|
||||
/* Accessibility: Reduce motion for users who prefer it */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
|
||||
.scanlines {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.animate-pulse,
|
||||
.animate-spin,
|
||||
.animate-bounce {
|
||||
animation: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip to main content link for keyboard users */
|
||||
.skip-link {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: 0;
|
||||
background: var(--zsl-primary);
|
||||
color: black;
|
||||
padding: 8px 16px;
|
||||
z-index: 10000;
|
||||
font-weight: bold;
|
||||
transition: top 0.3s;
|
||||
}
|
||||
|
||||
.skip-link:focus {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
/* Focus visible styles for better keyboard navigation */
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--zsl-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Better button and link focus states */
|
||||
button:focus-visible,
|
||||
a:focus-visible {
|
||||
outline: 2px solid var(--zsl-primary);
|
||||
outline-offset: 2px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import { Inter, Orbitron } from "next/font/google";
|
||||
import { Analytics } from '@vercel/analytics/next';
|
||||
import React from 'react';
|
||||
import "./globals.css";
|
||||
|
||||
@@ -13,6 +14,7 @@ export const viewport: Viewport = {
|
||||
};
|
||||
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL('https://zerosixlab.com'),
|
||||
title: {
|
||||
default: "ZeroSixLab - Geleceği Kodlayan Laboratuvar",
|
||||
template: "%s | ZeroSixLab"
|
||||
@@ -90,7 +92,13 @@ export default function RootLayout({
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
||||
</head>
|
||||
<body className={`${inter.variable} ${orbitron.variable} font-sans bg-zsl-bg text-zsl-text`}>
|
||||
{children}
|
||||
<a href="#main-content" className="skip-link">
|
||||
Ana içeriğe atla
|
||||
</a>
|
||||
<main id="main-content">
|
||||
{children}
|
||||
</main>
|
||||
<Analytics />
|
||||
<div className="scanlines"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,24 +1,38 @@
|
||||
"use client";
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
|
||||
// Static positions for floating elements to avoid hydration mismatch
|
||||
const FLOATING_POSITIONS = [
|
||||
{ left: '10%', top: '15%', delay: '0s' },
|
||||
{ left: '25%', top: '45%', delay: '0.3s' },
|
||||
{ left: '45%', top: '75%', delay: '0.6s' },
|
||||
{ left: '65%', top: '25%', delay: '0.9s' },
|
||||
{ left: '80%', top: '55%', delay: '1.2s' },
|
||||
{ left: '15%', top: '85%', delay: '1.5s' },
|
||||
{ left: '55%', top: '10%', delay: '1.8s' },
|
||||
{ left: '90%', top: '35%', delay: '0.2s' },
|
||||
{ left: '35%', top: '65%', delay: '0.5s' },
|
||||
{ left: '75%', top: '90%', delay: '0.8s' },
|
||||
];
|
||||
|
||||
export default function NotFound() {
|
||||
return (
|
||||
<div className="min-h-screen bg-zsl-bg flex flex-col items-center justify-center p-6 relative overflow-hidden">
|
||||
<div className="min-h-screen bg-[#0a0f1a] flex flex-col items-center justify-center p-6 relative overflow-hidden">
|
||||
{/* Background Grid */}
|
||||
<div className="absolute inset-0 cyber-grid opacity-10"></div>
|
||||
|
||||
{/* Floating elements */}
|
||||
<div className="absolute inset-0 overflow-hidden pointer-events-none">
|
||||
{[...Array(10)].map((_, i) => (
|
||||
{FLOATING_POSITIONS.map((pos, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="absolute w-2 h-2 bg-zsl-primary/30 rounded-full animate-pulse"
|
||||
style={{
|
||||
left: `${Math.random() * 100}%`,
|
||||
top: `${Math.random() * 100}%`,
|
||||
animationDelay: `${Math.random() * 2}s`,
|
||||
left: pos.left,
|
||||
top: pos.top,
|
||||
animationDelay: pos.delay,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
@@ -58,7 +72,7 @@ export default function NotFound() {
|
||||
<span className="ml-2 text-zsl-muted text-xs">terminal</span>
|
||||
</div>
|
||||
<div className="space-y-1 text-zsl-muted">
|
||||
<div><span className="text-zsl-primary">$</span> find /page --name "{typeof window !== 'undefined' ? window.location.pathname : '/unknown'}"</div>
|
||||
<div><span className="text-zsl-primary">$</span> find /page --name "/unknown"</div>
|
||||
<div className="text-red-400">Error: Page not found</div>
|
||||
<div><span className="text-zsl-primary">$</span> suggest --redirect home</div>
|
||||
<div className="text-zsl-accent">Suggestion: Return to homepage</div>
|
||||
@@ -93,7 +107,6 @@ export default function NotFound() {
|
||||
<div className="text-xs font-mono text-zsl-muted/30">
|
||||
<div>STATUS: 404</div>
|
||||
<div>LOCATION: UNKNOWN</div>
|
||||
<div>TIME: {new Date().toISOString()}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
111
src/app/page.tsx
111
src/app/page.tsx
@@ -17,6 +17,15 @@ import { CookieBanner } from '@/components/CookieBanner';
|
||||
import { ProjectModal } from '@/components/ProjectModal';
|
||||
import { NavPage } from '@/types';
|
||||
|
||||
// Social Links
|
||||
const socialLinks = {
|
||||
github: "https://github.com/zerosixlab",
|
||||
discord: "https://discord.gg/zerosixlab",
|
||||
twitter: "https://twitter.com/zerosixlab",
|
||||
linkedin: "https://linkedin.com/company/zerosixlab",
|
||||
instagram: "https://instagram.com/zerosixlab"
|
||||
};
|
||||
|
||||
// Data
|
||||
const testimonials = [
|
||||
{
|
||||
@@ -720,7 +729,7 @@ export default function Home() {
|
||||
<AnimatedCounter
|
||||
end={30}
|
||||
suffix="+"
|
||||
title="Mutlu Müşteri"
|
||||
title="İş Ortağı"
|
||||
icon={<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" /></svg>}
|
||||
/>
|
||||
<AnimatedCounter
|
||||
@@ -732,7 +741,7 @@ export default function Home() {
|
||||
<AnimatedCounter
|
||||
end={99}
|
||||
suffix="%"
|
||||
title="Müşteri Memnuniyeti"
|
||||
title="Proje Başarı Oranı"
|
||||
icon={<svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" /></svg>}
|
||||
/>
|
||||
</div>
|
||||
@@ -783,8 +792,8 @@ export default function Home() {
|
||||
<ScrollAnimation animation="fade-up" delay={200}>
|
||||
<div className="max-w-7xl mx-auto px-4 mt-32">
|
||||
<div className="text-center mb-12">
|
||||
<span className="inline-block px-3 py-1 bg-white/5 rounded border border-white/10 text-xs font-mono tracking-widest text-zsl-accent mb-4">MÜŞTERİ YORUMLARI</span>
|
||||
<h2 className="text-3xl md:text-4xl font-mono font-bold text-white">Müşterilerimiz Ne Diyor?</h2>
|
||||
<span className="inline-block px-3 py-1 bg-white/5 rounded border border-white/10 text-xs font-mono tracking-widest text-zsl-accent mb-4">REFERANSLAR</span>
|
||||
<h2 className="text-3xl md:text-4xl font-mono font-bold text-white">İş Ortaklarımız Ne Diyor?</h2>
|
||||
</div>
|
||||
<TestimonialSlider testimonials={testimonials} />
|
||||
</div>
|
||||
@@ -910,28 +919,84 @@ export default function Home() {
|
||||
</main>
|
||||
|
||||
{/* Footer */}
|
||||
<footer className="border-t border-white/5 bg-[#050B14] py-12 mt-20 relative overflow-hidden z-10">
|
||||
<footer className="border-t border-white/5 bg-[#050B14] py-16 mt-20 relative overflow-hidden z-10">
|
||||
<div className="absolute inset-0 cyber-grid opacity-10"></div>
|
||||
<div className="max-w-7xl mx-auto px-4 flex flex-col md:flex-row justify-between items-center gap-6 relative z-10">
|
||||
<div className="flex flex-col items-center md:items-start gap-2">
|
||||
<Logo size="sm" />
|
||||
<p className="font-mono text-slate-500 text-xs mt-2 text-center md:text-left">
|
||||
© 2024 ZeroSixLab. Tüm Hakları Saklıdır.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-6">
|
||||
{['Twitter', 'LinkedIn', 'GitHub'].map((social) => (
|
||||
<a key={social} href="#" className="text-slate-500 hover:text-zsl-primary transition-colors font-mono text-sm uppercase tracking-wider hover:underline decoration-zsl-primary underline-offset-4">{social}</a>
|
||||
))}
|
||||
<div className="max-w-7xl mx-auto px-4 relative z-10">
|
||||
{/* Main Footer Content */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-12 mb-12">
|
||||
{/* Brand */}
|
||||
<div className="md:col-span-1">
|
||||
<Logo size="sm" />
|
||||
<p className="font-mono text-slate-500 text-sm mt-4 leading-relaxed">
|
||||
Ankara merkezli, global vizyonlu yeni nesil yazılım ve Ar-Ge laboratuvarı.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Quick Links */}
|
||||
<div>
|
||||
<h4 className="font-mono text-white font-bold mb-4 text-sm uppercase tracking-wider">Keşfet</h4>
|
||||
<ul className="space-y-2">
|
||||
{[
|
||||
{ label: 'Ana Sayfa', page: NavPage.HOME },
|
||||
{ label: 'Çözümler', page: NavPage.SERVICES },
|
||||
{ label: 'Projeler', page: NavPage.PROJECTS },
|
||||
{ label: 'Hakkımızda', page: NavPage.ABOUT },
|
||||
].map((item) => (
|
||||
<li key={item.label}>
|
||||
<button onClick={() => handleNavClick(item.page)} className="text-slate-500 hover:text-zsl-primary transition-colors text-sm">{item.label}</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Services */}
|
||||
<div>
|
||||
<h4 className="font-mono text-white font-bold mb-4 text-sm uppercase tracking-wider">Hizmetler</h4>
|
||||
<ul className="space-y-2 text-sm text-slate-500">
|
||||
<li>Web Geliştirme</li>
|
||||
<li>Mobil Uygulama</li>
|
||||
<li>Yapay Zeka Çözümleri</li>
|
||||
<li>Blockchain & Web3</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Contact & Social */}
|
||||
<div>
|
||||
<h4 className="font-mono text-white font-bold mb-4 text-sm uppercase tracking-wider">Bize Ulaşın</h4>
|
||||
<p className="text-slate-500 text-sm mb-4">info@zerosixlab.com</p>
|
||||
<div className="flex gap-3">
|
||||
<a href={socialLinks.github} target="_blank" rel="noopener noreferrer" className="w-10 h-10 rounded-lg bg-white/5 border border-white/10 flex items-center justify-center text-slate-500 hover:text-zsl-primary hover:border-zsl-primary/50 transition-all">
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" /></svg>
|
||||
</a>
|
||||
<a href={socialLinks.discord} target="_blank" rel="noopener noreferrer" className="w-10 h-10 rounded-lg bg-white/5 border border-white/10 flex items-center justify-center text-slate-500 hover:text-zsl-primary hover:border-zsl-primary/50 transition-all">
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/></svg>
|
||||
</a>
|
||||
<a href={socialLinks.twitter} target="_blank" rel="noopener noreferrer" className="w-10 h-10 rounded-lg bg-white/5 border border-white/10 flex items-center justify-center text-slate-500 hover:text-zsl-primary hover:border-zsl-primary/50 transition-all">
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
|
||||
</a>
|
||||
<a href={socialLinks.linkedin} target="_blank" rel="noopener noreferrer" className="w-10 h-10 rounded-lg bg-white/5 border border-white/10 flex items-center justify-center text-slate-500 hover:text-zsl-primary hover:border-zsl-primary/50 transition-all">
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>
|
||||
</a>
|
||||
<a href={socialLinks.instagram} target="_blank" rel="noopener noreferrer" className="w-10 h-10 rounded-lg bg-white/5 border border-white/10 flex items-center justify-center text-slate-500 hover:text-zsl-primary hover:border-zsl-primary/50 transition-all">
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4 border border-white/10 px-4 py-2 rounded bg-black/40">
|
||||
<div className="text-right hidden md:block">
|
||||
<div className="text-[10px] text-slate-500 font-mono uppercase tracking-widest">SYSTEM STATUS</div>
|
||||
<div className="text-xs text-green-400 font-mono tracking-wider font-bold">ALL SYSTEMS OPERATIONAL</div>
|
||||
</div>
|
||||
<div className="w-2 h-2 rounded-full bg-green-500 shadow-[0_0_10px_#00ff00] animate-pulse"></div>
|
||||
{/* Bottom Bar */}
|
||||
<div className="pt-8 border-t border-white/5 flex flex-col md:flex-row justify-between items-center gap-4">
|
||||
<p className="font-mono text-slate-500 text-xs text-center md:text-left">
|
||||
© 2024 ZeroSixLab. Tüm Hakları Saklıdır.
|
||||
</p>
|
||||
|
||||
<div className="flex items-center gap-4 border border-white/10 px-4 py-2 rounded bg-black/40">
|
||||
<div className="text-right hidden md:block">
|
||||
<div className="text-[10px] text-slate-500 font-mono uppercase tracking-widest">SYSTEM STATUS</div>
|
||||
<div className="text-xs text-green-400 font-mono tracking-wider font-bold">ALL SYSTEMS OPERATIONAL</div>
|
||||
</div>
|
||||
<div className="w-2 h-2 rounded-full bg-green-500 shadow-[0_0_10px_#00ff00] animate-pulse"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
303
src/app/projects/[slug]/ProjectDetailClient.tsx
Normal file
303
src/app/projects/[slug]/ProjectDetailClient.tsx
Normal file
@@ -0,0 +1,303 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Project } from '@/data/projects';
|
||||
import { Logo } from '@/components/Logo';
|
||||
import { CustomCursor } from '@/components/CustomCursor';
|
||||
import { ParticleBackground } from '@/components/ParticleBackground';
|
||||
import { ScrollToTop } from '@/components/ScrollToTop';
|
||||
|
||||
interface Props {
|
||||
project: Project;
|
||||
allProjects: Project[];
|
||||
}
|
||||
|
||||
export default function ProjectDetailClient({ project, allProjects }: Props) {
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoaded(true);
|
||||
}, []);
|
||||
|
||||
const otherProjects = allProjects.filter(p => p.id !== project.id).slice(0, 3);
|
||||
|
||||
const statusColors = {
|
||||
'Tamamlandı': 'bg-green-500/20 text-green-400 border-green-500/30',
|
||||
'Devam Ediyor': 'bg-yellow-500/20 text-yellow-400 border-yellow-500/30',
|
||||
'Bakımda': 'bg-blue-500/20 text-blue-400 border-blue-500/30'
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#0a0f1a] text-white">
|
||||
<CustomCursor />
|
||||
<ParticleBackground />
|
||||
<ScrollToTop />
|
||||
|
||||
{/* Header */}
|
||||
<header className="fixed top-0 left-0 right-0 z-50 bg-[#0a0f1a]/80 backdrop-blur-xl border-b border-white/5">
|
||||
<div className="max-w-7xl mx-auto px-4 py-4 flex items-center justify-between">
|
||||
<Link href="/" className="hover:opacity-80 transition-opacity">
|
||||
<Logo size="sm" />
|
||||
</Link>
|
||||
<Link
|
||||
href="/#projects"
|
||||
className="flex items-center gap-2 text-slate-400 hover:text-white transition-colors font-mono text-sm"
|
||||
>
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
Tüm Projeler
|
||||
</Link>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Main Content */}
|
||||
<main className={`pt-24 pb-20 transition-all duration-700 ${isLoaded ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-10'}`}>
|
||||
<div className="max-w-6xl mx-auto px-4">
|
||||
|
||||
{/* Hero Section */}
|
||||
<div className="mb-16">
|
||||
<div className="flex flex-wrap items-center gap-3 mb-6">
|
||||
<span className="px-3 py-1 bg-zsl-primary/20 text-zsl-primary border border-zsl-primary/30 rounded text-xs font-mono uppercase tracking-wider">
|
||||
{project.category}
|
||||
</span>
|
||||
<span className={`px-3 py-1 border rounded text-xs font-mono ${statusColors[project.status]}`}>
|
||||
{project.status}
|
||||
</span>
|
||||
<span className="text-slate-500 text-sm font-mono">{project.year}</span>
|
||||
</div>
|
||||
|
||||
<h1 className="text-4xl md:text-6xl font-mono font-bold text-white mb-6 tracking-tight">
|
||||
{project.title}
|
||||
</h1>
|
||||
|
||||
<p className="text-xl text-slate-400 font-mono leading-relaxed max-w-3xl">
|
||||
{project.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Project Image */}
|
||||
<div className="relative aspect-video rounded-2xl overflow-hidden mb-16 bg-linear-to-br from-zsl-primary/20 to-purple-500/20 border border-white/10">
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<div className="w-24 h-24 mx-auto mb-4 rounded-2xl bg-linear-to-br from-zsl-primary to-purple-500 flex items-center justify-center text-4xl">
|
||||
{project.category === 'Yapay Zeka' && '🤖'}
|
||||
{project.category === 'Blockchain' && '⛓️'}
|
||||
{project.category === 'Cloud' && '☁️'}
|
||||
{project.category === 'Güvenlik' && '🛡️'}
|
||||
{project.category === 'Big Data' && '📊'}
|
||||
{project.category === 'IoT' && '📡'}
|
||||
</div>
|
||||
<span className="font-mono text-white/60 text-sm">Proje Görseli</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute inset-0 cyber-grid opacity-20"></div>
|
||||
</div>
|
||||
|
||||
{/* Content Grid */}
|
||||
<div className="grid md:grid-cols-3 gap-12">
|
||||
|
||||
{/* Main Content */}
|
||||
<div className="md:col-span-2 space-y-12">
|
||||
|
||||
{/* Description */}
|
||||
<section>
|
||||
<h2 className="text-2xl font-mono font-bold text-white mb-6 flex items-center gap-3">
|
||||
<span className="w-8 h-8 rounded bg-zsl-primary/20 flex items-center justify-center text-zsl-primary text-sm">01</span>
|
||||
Proje Hakkında
|
||||
</h2>
|
||||
<div className="prose prose-invert max-w-none">
|
||||
{project.longDescription.split('\n\n').map((paragraph, index) => (
|
||||
<p key={index} className="text-slate-400 font-mono leading-relaxed mb-4">
|
||||
{paragraph}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Features */}
|
||||
<section>
|
||||
<h2 className="text-2xl font-mono font-bold text-white mb-6 flex items-center gap-3">
|
||||
<span className="w-8 h-8 rounded bg-zsl-primary/20 flex items-center justify-center text-zsl-primary text-sm">02</span>
|
||||
Özellikler
|
||||
</h2>
|
||||
<div className="grid sm:grid-cols-2 gap-4">
|
||||
{project.features.map((feature, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-start gap-3 p-4 bg-white/5 border border-white/10 rounded-lg hover:border-zsl-primary/30 transition-colors"
|
||||
>
|
||||
<svg className="w-5 h-5 text-zsl-primary shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
<span className="text-slate-300 font-mono text-sm">{feature}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Technologies */}
|
||||
<section>
|
||||
<h2 className="text-2xl font-mono font-bold text-white mb-6 flex items-center gap-3">
|
||||
<span className="w-8 h-8 rounded bg-zsl-primary/20 flex items-center justify-center text-zsl-primary text-sm">03</span>
|
||||
Teknolojiler
|
||||
</h2>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{project.technologies.map((tech, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="px-4 py-2 bg-white/5 border border-white/10 rounded-lg text-sm font-mono text-slate-300 hover:border-zsl-primary/50 hover:text-zsl-primary transition-colors cursor-default"
|
||||
>
|
||||
{tech}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{/* Sidebar */}
|
||||
<div className="space-y-6">
|
||||
|
||||
{/* Project Info Card */}
|
||||
<div className="bg-white/5 border border-white/10 rounded-xl p-6 sticky top-24">
|
||||
<h3 className="font-mono font-bold text-white mb-6">Proje Detayları</h3>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center py-3 border-b border-white/5">
|
||||
<span className="text-slate-500 font-mono text-sm">Durum</span>
|
||||
<span className={`px-2 py-1 border rounded text-xs font-mono ${statusColors[project.status]}`}>
|
||||
{project.status}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between items-center py-3 border-b border-white/5">
|
||||
<span className="text-slate-500 font-mono text-sm">Yıl</span>
|
||||
<span className="text-white font-mono text-sm">{project.year}</span>
|
||||
</div>
|
||||
|
||||
{project.duration && (
|
||||
<div className="flex justify-between items-center py-3 border-b border-white/5">
|
||||
<span className="text-slate-500 font-mono text-sm">Süre</span>
|
||||
<span className="text-white font-mono text-sm">{project.duration}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{project.client && (
|
||||
<div className="flex justify-between items-center py-3 border-b border-white/5">
|
||||
<span className="text-slate-500 font-mono text-sm">İş Ortağı</span>
|
||||
<span className="text-white font-mono text-sm">{project.client}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex justify-between items-center py-3">
|
||||
<span className="text-slate-500 font-mono text-sm">Kategori</span>
|
||||
<span className="text-zsl-primary font-mono text-sm">{project.category}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<div className="mt-6 space-y-3">
|
||||
{project.link && (
|
||||
<a
|
||||
href={project.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center gap-2 w-full py-3 bg-linear-to-r from-zsl-primary to-cyan-400 text-black font-mono font-bold rounded-lg hover:shadow-[0_0_20px_rgba(0,212,255,0.4)] transition-all"
|
||||
>
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||||
</svg>
|
||||
Demo İncele
|
||||
</a>
|
||||
)}
|
||||
|
||||
{project.github && (
|
||||
<a
|
||||
href={project.github}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center gap-2 w-full py-3 border border-white/20 text-white font-mono rounded-lg hover:border-zsl-primary/50 hover:text-zsl-primary transition-all"
|
||||
>
|
||||
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
|
||||
</svg>
|
||||
GitHub
|
||||
</a>
|
||||
)}
|
||||
|
||||
<Link
|
||||
href="/#contact"
|
||||
className="flex items-center justify-center gap-2 w-full py-3 border border-white/20 text-white font-mono rounded-lg hover:border-zsl-accent/50 hover:text-zsl-accent transition-all"
|
||||
>
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
|
||||
</svg>
|
||||
Benzer Proje İste
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Tags */}
|
||||
<div className="mt-6 pt-6 border-t border-white/10">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{project.tags.map((tag, index) => (
|
||||
<span key={index} className="px-2 py-1 bg-white/5 text-slate-500 text-xs font-mono rounded">
|
||||
#{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Other Projects */}
|
||||
<section className="mt-24">
|
||||
<h2 className="text-2xl font-mono font-bold text-white mb-8">Diğer Projeler</h2>
|
||||
<div className="grid md:grid-cols-3 gap-6">
|
||||
{otherProjects.map((p) => (
|
||||
<Link
|
||||
key={p.id}
|
||||
href={`/projects/${p.slug}`}
|
||||
className="group bg-white/5 border border-white/10 rounded-xl overflow-hidden hover:border-zsl-primary/50 transition-all duration-300"
|
||||
>
|
||||
<div className="aspect-video bg-linear-to-br from-zsl-primary/10 to-purple-500/10 flex items-center justify-center">
|
||||
<span className="text-4xl">
|
||||
{p.category === 'Yapay Zeka' && '🤖'}
|
||||
{p.category === 'Blockchain' && '⛓️'}
|
||||
{p.category === 'Cloud' && '☁️'}
|
||||
{p.category === 'Güvenlik' && '🛡️'}
|
||||
{p.category === 'Big Data' && '📊'}
|
||||
{p.category === 'IoT' && '📡'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<span className="text-xs font-mono text-zsl-primary">{p.category}</span>
|
||||
<h3 className="font-mono font-bold text-white mt-1 group-hover:text-zsl-primary transition-colors">
|
||||
{p.title}
|
||||
</h3>
|
||||
<p className="text-sm text-slate-500 font-mono mt-2 line-clamp-2">
|
||||
{p.description}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{/* Footer */}
|
||||
<footer className="border-t border-white/5 bg-[#050B14] py-8">
|
||||
<div className="max-w-6xl mx-auto px-4 flex flex-col md:flex-row justify-between items-center gap-4">
|
||||
<Link href="/" className="hover:opacity-80 transition-opacity">
|
||||
<Logo size="sm" />
|
||||
</Link>
|
||||
<p className="font-mono text-slate-500 text-xs">
|
||||
© 2024 ZeroSixLab. Tüm Hakları Saklıdır.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
46
src/app/projects/[slug]/page.tsx
Normal file
46
src/app/projects/[slug]/page.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { Metadata } from 'next';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { getProjectBySlug, getAllProjectSlugs, projects } from '@/data/projects';
|
||||
import ProjectDetailClient from './ProjectDetailClient';
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ slug: string }>;
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return getAllProjectSlugs().map((slug) => ({
|
||||
slug,
|
||||
}));
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const project = getProjectBySlug(slug);
|
||||
|
||||
if (!project) {
|
||||
return {
|
||||
title: 'Proje Bulunamadı | ZeroSixLab',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
title: `${project.title} | ZeroSixLab`,
|
||||
description: project.description,
|
||||
openGraph: {
|
||||
title: `${project.title} | ZeroSixLab`,
|
||||
description: project.description,
|
||||
images: [project.image],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function ProjectPage({ params }: Props) {
|
||||
const { slug } = await params;
|
||||
const project = getProjectBySlug(slug);
|
||||
|
||||
if (!project) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
return <ProjectDetailClient project={project} allProjects={projects} />;
|
||||
}
|
||||
58
src/app/sitemap.ts
Normal file
58
src/app/sitemap.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { MetadataRoute } from 'next'
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
const baseUrl = 'https://zerosixlab.com'
|
||||
|
||||
// Static pages
|
||||
const staticPages = [
|
||||
{
|
||||
url: baseUrl,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: 'weekly' as const,
|
||||
priority: 1,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/#services`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: 'monthly' as const,
|
||||
priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/#projects`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: 'weekly' as const,
|
||||
priority: 0.9,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/#about`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: 'monthly' as const,
|
||||
priority: 0.7,
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/#contact`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: 'monthly' as const,
|
||||
priority: 0.8,
|
||||
},
|
||||
]
|
||||
|
||||
// Project pages
|
||||
const projects = [
|
||||
'aurora-ai',
|
||||
'quantumledger',
|
||||
'nexuscloud',
|
||||
'cyberguard',
|
||||
'dataforge',
|
||||
'smartcity'
|
||||
]
|
||||
|
||||
const projectPages = projects.map((slug) => ({
|
||||
url: `${baseUrl}/projects/${slug}`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: 'monthly' as const,
|
||||
priority: 0.6,
|
||||
}))
|
||||
|
||||
return [...staticPages, ...projectPages]
|
||||
}
|
||||
225
src/components/ContactForm.tsx
Normal file
225
src/components/ContactForm.tsx
Normal file
@@ -0,0 +1,225 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useRef, FormEvent } from 'react';
|
||||
|
||||
// EmailJS configuration - Replace with your actual IDs
|
||||
const EMAILJS_SERVICE_ID = 'YOUR_SERVICE_ID';
|
||||
const EMAILJS_TEMPLATE_ID = 'YOUR_TEMPLATE_ID';
|
||||
const EMAILJS_PUBLIC_KEY = 'YOUR_PUBLIC_KEY';
|
||||
|
||||
interface ContactFormData {
|
||||
name: string;
|
||||
email: string;
|
||||
subject: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
interface FormStatus {
|
||||
type: 'idle' | 'loading' | 'success' | 'error';
|
||||
message: string;
|
||||
}
|
||||
|
||||
export default function ContactForm() {
|
||||
const formRef = useRef<HTMLFormElement>(null);
|
||||
const [formData, setFormData] = useState<ContactFormData>({
|
||||
name: '',
|
||||
email: '',
|
||||
subject: '',
|
||||
message: ''
|
||||
});
|
||||
const [status, setStatus] = useState<FormStatus>({ type: 'idle', message: '' });
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData(prev => ({ ...prev, [name]: value }));
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
// Validation
|
||||
if (!formData.name || !formData.email || !formData.message) {
|
||||
setStatus({ type: 'error', message: 'Lütfen tüm zorunlu alanları doldurun.' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Email validation
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!emailRegex.test(formData.email)) {
|
||||
setStatus({ type: 'error', message: 'Geçerli bir e-posta adresi girin.' });
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus({ type: 'loading', message: 'Gönderiliyor...' });
|
||||
|
||||
try {
|
||||
// Dynamic import for EmailJS to reduce bundle size
|
||||
const emailjs = await import('@emailjs/browser');
|
||||
|
||||
await emailjs.sendForm(
|
||||
EMAILJS_SERVICE_ID,
|
||||
EMAILJS_TEMPLATE_ID,
|
||||
formRef.current!,
|
||||
EMAILJS_PUBLIC_KEY
|
||||
);
|
||||
|
||||
setStatus({ type: 'success', message: 'Mesajınız başarıyla gönderildi! En kısa sürede dönüş yapacağız.' });
|
||||
setFormData({ name: '', email: '', subject: '', message: '' });
|
||||
} catch (error) {
|
||||
console.error('EmailJS Error:', error);
|
||||
setStatus({
|
||||
type: 'error',
|
||||
message: 'Mesaj gönderilemedi. Lütfen daha sonra tekrar deneyin veya doğrudan e-posta gönderin.'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const subjects = [
|
||||
'Web Geliştirme',
|
||||
'Mobil Uygulama',
|
||||
'Yapay Zeka Çözümleri',
|
||||
'Blockchain & Web3',
|
||||
'Danışmanlık',
|
||||
'Diğer'
|
||||
];
|
||||
|
||||
return (
|
||||
<form ref={formRef} onSubmit={handleSubmit} className="space-y-6">
|
||||
{/* Name Field */}
|
||||
<div>
|
||||
<label htmlFor="name" className="block text-sm font-mono text-slate-400 mb-2">
|
||||
İsim <span className="text-red-400">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
value={formData.name}
|
||||
onChange={handleChange}
|
||||
placeholder="Adınız Soyadınız"
|
||||
className="w-full px-4 py-3 bg-white/5 border border-white/10 rounded-lg text-white placeholder:text-slate-600 focus:outline-none focus:border-zsl-primary/50 focus:ring-1 focus:ring-zsl-primary/50 transition-all font-mono text-sm"
|
||||
disabled={status.type === 'loading'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Email Field */}
|
||||
<div>
|
||||
<label htmlFor="email" className="block text-sm font-mono text-slate-400 mb-2">
|
||||
E-posta <span className="text-red-400">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
value={formData.email}
|
||||
onChange={handleChange}
|
||||
placeholder="ornek@email.com"
|
||||
className="w-full px-4 py-3 bg-white/5 border border-white/10 rounded-lg text-white placeholder:text-slate-600 focus:outline-none focus:border-zsl-primary/50 focus:ring-1 focus:ring-zsl-primary/50 transition-all font-mono text-sm"
|
||||
disabled={status.type === 'loading'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Subject Field */}
|
||||
<div>
|
||||
<label htmlFor="subject" className="block text-sm font-mono text-slate-400 mb-2">
|
||||
Konu
|
||||
</label>
|
||||
<select
|
||||
id="subject"
|
||||
name="subject"
|
||||
value={formData.subject}
|
||||
onChange={handleChange}
|
||||
className="w-full px-4 py-3 bg-white/5 border border-white/10 rounded-lg text-white focus:outline-none focus:border-zsl-primary/50 focus:ring-1 focus:ring-zsl-primary/50 transition-all font-mono text-sm appearance-none cursor-pointer"
|
||||
disabled={status.type === 'loading'}
|
||||
>
|
||||
<option value="" className="bg-[#0a0f1a]">Konu Seçin</option>
|
||||
{subjects.map((subj) => (
|
||||
<option key={subj} value={subj} className="bg-[#0a0f1a]">
|
||||
{subj}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Message Field */}
|
||||
<div>
|
||||
<label htmlFor="message" className="block text-sm font-mono text-slate-400 mb-2">
|
||||
Mesaj <span className="text-red-400">*</span>
|
||||
</label>
|
||||
<textarea
|
||||
id="message"
|
||||
name="message"
|
||||
value={formData.message}
|
||||
onChange={handleChange}
|
||||
placeholder="Projeniz hakkında detayları paylaşın..."
|
||||
rows={5}
|
||||
className="w-full px-4 py-3 bg-white/5 border border-white/10 rounded-lg text-white placeholder:text-slate-600 focus:outline-none focus:border-zsl-primary/50 focus:ring-1 focus:ring-zsl-primary/50 transition-all font-mono text-sm resize-none"
|
||||
disabled={status.type === 'loading'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Status Message */}
|
||||
{status.type !== 'idle' && (
|
||||
<div className={`p-4 rounded-lg border font-mono text-sm ${
|
||||
status.type === 'success'
|
||||
? 'bg-green-500/10 border-green-500/30 text-green-400'
|
||||
: status.type === 'error'
|
||||
? 'bg-red-500/10 border-red-500/30 text-red-400'
|
||||
: 'bg-zsl-primary/10 border-zsl-primary/30 text-zsl-primary'
|
||||
}`}>
|
||||
<div className="flex items-center gap-2">
|
||||
{status.type === 'loading' && (
|
||||
<svg className="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
|
||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
)}
|
||||
{status.type === 'success' && (
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
)}
|
||||
{status.type === 'error' && (
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
)}
|
||||
{status.message}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Submit Button */}
|
||||
<button
|
||||
type="submit"
|
||||
disabled={status.type === 'loading'}
|
||||
className="w-full group relative overflow-hidden bg-linear-to-r from-zsl-primary to-cyan-400 text-black font-mono font-bold py-4 px-6 rounded-lg transition-all duration-300 hover:shadow-[0_0_30px_rgba(0,212,255,0.4)] disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<span className="relative z-10 flex items-center justify-center gap-2">
|
||||
{status.type === 'loading' ? (
|
||||
<>
|
||||
<svg className="w-5 h-5 animate-spin" fill="none" viewBox="0 0 24 24">
|
||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
GÖNDERİLİYOR...
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
MESAJ GÖNDER
|
||||
<svg className="w-5 h-5 group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14 5l7 7m0 0l-7 7m7-7H3" />
|
||||
</svg>
|
||||
</>
|
||||
)}
|
||||
</span>
|
||||
<div className="absolute inset-0 bg-linear-to-r from-cyan-400 to-zsl-primary opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
||||
</button>
|
||||
|
||||
{/* Privacy Note */}
|
||||
<p className="text-xs text-slate-600 font-mono text-center">
|
||||
Formu göndererek <span className="text-slate-500">Gizlilik Politikamızı</span> kabul etmiş olursunuz.
|
||||
</p>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
export const CustomCursor: React.FC = () => {
|
||||
const [position, setPosition] = useState({ x: 0, y: 0 });
|
||||
const cursorRef = useRef<HTMLDivElement>(null);
|
||||
const ringRef = useRef<HTMLDivElement>(null);
|
||||
const [isPointer, setIsPointer] = useState(false);
|
||||
const [isClicking, setIsClicking] = useState(false);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
@@ -13,10 +14,22 @@ export const CustomCursor: React.FC = () => {
|
||||
const hasHover = window.matchMedia('(hover: hover)').matches;
|
||||
if (!hasHover) return;
|
||||
|
||||
let mouseX = 0;
|
||||
let mouseY = 0;
|
||||
let ringX = 0;
|
||||
let ringY = 0;
|
||||
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
setPosition({ x: e.clientX, y: e.clientY });
|
||||
mouseX = e.clientX;
|
||||
mouseY = e.clientY;
|
||||
setIsVisible(true);
|
||||
|
||||
// Instantly move main cursor
|
||||
if (cursorRef.current) {
|
||||
cursorRef.current.style.left = `${mouseX}px`;
|
||||
cursorRef.current.style.top = `${mouseY}px`;
|
||||
}
|
||||
|
||||
const target = e.target as HTMLElement;
|
||||
const isClickable = !!(
|
||||
target.tagName === 'BUTTON' ||
|
||||
@@ -30,6 +43,19 @@ export const CustomCursor: React.FC = () => {
|
||||
setIsPointer(isClickable);
|
||||
};
|
||||
|
||||
// Smooth follow for outer ring
|
||||
const animateRing = () => {
|
||||
ringX += (mouseX - ringX) * 0.15;
|
||||
ringY += (mouseY - ringY) * 0.15;
|
||||
|
||||
if (ringRef.current) {
|
||||
ringRef.current.style.left = `${ringX}px`;
|
||||
ringRef.current.style.top = `${ringY}px`;
|
||||
}
|
||||
|
||||
requestAnimationFrame(animateRing);
|
||||
};
|
||||
|
||||
const handleMouseDown = () => setIsClicking(true);
|
||||
const handleMouseUp = () => setIsClicking(false);
|
||||
const handleMouseLeave = () => setIsVisible(false);
|
||||
@@ -41,6 +67,9 @@ export const CustomCursor: React.FC = () => {
|
||||
document.documentElement.addEventListener('mouseleave', handleMouseLeave);
|
||||
document.documentElement.addEventListener('mouseenter', handleMouseEnter);
|
||||
|
||||
// Start animation loop
|
||||
const animationId = requestAnimationFrame(animateRing);
|
||||
|
||||
// Hide default cursor
|
||||
document.body.style.cursor = 'none';
|
||||
document.querySelectorAll('a, button').forEach(el => {
|
||||
@@ -54,6 +83,7 @@ export const CustomCursor: React.FC = () => {
|
||||
document.documentElement.removeEventListener('mouseleave', handleMouseLeave);
|
||||
document.documentElement.removeEventListener('mouseenter', handleMouseEnter);
|
||||
document.body.style.cursor = 'auto';
|
||||
cancelAnimationFrame(animationId);
|
||||
};
|
||||
}, []);
|
||||
|
||||
@@ -61,51 +91,37 @@ export const CustomCursor: React.FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Main cursor dot */}
|
||||
{/* Main cursor dot - instantly follows mouse */}
|
||||
<div
|
||||
className="fixed pointer-events-none z-9999 mix-blend-difference"
|
||||
ref={cursorRef}
|
||||
className="fixed pointer-events-none z-9999"
|
||||
style={{
|
||||
left: position.x,
|
||||
top: position.y,
|
||||
transform: 'translate(-50%, -50%)',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={`
|
||||
rounded-full bg-zsl-primary transition-all duration-150 ease-out
|
||||
rounded-full bg-zsl-primary transition-all duration-75 ease-out
|
||||
${isClicking ? 'w-2 h-2' : isPointer ? 'w-4 h-4' : 'w-3 h-3'}
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Outer ring */}
|
||||
{/* Outer ring - smooth follow */}
|
||||
<div
|
||||
className="fixed pointer-events-none z-9998 transition-all duration-300 ease-out"
|
||||
ref={ringRef}
|
||||
className="fixed pointer-events-none z-9998"
|
||||
style={{
|
||||
left: position.x,
|
||||
top: position.y,
|
||||
transform: 'translate(-50%, -50%)',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={`
|
||||
rounded-full border-2 border-zsl-primary/50 transition-all duration-200 ease-out
|
||||
rounded-full border-2 border-zsl-primary/50 transition-all duration-100 ease-out
|
||||
${isClicking ? 'w-6 h-6 border-zsl-accent' : isPointer ? 'w-10 h-10 border-zsl-accent' : 'w-8 h-8'}
|
||||
`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Glow trail effect */}
|
||||
<div
|
||||
className="fixed pointer-events-none z-9997 transition-all duration-500 ease-out opacity-30"
|
||||
style={{
|
||||
left: position.x,
|
||||
top: position.y,
|
||||
transform: 'translate(-50%, -50%)',
|
||||
}}
|
||||
>
|
||||
<div className="w-16 h-16 rounded-full bg-zsl-primary/20 blur-xl" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
190
src/data/projects.ts
Normal file
190
src/data/projects.ts
Normal file
@@ -0,0 +1,190 @@
|
||||
// Project data shared between pages
|
||||
export interface Project {
|
||||
id: string;
|
||||
slug: string;
|
||||
title: string;
|
||||
category: string;
|
||||
description: string;
|
||||
longDescription: string;
|
||||
image: string;
|
||||
tags: string[];
|
||||
technologies: string[];
|
||||
features: string[];
|
||||
status: 'Tamamlandı' | 'Devam Ediyor' | 'Bakımda';
|
||||
year: string;
|
||||
client?: string;
|
||||
duration?: string;
|
||||
link?: string;
|
||||
github?: string;
|
||||
}
|
||||
|
||||
export const projects: Project[] = [
|
||||
{
|
||||
id: '1',
|
||||
slug: 'aurora-ai',
|
||||
title: 'Aurora AI',
|
||||
category: 'Yapay Zeka',
|
||||
description: 'Doğal dil işleme ve makine öğrenimi ile güçlendirilmiş kurumsal yapay zeka asistanı.',
|
||||
longDescription: `Aurora AI, işletmelerin müşteri hizmetlerini ve iç süreçlerini otomatize etmek için geliştirdiğimiz yapay zeka çözümüdür.
|
||||
|
||||
Doğal dil işleme (NLP) teknolojileri kullanarak Türkçe dahil 15+ dilde akıcı konuşma yapabilen bu sistem, GPT tabanlı modellerle entegre çalışır.
|
||||
|
||||
Müşteri hizmetleri, HR süreçleri, teknik destek ve satış asistanlığı gibi birçok alanda kullanılabilir. Öğrenme yeteneği sayesinde her geçen gün daha akıllı hale gelir.`,
|
||||
image: '/projects/aurora-ai.jpg',
|
||||
tags: ['AI', 'NLP', 'Machine Learning', 'Enterprise'],
|
||||
technologies: ['Python', 'TensorFlow', 'FastAPI', 'React', 'PostgreSQL', 'Redis', 'Docker', 'Kubernetes'],
|
||||
features: [
|
||||
'15+ dilde doğal dil desteği',
|
||||
'GPT-4 ve Claude entegrasyonu',
|
||||
'Özel model eğitimi',
|
||||
'CRM ve ERP entegrasyonları',
|
||||
'Gerçek zamanlı analytics',
|
||||
'Multi-tenant mimari'
|
||||
],
|
||||
status: 'Tamamlandı',
|
||||
year: '2024',
|
||||
duration: '8 ay',
|
||||
link: 'https://aurora-ai.demo.zerosixlab.com'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
slug: 'quantumledger',
|
||||
title: 'QuantumLedger',
|
||||
category: 'Blockchain',
|
||||
description: 'Kurumsal seviye dağıtık defter teknolojisi ve akıllı sözleşme platformu.',
|
||||
longDescription: `QuantumLedger, finansal kurumlar için geliştirdiğimiz özel blockchain çözümüdür.
|
||||
|
||||
Hyperledger Fabric tabanlı bu platform, saniyede 10,000+ işlem kapasitesi ile yüksek performans sunar. Akıllı sözleşmeler ile otomatik uyumluluk kontrolü ve denetim izi sağlar.
|
||||
|
||||
Özellikle bankacılık, sigorta ve tedarik zinciri sektörlerinde kullanılmak üzere tasarlanmıştır.`,
|
||||
image: '/projects/quantumledger.jpg',
|
||||
tags: ['Blockchain', 'DeFi', 'Smart Contracts', 'Fintech'],
|
||||
technologies: ['Solidity', 'Hyperledger Fabric', 'Go', 'Node.js', 'React', 'MongoDB', 'AWS'],
|
||||
features: [
|
||||
'10,000+ TPS performans',
|
||||
'Akıllı sözleşme desteği',
|
||||
'Çoklu konsensüs mekanizması',
|
||||
'Regülasyon uyumluluğu',
|
||||
'Gerçek zamanlı izleme',
|
||||
'API gateway'
|
||||
],
|
||||
status: 'Tamamlandı',
|
||||
year: '2024',
|
||||
client: 'Gizli (NDA)',
|
||||
duration: '12 ay'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
slug: 'nexuscloud',
|
||||
title: 'NexusCloud',
|
||||
category: 'Cloud',
|
||||
description: 'Hibrit bulut yönetimi ve orkestrasyon platformu.',
|
||||
longDescription: `NexusCloud, çoklu bulut ortamlarını tek bir panelden yönetmenizi sağlayan orkestrasyon platformudur.
|
||||
|
||||
AWS, Azure, GCP ve on-premise sistemleri entegre ederek hibrit bulut stratejinizi kolaylaştırır. Kubernetes tabanlı konteyner orkestrasyonu, otomatik ölçeklendirme ve maliyet optimizasyonu özellikleri sunar.
|
||||
|
||||
DevOps ekipleri için CI/CD pipeline entegrasyonları ve Infrastructure as Code desteği ile tam otomasyon sağlar.`,
|
||||
image: '/projects/nexuscloud.jpg',
|
||||
tags: ['Cloud', 'DevOps', 'Kubernetes', 'IaC'],
|
||||
technologies: ['Go', 'Kubernetes', 'Terraform', 'React', 'GraphQL', 'TimescaleDB', 'Prometheus'],
|
||||
features: [
|
||||
'Multi-cloud yönetimi',
|
||||
'Otomatik ölçeklendirme',
|
||||
'Maliyet optimizasyonu',
|
||||
'CI/CD entegrasyonu',
|
||||
'Infrastructure as Code',
|
||||
'Gerçek zamanlı monitoring'
|
||||
],
|
||||
status: 'Devam Ediyor',
|
||||
year: '2024',
|
||||
duration: '6 ay (devam ediyor)'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
slug: 'cyberguard',
|
||||
title: 'CyberGuard',
|
||||
category: 'Güvenlik',
|
||||
description: 'AI destekli siber tehdit algılama ve yanıt sistemi.',
|
||||
longDescription: `CyberGuard, yapay zeka destekli siber güvenlik çözümümüzdür.
|
||||
|
||||
Makine öğrenimi algoritmaları ile anormal davranışları tespit eder, zero-day saldırılarını önler ve otomatik yanıt mekanizmaları ile tehditleri nötralize eder.
|
||||
|
||||
SIEM sistemleri, firewall'lar ve endpoint protection çözümleri ile entegre çalışarak 360 derece güvenlik sağlar.`,
|
||||
image: '/projects/cyberguard.jpg',
|
||||
tags: ['Security', 'AI', 'Threat Detection', 'SIEM'],
|
||||
technologies: ['Python', 'Rust', 'Elasticsearch', 'Kafka', 'React', 'TensorFlow', 'Docker'],
|
||||
features: [
|
||||
'AI tabanlı tehdit algılama',
|
||||
'Zero-day koruma',
|
||||
'Otomatik yanıt sistemi',
|
||||
'SIEM entegrasyonu',
|
||||
'Compliance raporlama',
|
||||
'7/24 SOC desteği'
|
||||
],
|
||||
status: 'Tamamlandı',
|
||||
year: '2023',
|
||||
duration: '10 ay',
|
||||
link: 'https://cyberguard.demo.zerosixlab.com'
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
slug: 'dataforge',
|
||||
title: 'DataForge',
|
||||
category: 'Big Data',
|
||||
description: 'Büyük veri işleme ve gerçek zamanlı analitik platformu.',
|
||||
longDescription: `DataForge, petabayt ölçeğinde veri işleme kapasitesine sahip analitik platformumuzdur.
|
||||
|
||||
Apache Spark ve Flink tabanlı stream processing ile gerçek zamanlı veri analizi yapar. Özelleştirilebilir dashboard'lar ve raporlama araçları ile veriden değer çıkarır.
|
||||
|
||||
E-ticaret, telekomünikasyon ve IoT sektörlerinde kullanılan bu platform, veri mühendisliği süreçlerini otomatize eder.`,
|
||||
image: '/projects/dataforge.jpg',
|
||||
tags: ['Big Data', 'Analytics', 'Real-time', 'ETL'],
|
||||
technologies: ['Scala', 'Apache Spark', 'Apache Flink', 'Kafka', 'Airflow', 'Snowflake', 'dbt'],
|
||||
features: [
|
||||
'Petabayt ölçeği',
|
||||
'Gerçek zamanlı stream processing',
|
||||
'ETL/ELT pipeline\'lar',
|
||||
'Özel dashboard\'lar',
|
||||
'ML model entegrasyonu',
|
||||
'Data governance'
|
||||
],
|
||||
status: 'Tamamlandı',
|
||||
year: '2024',
|
||||
duration: '9 ay'
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
slug: 'smartcity',
|
||||
title: 'SmartCity IoT',
|
||||
category: 'IoT',
|
||||
description: 'Akıllı şehir altyapısı için IoT sensör yönetim sistemi.',
|
||||
longDescription: `SmartCity IoT, belediyeler ve altyapı şirketleri için geliştirdiğimiz akıllı şehir çözümüdür.
|
||||
|
||||
Trafik yönetimi, enerji optimizasyonu, atık yönetimi ve çevre izleme gibi birçok alanda IoT sensörlerden toplanan verileri analiz eder.
|
||||
|
||||
Edge computing ile düşük latency, mesh network ile yüksek erişilebilirlik sağlar. Yapay zeka ile predictive maintenance yaparak arızaları önceden tespit eder.`,
|
||||
image: '/projects/smartcity.jpg',
|
||||
tags: ['IoT', 'Smart City', 'Edge Computing', 'AI'],
|
||||
technologies: ['C++', 'Rust', 'MQTT', 'InfluxDB', 'Grafana', 'TensorFlow Lite', 'React Native'],
|
||||
features: [
|
||||
'100,000+ sensör desteği',
|
||||
'Edge computing',
|
||||
'Predictive maintenance',
|
||||
'Enerji optimizasyonu',
|
||||
'Trafik yönetimi',
|
||||
'Çevre izleme'
|
||||
],
|
||||
status: 'Devam Ediyor',
|
||||
year: '2024',
|
||||
client: 'Büyükşehir Belediyesi',
|
||||
duration: '18 ay (devam ediyor)'
|
||||
}
|
||||
];
|
||||
|
||||
export function getProjectBySlug(slug: string): Project | undefined {
|
||||
return projects.find(p => p.slug === slug);
|
||||
}
|
||||
|
||||
export function getAllProjectSlugs(): string[] {
|
||||
return projects.map(p => p.slug);
|
||||
}
|
||||
Reference in New Issue
Block a user