init commit
This commit is contained in:
296
.history/views/portfolio_20251019165556.ejs
Normal file
296
.history/views/portfolio_20251019165556.ejs
Normal file
@@ -0,0 +1,296 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>포트폴리오 - SmartSolTech</title>
|
||||
|
||||
<!-- SEO Meta Tags -->
|
||||
<meta name="description" content="SmartSolTech의 다양한 프로젝트와 성공 사례를 확인해보세요. 웹 개발, 모바일 앱, UI/UX 디자인 포트폴리오.">
|
||||
<meta name="keywords" content="포트폴리오, 웹 개발, 모바일 앱, UI/UX 디자인, 프로젝트, SmartSolTech">
|
||||
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:title" content="포트폴리오 - SmartSolTech">
|
||||
<meta property="og:description" content="SmartSolTech의 다양한 프로젝트와 성공 사례">
|
||||
<meta property="og:type" content="website">
|
||||
|
||||
<!-- PWA -->
|
||||
<meta name="theme-color" content="#3B82F6">
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link rel="apple-touch-icon" href="/images/icons/icon-192x192.png">
|
||||
|
||||
<!-- Styles -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
|
||||
<link href="/css/main.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<%- include('partials/navigation') %>
|
||||
|
||||
<!-- Portfolio Hero Section -->
|
||||
<section class="hero-section bg-gradient-to-br from-blue-600 via-purple-600 to-blue-800 pt-20">
|
||||
<div class="container mx-auto px-4 py-20 text-center text-white">
|
||||
<h1 class="text-5xl md:text-6xl font-bold mb-6" data-aos="fade-up">
|
||||
우리의 <span class="text-yellow-300">포트폴리오</span>
|
||||
</h1>
|
||||
<p class="text-xl md:text-2xl mb-8 opacity-90" data-aos="fade-up" data-aos-delay="200">
|
||||
혁신적인 프로젝트와 창의적인 솔루션들을 만나보세요
|
||||
</p>
|
||||
<div class="flex flex-wrap justify-center gap-4" data-aos="fade-up" data-aos-delay="400">
|
||||
<button class="filter-btn bg-white text-blue-600 px-6 py-3 rounded-full font-semibold hover:bg-blue-50 transition-colors active" data-filter="all">
|
||||
전체
|
||||
</button>
|
||||
<button class="filter-btn bg-blue-700 text-white px-6 py-3 rounded-full font-semibold hover:bg-blue-800 transition-colors" data-filter="web-development">
|
||||
웹 개발
|
||||
</button>
|
||||
<button class="filter-btn bg-blue-700 text-white px-6 py-3 rounded-full font-semibold hover:bg-blue-800 transition-colors" data-filter="mobile-app">
|
||||
모바일 앱
|
||||
</button>
|
||||
<button class="filter-btn bg-blue-700 text-white px-6 py-3 rounded-full font-semibold hover:bg-blue-800 transition-colors" data-filter="ui-ux-design">
|
||||
UI/UX 디자인
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Portfolio Grid -->
|
||||
<section class="section-padding bg-gray-50">
|
||||
<div class="container mx-auto px-4">
|
||||
<div id="portfolio-grid" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
<% if (portfolioItems && portfolioItems.length > 0) { %>
|
||||
<% portfolioItems.forEach((item, index) => { %>
|
||||
<div class="portfolio-item bg-white rounded-xl shadow-lg overflow-hidden hover:shadow-xl transition-all duration-300 transform hover:-translate-y-2"
|
||||
data-category="<%= item.category %>"
|
||||
data-aos="fade-up"
|
||||
data-aos-delay="<%= index * 100 %>">
|
||||
|
||||
<!-- Project Image -->
|
||||
<div class="relative overflow-hidden h-64">
|
||||
<% if (item.images && item.images.length > 0) { %>
|
||||
<img src="<%= item.images.find(img => img.isPrimary)?.url || item.images[0].url || '/images/placeholder-project.jpg' %>"
|
||||
alt="<%= item.title %>"
|
||||
class="w-full h-full object-cover transition-transform duration-300 hover:scale-110">
|
||||
<% } else { %>
|
||||
<div class="w-full h-full bg-gradient-to-br from-blue-400 to-purple-500 flex items-center justify-center">
|
||||
<i class="fas fa-code text-white text-4xl opacity-50"></i>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<!-- Category Badge -->
|
||||
<div class="absolute top-4 left-4">
|
||||
<span class="bg-blue-600 text-white px-3 py-1 rounded-full text-sm font-semibold">
|
||||
<%= getCategoryName(item.category) %>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Featured Badge -->
|
||||
<% if (item.featured) { %>
|
||||
<div class="absolute top-4 right-4">
|
||||
<span class="bg-yellow-500 text-white px-2 py-1 rounded-full text-xs font-bold">
|
||||
<i class="fas fa-star"></i> FEATURED
|
||||
</span>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<!-- Overlay -->
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent opacity-0 hover:opacity-100 transition-opacity duration-300 flex items-center justify-center">
|
||||
<a href="/portfolio/<%= item._id %>" class="bg-white text-gray-900 px-6 py-3 rounded-full font-semibold hover:bg-gray-100 transition-colors">
|
||||
자세히 보기
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Project Info -->
|
||||
<div class="p-6">
|
||||
<h3 class="text-xl font-bold text-gray-900 mb-3 line-clamp-2">
|
||||
<%= item.title %>
|
||||
</h3>
|
||||
<p class="text-gray-600 mb-4 line-clamp-3">
|
||||
<%= item.shortDescription || item.description %>
|
||||
</p>
|
||||
|
||||
<!-- Technologies -->
|
||||
<div class="flex flex-wrap gap-2 mb-4">
|
||||
<% if (item.technologies && item.technologies.length > 0) { %>
|
||||
<% item.technologies.slice(0, 3).forEach(tech => { %>
|
||||
<span class="bg-gray-100 text-gray-600 px-2 py-1 rounded text-xs font-medium">
|
||||
<%= tech %>
|
||||
</span>
|
||||
<% }) %>
|
||||
<% if (item.technologies.length > 3) { %>
|
||||
<span class="bg-gray-100 text-gray-600 px-2 py-1 rounded text-xs font-medium">
|
||||
+<%= item.technologies.length - 3 %>
|
||||
</span>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
<!-- Client & Stats -->
|
||||
<div class="flex items-center justify-between text-sm text-gray-500">
|
||||
<div class="flex items-center">
|
||||
<% if (item.clientName) { %>
|
||||
<i class="fas fa-user mr-1"></i>
|
||||
<%= item.clientName %>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="flex items-center">
|
||||
<i class="fas fa-eye mr-1"></i>
|
||||
<%= item.viewCount || 0 %>
|
||||
</span>
|
||||
<span class="flex items-center">
|
||||
<i class="fas fa-heart mr-1 text-red-400"></i>
|
||||
<%= item.likes || 0 %>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Button -->
|
||||
<div class="mt-4 pt-4 border-t border-gray-100">
|
||||
<a href="/portfolio/<%= item._id %>" class="block w-full bg-blue-600 text-white text-center py-2 rounded-lg hover:bg-blue-700 transition-colors font-semibold">
|
||||
프로젝트 상세보기
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% }) %>
|
||||
<% } else { %>
|
||||
<div class="col-span-full text-center py-12">
|
||||
<i class="fas fa-folder-open text-6xl text-gray-300 mb-4"></i>
|
||||
<h3 class="text-2xl font-bold text-gray-500 mb-2">아직 포트폴리오가 없습니다</h3>
|
||||
<p class="text-gray-400">곧 멋진 프로젝트들을 공개할 예정입니다!</p>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
<!-- Load More Button -->
|
||||
<% if (portfolioItems && portfolioItems.length >= 9) { %>
|
||||
<div class="text-center mt-12" data-aos="fade-up">
|
||||
<button id="load-more-btn" class="bg-blue-600 text-white px-8 py-3 rounded-full hover:bg-blue-700 transition-colors font-semibold">
|
||||
더 많은 프로젝트 보기
|
||||
</button>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<section class="section-padding bg-gradient-to-r from-blue-600 to-purple-600 text-white">
|
||||
<div class="container mx-auto px-4 text-center">
|
||||
<h2 class="text-3xl md:text-4xl font-bold mb-6" data-aos="fade-up">
|
||||
다음 프로젝트의 주인공이 되어보세요
|
||||
</h2>
|
||||
<p class="text-xl mb-8 opacity-90" data-aos="fade-up" data-aos-delay="200">
|
||||
우리와 함께 혁신적인 디지털 솔루션을 만들어보세요
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center" data-aos="fade-up" data-aos-delay="400">
|
||||
<a href="/contact" class="bg-white text-blue-600 px-8 py-3 rounded-full hover:bg-gray-100 transition-colors font-semibold">
|
||||
프로젝트 문의하기
|
||||
</a>
|
||||
<a href="/calculator" class="border-2 border-white text-white px-8 py-3 rounded-full hover:bg-white hover:text-blue-600 transition-colors font-semibold">
|
||||
비용 계산하기
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<%- include('partials/footer') %>
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
|
||||
<script src="/js/main.js"></script>
|
||||
|
||||
<script>
|
||||
// Portfolio filtering functionality
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const filterButtons = document.querySelectorAll('.filter-btn');
|
||||
const portfolioItems = document.querySelectorAll('.portfolio-item');
|
||||
|
||||
filterButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const filter = button.getAttribute('data-filter');
|
||||
|
||||
// Update active button
|
||||
filterButtons.forEach(btn => {
|
||||
btn.classList.remove('active', 'bg-white', 'text-blue-600');
|
||||
btn.classList.add('bg-blue-700', 'text-white');
|
||||
});
|
||||
button.classList.add('active', 'bg-white', 'text-blue-600');
|
||||
button.classList.remove('bg-blue-700', 'text-white');
|
||||
|
||||
// Filter items
|
||||
portfolioItems.forEach(item => {
|
||||
const itemCategory = item.getAttribute('data-category');
|
||||
if (filter === 'all' || itemCategory === filter) {
|
||||
item.style.display = 'block';
|
||||
item.classList.remove('opacity-0');
|
||||
item.classList.add('opacity-100');
|
||||
} else {
|
||||
item.classList.remove('opacity-100');
|
||||
item.classList.add('opacity-0');
|
||||
setTimeout(() => {
|
||||
if (item.classList.contains('opacity-0')) {
|
||||
item.style.display = 'none';
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Load more functionality
|
||||
const loadMoreBtn = document.getElementById('load-more-btn');
|
||||
if (loadMoreBtn) {
|
||||
loadMoreBtn.addEventListener('click', async () => {
|
||||
try {
|
||||
const currentItems = portfolioItems.length;
|
||||
const response = await fetch(`/api/portfolio?offset=${currentItems}&limit=6`);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success && data.portfolioItems.length > 0) {
|
||||
// Add new items to grid
|
||||
// This would require server-side rendering or client-side templating
|
||||
// For now, we'll just hide the button
|
||||
if (data.portfolioItems.length < 6) {
|
||||
loadMoreBtn.style.display = 'none';
|
||||
}
|
||||
} else {
|
||||
loadMoreBtn.style.display = 'none';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading more portfolio items:', error);
|
||||
loadMoreBtn.style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Category name mapping
|
||||
function getCategoryName(category) {
|
||||
const categoryNames = {
|
||||
'web-development': '웹 개발',
|
||||
'mobile-app': '모바일 앱',
|
||||
'ui-ux-design': 'UI/UX 디자인',
|
||||
'branding': '브랜딩',
|
||||
'marketing': '디지털 마케팅'
|
||||
};
|
||||
return categoryNames[category] || category;
|
||||
}
|
||||
</script>
|
||||
|
||||
<%
|
||||
// Helper function for category names
|
||||
function getCategoryName(category) {
|
||||
const categoryNames = {
|
||||
'web-development': '웹 개발',
|
||||
'mobile-app': '모바일 앱',
|
||||
'ui-ux-design': 'UI/UX 디자인',
|
||||
'branding': '브랜딩',
|
||||
'marketing': '디지털 마케팅'
|
||||
};
|
||||
return categoryNames[category] || category;
|
||||
}
|
||||
%>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user