Implementierung - SEO - 01.08.2025

This commit is contained in:
2025-08-01 14:26:05 +02:00
parent 7aa0543001
commit f176743885
35 changed files with 3427 additions and 98 deletions
+221
View File
@@ -0,0 +1,221 @@
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const generateGitHubReadme = () => {
const readme = `# 👋 Hi, I'm Damjan Savić - Fullstack Developer
🚀 **Specializing in:** Python | JavaScript | React | Next.js | TypeScript | AI/ML with OLLAMA
## 🎯 Current Focus
- 🤖 Building AI-powered applications with OLLAMA
- 🏢 Developing ERP integration solutions
- 🛒 Creating scalable e-commerce platforms
- ⚡ Automating business processes with Python
## 💻 Tech Stack
### Languages
![Python](https://img.shields.io/badge/Python-3776AB?style=for-the-badge&logo=python&logoColor=white)
![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?style=for-the-badge&logo=javascript&logoColor=black)
![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)
### Frontend
![React](https://img.shields.io/badge/React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB)
![Next.js](https://img.shields.io/badge/Next.js-000000?style=for-the-badge&logo=nextdotjs&logoColor=white)
![Tailwind CSS](https://img.shields.io/badge/Tailwind_CSS-38B2AC?style=for-the-badge&logo=tailwind-css&logoColor=white)
### Backend
![FastAPI](https://img.shields.io/badge/FastAPI-009688?style=for-the-badge&logo=FastAPI&logoColor=white)
![Django](https://img.shields.io/badge/Django-092E20?style=for-the-badge&logo=django&logoColor=white)
![Node.js](https://img.shields.io/badge/Node.js-339933?style=for-the-badge&logo=nodedotjs&logoColor=white)
### AI/ML
![OLLAMA](https://img.shields.io/badge/OLLAMA-000000?style=for-the-badge&logo=ai&logoColor=white)
![LangChain](https://img.shields.io/badge/LangChain-121212?style=for-the-badge)
### Databases
![PostgreSQL](https://img.shields.io/badge/PostgreSQL-316192?style=for-the-badge&logo=postgresql&logoColor=white)
![MongoDB](https://img.shields.io/badge/MongoDB-4EA94B?style=for-the-badge&logo=mongodb&logoColor=white)
### DevOps
![Docker](https://img.shields.io/badge/Docker-2CA5E0?style=for-the-badge&logo=docker&logoColor=white)
![AWS](https://img.shields.io/badge/AWS-FF9900?style=for-the-badge&logo=amazonaws&logoColor=white)
## 📊 GitHub Stats
![GitHub Stats](https://github-readme-stats.vercel.app/api?username=damjansavic&show_icons=true&theme=dark&count_private=true)
![Top Languages](https://github-readme-stats.vercel.app/api/top-langs/?username=damjansavic&layout=compact&theme=dark)
## 🏆 Featured Projects
### 🤖 [OLLAMA Chat Interface](https://github.com/damjansavic/ollama-chat)
Local AI chat application with privacy-first approach
- **Tech:** Python, FastAPI, React, OLLAMA
- **Features:** Stream responses, conversation history, multiple models
### 🛒 [E-Commerce Automation Suite](https://github.com/damjansavic/ecommerce-automation)
Automated inventory and order management system
- **Tech:** Python, Django, React, PostgreSQL
- **Impact:** 60% reduction in manual processing time
### 📊 [ERP Integration Platform](https://github.com/damjansavic/erp-integration)
Seamless connection between multiple ERP systems
- **Tech:** Python, FastAPI, Docker, RabbitMQ
- **Scale:** Processing 1M+ transactions daily
## 💡 What I Offer
- **🚀 Performance:** Applications optimized for speed and scalability
- **🔒 Security:** Privacy-first AI solutions with OLLAMA
- **📈 Business Impact:** Solutions that deliver measurable ROI
- **🛠️ Full Stack:** From database design to user interface
## 📫 Connect With Me
- 🌐 [Portfolio](https://damjan-savic.com)
- 💼 [LinkedIn](https://linkedin.com/in/damjansavic)
- 📧 [Email](mailto:info@damjan-savic.com)
## 🎯 Open for Opportunities
I'm interested in projects involving:
- AI/ML integration with business applications
- High-performance web applications
- Process automation and optimization
- E-commerce and ERP solutions
---
*"Building the future, one line of code at a time"* 🚀
`;
return readme;
};
// Generate and save the README
const readme = generateGitHubReadme();
const outputPath = path.join(__dirname, '..', 'github-profile-README.md');
fs.writeFileSync(outputPath, readme, 'utf-8');
console.log(`✅ GitHub Profile README generated successfully at ${outputPath}`);
// Also generate a template for project READMEs
const projectReadmeTemplate = `# Project Name
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Python](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![React](https://img.shields.io/badge/react-18.0+-blue.svg)](https://reactjs.org/)
## 🚀 Overview
Brief description of what this project does and why it's useful.
### 🎯 Key Features
- Feature 1: Description
- Feature 2: Description
- Feature 3: Description
### 💡 Use Cases
- Use case 1
- Use case 2
- Use case 3
## 🛠️ Tech Stack
- **Backend:** Python, FastAPI/Django
- **Frontend:** React, Next.js, TypeScript
- **Database:** PostgreSQL/MongoDB
- **AI/ML:** OLLAMA, LangChain
- **DevOps:** Docker, AWS
## 📦 Installation
\`\`\`bash
# Clone the repository
git clone https://github.com/damjansavic/project-name.git
# Navigate to project directory
cd project-name
# Install dependencies
pip install -r requirements.txt
npm install
# Set up environment variables
cp .env.example .env
\`\`\`
## 🚀 Quick Start
\`\`\`bash
# Start the backend
python main.py
# Start the frontend (in another terminal)
npm run dev
\`\`\`
## 📊 Performance
- **Response Time:** < 100ms
- **Throughput:** 1000+ requests/second
- **Uptime:** 99.9%
## 🔧 Configuration
Key configuration options:
\`\`\`python
# config.py
DATABASE_URL = "postgresql://..."
OLLAMA_MODEL = "llama2"
API_KEY = "your-api-key"
\`\`\`
## 📱 API Documentation
API documentation is available at \`/docs\` when running the application.
### Example Request
\`\`\`bash
curl -X POST "http://localhost:8000/api/v1/process" \\
-H "Content-Type: application/json" \\
-d '{"data": "example"}'
\`\`\`
## 🧪 Testing
\`\`\`bash
# Run tests
pytest
# Run with coverage
pytest --cov=app tests/
\`\`\`
## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 👨‍💻 Author
**Damjan Savić**
- Website: [damjan-savic.com](https://damjan-savic.com)
- LinkedIn: [@damjansavic](https://linkedin.com/in/damjansavic)
- GitHub: [@damjansavic](https://github.com/damjansavic)
---
⭐️ If you find this project useful, please consider giving it a star!
`;
const templatePath = path.join(__dirname, '..', 'project-readme-template.md');
fs.writeFileSync(templatePath, projectReadmeTemplate, 'utf-8');
console.log(`✅ Project README template generated at ${templatePath}`);
+117
View File
@@ -0,0 +1,117 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>OG Image Generator</title>
<style>
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.og-container {
width: 1200px;
height: 630px;
background: linear-gradient(135deg, #18181B 0%, #27272A 100%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
}
.pattern {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0.05;
background-image:
repeating-linear-gradient(45deg, transparent, transparent 35px, rgba(255,255,255,.1) 35px, rgba(255,255,255,.1) 70px);
}
.content {
position: relative;
z-index: 1;
text-align: center;
padding: 60px;
}
.logo {
width: 120px;
height: 120px;
background: #3B82F6;
border-radius: 30px;
margin: 0 auto 40px;
display: flex;
align-items: center;
justify-content: center;
font-size: 60px;
font-weight: bold;
color: white;
}
h1 {
color: white;
font-size: 72px;
margin: 0 0 20px 0;
font-weight: 700;
line-height: 1.1;
}
.subtitle {
color: #A1A1AA;
font-size: 36px;
margin: 0 0 40px 0;
font-weight: 400;
}
.skills {
display: flex;
gap: 20px;
justify-content: center;
flex-wrap: wrap;
max-width: 900px;
margin: 0 auto;
}
.skill {
background: rgba(59, 130, 246, 0.1);
border: 2px solid #3B82F6;
color: #93BBFC;
padding: 12px 24px;
border-radius: 50px;
font-size: 20px;
font-weight: 500;
}
.bottom-line {
position: absolute;
bottom: 40px;
left: 0;
right: 0;
text-align: center;
color: #71717A;
font-size: 18px;
}
</style>
</head>
<body>
<div class="og-container" id="og-image">
<div class="pattern"></div>
<div class="content">
<div class="logo">DS</div>
<h1>Damjan Savić</h1>
<p class="subtitle">Fullstack Developer & KI Spezialist</p>
<div class="skills">
<span class="skill">Python</span>
<span class="skill">JavaScript</span>
<span class="skill">React</span>
<span class="skill">TypeScript</span>
<span class="skill">OLLAMA</span>
<span class="skill">AI/ML</span>
</div>
</div>
<div class="bottom-line">damjan-savic.com</div>
</div>
<script>
// This HTML can be used with a headless browser to generate the OG image
// Example: Use Puppeteer or Playwright to screenshot this page
</script>
</body>
</html>
+162
View File
@@ -0,0 +1,162 @@
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const SITE_URL = 'https://damjan-savic.com';
const LANGUAGES = ['de', 'en', 'sr'];
const DEFAULT_LANGUAGE = 'de';
// Static pages that exist in your application
const staticPages = [
'/',
'/about',
'/portfolio',
'/blog',
'/contact',
'/privacy',
'/terms'
];
// Blog posts (you can dynamically read these from your MDX files)
const blogPosts = [
'erp-integration-breuninger',
'fullstack-development-timetracking',
'rfid-automation'
];
// Projects (you can dynamically read these from your project data)
const projects = [
'ai-data-reader',
'bi-vision',
'business-intelligence-ai',
'claude-personal-assistant',
'e-commerce-integration',
'local-llm-training',
'rfid-automation',
'timetracking-software'
];
function generateUrl(path, language) {
const langPrefix = language === DEFAULT_LANGUAGE ? '' : `/${language}`;
return `${SITE_URL}${langPrefix}${path}`;
}
function generateSitemapXML() {
const currentDate = new Date().toISOString().split('T')[0];
let xml = '<?xml version="1.0" encoding="UTF-8"?>\n';
xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"\n';
xml += ' xmlns:xhtml="http://www.w3.org/1999/xhtml">\n';
// Generate entries for static pages
staticPages.forEach(page => {
LANGUAGES.forEach(lang => {
const url = generateUrl(page, lang);
const priority = page === '/' ? '1.0' : page === '/portfolio' || page === '/blog' ? '0.9' : '0.8';
const changefreq = page === '/' || page === '/portfolio' || page === '/blog' ? 'weekly' : 'monthly';
xml += ' <url>\n';
xml += ` <loc>${url}</loc>\n`;
xml += ` <lastmod>${currentDate}</lastmod>\n`;
xml += ` <changefreq>${changefreq}</changefreq>\n`;
xml += ` <priority>${priority}</priority>\n`;
// Add alternate language links
LANGUAGES.forEach(altLang => {
if (altLang !== lang) {
const altUrl = generateUrl(page, altLang);
xml += ` <xhtml:link rel="alternate" hreflang="${altLang}" href="${altUrl}"/>\n`;
}
});
xml += ` <xhtml:link rel="alternate" hreflang="x-default" href="${generateUrl(page, DEFAULT_LANGUAGE)}"/>\n`;
xml += ' </url>\n';
});
});
// Generate entries for blog posts
blogPosts.forEach(post => {
LANGUAGES.forEach(lang => {
const url = generateUrl(`/blog/${post}`, lang);
xml += ' <url>\n';
xml += ` <loc>${url}</loc>\n`;
xml += ` <lastmod>${currentDate}</lastmod>\n`;
xml += ' <changefreq>monthly</changefreq>\n';
xml += ' <priority>0.7</priority>\n';
// Add alternate language links
LANGUAGES.forEach(altLang => {
if (altLang !== lang) {
const altUrl = generateUrl(`/blog/${post}`, altLang);
xml += ` <xhtml:link rel="alternate" hreflang="${altLang}" href="${altUrl}"/>\n`;
}
});
xml += ` <xhtml:link rel="alternate" hreflang="x-default" href="${generateUrl(`/blog/${post}`, DEFAULT_LANGUAGE)}"/>\n`;
xml += ' </url>\n';
});
});
// Generate entries for projects
projects.forEach(project => {
LANGUAGES.forEach(lang => {
const url = generateUrl(`/portfolio/${project}`, lang);
xml += ' <url>\n';
xml += ` <loc>${url}</loc>\n`;
xml += ` <lastmod>${currentDate}</lastmod>\n`;
xml += ' <changefreq>monthly</changefreq>\n';
xml += ' <priority>0.8</priority>\n';
// Add alternate language links
LANGUAGES.forEach(altLang => {
if (altLang !== lang) {
const altUrl = generateUrl(`/portfolio/${project}`, altLang);
xml += ` <xhtml:link rel="alternate" hreflang="${altLang}" href="${altUrl}"/>\n`;
}
});
xml += ` <xhtml:link rel="alternate" hreflang="x-default" href="${generateUrl(`/portfolio/${project}`, DEFAULT_LANGUAGE)}"/>\n`;
xml += ' </url>\n';
});
});
xml += '</urlset>';
return xml;
}
// Generate and save the sitemap
const sitemapXML = generateSitemapXML();
const outputPath = path.join(__dirname, '..', 'public', 'sitemap.xml');
fs.writeFileSync(outputPath, sitemapXML, 'utf-8');
console.log(`✅ Sitemap generated successfully at ${outputPath}`);
// Also generate a robots.txt if it doesn't exist or update it
const robotsPath = path.join(__dirname, '..', 'public', 'robots.txt');
const robotsContent = `# Allow all crawlers
User-agent: *
Allow: /
Crawl-delay: 1
# Disallow admin or sensitive paths if any
Disallow: /admin
Disallow: /api/
Disallow: /.env
# Sitemap location
Sitemap: ${SITE_URL}/sitemap.xml
# Language specific sitemaps
Sitemap: ${SITE_URL}/sitemap-de.xml
Sitemap: ${SITE_URL}/sitemap-en.xml
Sitemap: ${SITE_URL}/sitemap-sr.xml
`;
fs.writeFileSync(robotsPath, robotsContent, 'utf-8');
console.log(`✅ robots.txt updated successfully at ${robotsPath}`);