You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
679 lines
37 KiB
679 lines
37 KiB
<!DOCTYPE html>
|
|
<html class=" overflow-x-hidden" lang="en">
|
|
<head>
|
|
<meta charset="utf-8"/>
|
|
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"/>
|
|
<title>Join Us - TechCorp</title>
|
|
|
|
<!-- Google Fonts & Icons -->
|
|
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
|
|
<link href="https://fonts.googleapis.com" rel="preconnect"/>
|
|
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
|
|
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;700;900&family=Montserrat:wght@400;500;700;800;900&family=Inter:wght@400;500;700;800;900&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet"/>
|
|
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.css" />
|
|
<!-- AOS Animation Library -->
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-tilt/1.7.2/vanilla-tilt.min.js"></script>
|
|
<!-- Tailwind & Config -->
|
|
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
|
<script id="tailwind-config">
|
|
tailwind.config = {
|
|
darkMode: "class",
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
"primary": "#13eca4",
|
|
"background-light": "#f8fcfa",
|
|
"background-dark": "#10221c",
|
|
"pearlescent": "#f0f7f5",
|
|
"silver-accent": "#e2e8f0",
|
|
"about-us": "#ff6b00"
|
|
},
|
|
fontFamily: {
|
|
"display": ["Montserrat", "sans-serif"],
|
|
"sans": ["Montserrat", "sans-serif"],
|
|
"mono": ["JetBrains Mono", "Montserrat"],
|
|
"inter": ["Inter", "Montserrat"],
|
|
},
|
|
borderRadius: {
|
|
"DEFAULT": "0.5rem",
|
|
"lg": "1rem",
|
|
"xl": "1.5rem",
|
|
"2xl": "2rem",
|
|
"3xl": "3rem",
|
|
"full": "9999px"
|
|
},
|
|
backgroundImage: {
|
|
'liquid-gradient': 'linear-gradient(135deg, #f8fcfa 0%, #e8f5f1 50%, #dcfce7 100%)',
|
|
'glass-gradient': 'linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.3) 100%)',
|
|
'aurora': 'linear-gradient(135deg, rgba(19,236,164,0.1) 0%, rgba(13,166,112,0.05) 50%, rgba(248,252,250,0) 100%)',
|
|
'mesh': 'radial-gradient(at 40% 20%, rgba(19,236,164,0.08) 0px, transparent 50%), radial-gradient(at 80% 0%, rgba(16,34,28,0.05) 0px, transparent 50%), radial-gradient(at 0% 50%, rgba(19,236,164,0.05) 0px, transparent 50%)',
|
|
|
|
},
|
|
boxShadow: {
|
|
// 将光效统一映射为 primary 颜色 (13eca4 的 RGBA)
|
|
'glow': '0 0 20px rgba(19, 236, 164, 0.4)',
|
|
'glow-lg': '0 10px 30px rgba(19, 236, 164, 0.4)',
|
|
'bento': '0 20px 40px -15px rgba(0,0,0,0.05), 0 0 0 1px rgba(0,0,0,0.02)',
|
|
'bento-hover': '0 30px 60px -20px rgba(19,236,164,0.15), 0 0 0 1px rgba(19,236,164,0.3)',
|
|
'bento-dark': '0 30px 60px -15px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.1)',
|
|
},
|
|
keyframes: {
|
|
fadeIn: {
|
|
'0%': { opacity: '0', transform: 'translateY(10px)' },
|
|
'100%': { opacity: '1', transform: 'translateY(0)' },
|
|
},
|
|
scan: {
|
|
'0%': { top: '-10%', opacity: '0' },
|
|
'10%': { opacity: '1' },
|
|
'90%': { opacity: '1' },
|
|
'100%': { top: '110%', opacity: '0' },
|
|
},
|
|
rotateGlobe: {
|
|
'0%': { transform: 'rotate(0deg)' },
|
|
'100%': { transform: 'rotate(360deg)' },
|
|
},
|
|
dash: {
|
|
'0%': { strokeDashoffset: '1000' },
|
|
'100%': { strokeDashoffset: '0' },
|
|
},
|
|
globePulse: {
|
|
'0%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
|
|
'50%': { boxShadow: '0 0 50px rgba(19,236,164,0.4)', transform: 'scale(1.02)' },
|
|
'100%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
|
|
},
|
|
// 高级交互动画
|
|
pulseGlow: {
|
|
'0%': { textShadow: '0 0 10px rgba(19, 236, 164, 0.4)' },
|
|
'100%': { textShadow: '0 0 30px #ff6b00' }
|
|
},
|
|
sweep: { '100%': { left: '200%' } },
|
|
cardFlip: {
|
|
'0%': { opacity: '0', transform: 'rotateY(-90deg) translateZ(50px)' },
|
|
'100%': { opacity: '1', transform: 'rotateY(0deg) translateZ(0)' }
|
|
},
|
|
floatY: {
|
|
'0%, 100%': { transform: 'translateY(0)' },
|
|
'50%': { transform: 'translateY(-15px)' }
|
|
},
|
|
textShimmer: {
|
|
'0%': { backgroundPosition: '0% 50%' },
|
|
'100%': { backgroundPosition: '100% 50%' },
|
|
},
|
|
blobSpin: {
|
|
'0%': { transform: 'rotate(0deg) scale(1)' },
|
|
'50%': { transform: 'rotate(180deg) scale(1.1)' },
|
|
'100%': { transform: 'rotate(360deg) scale(1)' },
|
|
}
|
|
},
|
|
animation: {
|
|
'fade-in': 'fadeIn 0.5s ease-out forwards',
|
|
'scan-slow': 'scan 6s linear infinite',
|
|
'spin-slow': 'rotateGlobe 60s linear infinite',
|
|
'dash-flow': 'dash 3s linear infinite',
|
|
'globe-select': 'globePulse 0.8s ease-out',
|
|
'pulse-glow': 'pulseGlow 2s infinite alternate',
|
|
'sweep': 'sweep 3s infinite',
|
|
'flip-in': 'cardFlip 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards',
|
|
'float-1': 'floatY 3s ease-in-out infinite',
|
|
'float-2': 'floatY 3s ease-in-out infinite 1s',
|
|
'float-3': 'floatY 3s ease-in-out infinite 2s',
|
|
'text-shimmer': 'textShimmer 3s ease-out infinite alternate',
|
|
'blob-spin': 'blobSpin 20s infinite cubic-bezier(0.4, 0, 0.2, 1)',
|
|
}
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<!-- Swiper CSS -->
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
|
|
|
|
<!-- AOS Animation CSS -->
|
|
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
|
|
|
|
<style>
|
|
html { scroll-behavior: smooth; }
|
|
|
|
body {
|
|
overflow-x: hidden;
|
|
width: 100%;
|
|
font-family: "Inter", "JetBrains Mono","sans-serif";
|
|
}
|
|
|
|
.swiper-slide {
|
|
height: auto;
|
|
transform: translateZ(0);
|
|
}
|
|
|
|
.swiper-wrapper {
|
|
align-items: stretch;
|
|
}
|
|
|
|
.swiper-scrollbar {
|
|
background: rgba(0, 0, 0, 0.06) !important;
|
|
height: 6px !important;
|
|
border-radius: 999px;
|
|
width: 100%;
|
|
}
|
|
.dark .swiper-scrollbar {
|
|
background: rgba(255, 255, 255, 0.1) !important;
|
|
}
|
|
.swiper-scrollbar-drag {
|
|
background: #2b8cee !important;
|
|
border-radius: 9999px;
|
|
cursor: grab;
|
|
}
|
|
|
|
.swiper-button-disabled {
|
|
opacity: 0.3 !important;
|
|
cursor: not-allowed !important;
|
|
pointer-events: none;
|
|
box-shadow: none !important;
|
|
filter: grayscale(100%);
|
|
transform: none !important;
|
|
border-color: transparent !important;
|
|
}
|
|
|
|
.dark .swiper-button-disabled {
|
|
opacity: 0.2 !important;
|
|
background-color: #1f2937 !important;
|
|
}
|
|
|
|
.search-container:focus-within {
|
|
box-shadow: 0 0 0 2px var(--tw-ring-offset-color, #fff), 0 0 0 4px rgba(43, 140, 238, 0.5);
|
|
}
|
|
|
|
.card-image-bg {
|
|
transition: transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
}
|
|
.group:hover .card-image-bg {
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
/* Modal Styles */
|
|
.modal-overlay {
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
transition: all 0.3s ease-in-out;
|
|
}
|
|
.modal-overlay.open {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
}
|
|
|
|
.modal-container {
|
|
transform: translateY(20px) scale(0.95);
|
|
opacity: 0;
|
|
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
|
}
|
|
.modal-overlay.open .modal-container {
|
|
transform: translateY(0) scale(1);
|
|
opacity: 1;
|
|
}
|
|
|
|
/* 隐藏滚动条但保留功能 */
|
|
.no-scrollbar::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
.no-scrollbar {
|
|
-ms-overflow-style: none;
|
|
scrollbar-width: none;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body class="bg-background-light dark:bg-background-dark text-[#111418] dark:text-white font-display antialiased w-screen overflow-x-hidden">
|
|
|
|
<div class="relative flex h-auto min-h-screen w-full flex-col group/design-root overflow-x-hidden">
|
|
|
|
<!-- Header -->
|
|
<!-- <header class="sticky top-0 z-40 flex items-center justify-between border-b border-solid border-[#e5e7eb] dark:border-gray-800 bg-white/80 dark:bg-[#101922]/80 backdrop-blur-md px-4 sm:px-6 lg:px-10 py-3 transition-all duration-300">
|
|
<div class="flex items-center gap-4 text-[#111418] dark:text-white">
|
|
<div class="size-8 flex items-center justify-center text-primary flex-shrink-0">
|
|
<span class="material-symbols-outlined text-3xl"></span>
|
|
</div>
|
|
<h2 class="text-[#111418] dark:text-white text-lg leading-tight tracking-[-0.015em] truncate">TechCorp</h2>
|
|
</div>
|
|
<div class="hidden md:flex flex-1 justify-end gap-8">
|
|
<div class="flex items-center gap-9">
|
|
<a class="text-[#111418] dark:text-gray-200 text-sm font-medium hover:text-primary transition-colors" href="#">Jobs</a>
|
|
<a class="text-[#111418] dark:text-gray-200 text-sm font-medium hover:text-primary transition-colors" href="#">Culture</a>
|
|
<a class="text-[#111418] dark:text-gray-200 text-sm font-medium hover:text-primary transition-colors" href="#">About Us</a>
|
|
</div>
|
|
<button class="flex min-w-[84px] items-center justify-center rounded-lg h-10 px-6 bg-primary text-white text-sm hover:bg-blue-600 transition-colors shadow-sm">
|
|
Login
|
|
</button>
|
|
</div>
|
|
<div class="md:hidden p-2 -mr-2 cursor-pointer text-[#111418] dark:text-white">
|
|
<span class="material-symbols-outlined text-2xl"></span>
|
|
</div>
|
|
</header> -->
|
|
|
|
<main class="layout-container flex h-full grow flex-col pt-6 sm:pt-10 pb-20 w-full overflow-x-hidden">
|
|
<div class="w-full flex flex-1 justify-center">
|
|
<div class="layout-content-container flex flex-col w-full max-w-[1400px] flex-1">
|
|
|
|
<!-- Heading & Search Section -->
|
|
<div class="flex flex-col gap-6 px-4 sm:px-6 lg:px-40 mb-6 sm:mb-8 w-full max-w-[100vw] overflow-hidden">
|
|
<div class="flex flex-wrap items-end justify-between gap-6">
|
|
<div class="flex min-w-full md:min-w-[400px] flex-col gap-3 max-w-2xl" data-aos="fade-right" data-aos-duration="1000">
|
|
<h1 class="text-[#111418] dark:text-white text-4xl md:text-[2.66rem] leading-tight tracking-[-0.033em]">
|
|
Shape the future <br/><span class="text-primary bg-clip-text text-transparent bg-gradient-to-r from-blue-500 to-cyan-400">with us.</span>
|
|
</h1>
|
|
<p class="text-[#617589] dark:text-gray-400 text-[1rem] leading-normal max-w-lg mt-1 sm:mt-2">
|
|
We are looking for thinkers, makers, and doers to join our high-energy team.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="flex flex-col sm:flex-row items-end sm:items-center gap-4 w-full sm:w-auto" data-aos="fade-left" data-aos-delay="200">
|
|
<div class="search-container relative w-full sm:w-64 group transition-all duration-300 rounded-full">
|
|
<span class="material-symbols-outlined absolute left-4 top-1/2 -translate-y-1/2 text-gray-400 group-focus-within:text-primary transition-colors"></span>
|
|
<input id="job-search" type="text" placeholder="Search positions..."
|
|
class="w-full h-11 sm:h-12 pl-12 pr-4 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-full text-sm outline-none focus:border-primary dark:focus:border-primary transition-colors text-[#111418] dark:text-white shadow-sm"
|
|
>
|
|
</div>
|
|
|
|
<div class="hidden sm:flex gap-3">
|
|
<button class="swiper-button-prev-custom size-12 rounded-full border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 flex items-center justify-center hover:bg-gray-50 dark:hover:bg-gray-700 hover:border-primary/50 text-[#111418] dark:text-white transition-all duration-300 shadow-sm hover:shadow-md active:scale-95 z-10 group cursor-pointer">
|
|
<span class="material-symbols-outlined group-hover:text-primary transition-colors"></span>
|
|
</button>
|
|
<button class="swiper-button-next-custom size-12 rounded-full border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 flex items-center justify-center hover:bg-gray-50 dark:hover:bg-gray-700 hover:border-primary/50 text-[#111418] dark:text-white transition-all duration-300 shadow-sm hover:shadow-md active:scale-95 z-10 group cursor-pointer">
|
|
<span class="material-symbols-outlined group-hover:text-primary transition-colors"></span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Job Slider Area -->
|
|
<div class="relative w-full min-h-[400px]">
|
|
<div class="swiper mySwiper w-full pb-14 !overflow-visible">
|
|
<div class="swiper-wrapper" id="jobs-container">
|
|
<!-- JS will inject slides here -->
|
|
</div>
|
|
</div>
|
|
|
|
<div id="no-results" class="hidden absolute inset-0 flex flex-col items-center justify-center text-center p-8 z-0 mt-12">
|
|
<span class="material-symbols-outlined text-5xl sm:text-6xl text-gray-300 dark:text-gray-700 mb-4"></span>
|
|
<h3 class="text-lg sm:text-xl text-[#111418] dark:text-white">No positions found</h3>
|
|
<p class="text-sm sm:text-base text-[#617589] dark:text-gray-400 mt-2">Try adjusting your search criteria</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Progress Section -->
|
|
<div class="w-full flex justify-center px-4 sm:px-6 lg:px-40 mt-4 max-w-[100vw]" data-aos="fade-in" data-aos-delay="500">
|
|
<div class="w-full flex flex-col gap-4">
|
|
<div class="flex justify-between items-end">
|
|
<div class="flex flex-col gap-0.5">
|
|
<p class="text-[10px] sm:text-xs tracking-[0.15em] text-primary uppercase">Explore</p>
|
|
<p class="text-[#111418] dark:text-white text-sm sm:text-base ">Open Positions</p>
|
|
</div>
|
|
<p class="text-[#617589] dark:text-gray-400 text-sm sm:text-base font-medium tabular-nums font-mono">
|
|
<span id="slide-current" class="text-[#111418] dark:text-white text-lg">01</span>
|
|
<span class="mx-1 text-gray-300 dark:text-gray-600">/</span>
|
|
<span id="slide-total">00</span>
|
|
</p>
|
|
</div>
|
|
<div class="w-full h-1.5 rounded-full bg-gray-100 dark:bg-gray-800 overflow-hidden relative">
|
|
<div class="swiper-scrollbar !static !w-full !h-full !bg-transparent"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- [New] Job Detail Modal -->
|
|
<div id="job-detail-modal" class="modal-overlay fixed inset-0 z-50 flex items-end sm:items-center justify-center bg-black/60 backdrop-blur-sm p-0 sm:p-4">
|
|
<div class="absolute inset-0 cursor-pointer" onclick="closeJobModal()"></div>
|
|
|
|
<div class="modal-container relative w-full max-w-2xl bg-white dark:bg-[#1a2632] rounded-t-2xl sm:rounded-2xl shadow-2xl flex flex-col max-h-[90vh] sm:max-h-[85vh] border border-white/10 overflow-hidden">
|
|
|
|
<!-- Header -->
|
|
<div class="flex items-start justify-between p-6 border-b border-gray-100 dark:border-gray-700 bg-white/50 dark:bg-[#1a2632]/50 backdrop-blur-sm sticky top-0 z-10">
|
|
<div>
|
|
<div class="flex items-center gap-3 mb-2">
|
|
<span id="modal-tag" class="inline-flex items-center justify-center px-2.5 py-0.5 rounded-full text-xs font-semibold bg-primary/20 text-primary border border-primary/10">Product</span>
|
|
<span class="text-xs text-gray-400 font-mono" id="modal-location">Remote</span>
|
|
</div>
|
|
<h2 id="modal-title" class="text-2xl text-[#111418] dark:text-white leading-tight">Senior Product Designer</h2>
|
|
</div>
|
|
<button onclick="closeJobModal()" class="size-8 rounded-full bg-gray-100 dark:bg-gray-700 flex items-center justify-center text-gray-500 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white transition-colors">
|
|
<span class="material-symbols-outlined text-xl"></span>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Body (Scrollable) -->
|
|
<!-- [修复] 添加 ID 'modal-body' 用于 JS 控制 -->
|
|
<div id="modal-body" class="p-6 overflow-y-auto no-scrollbar flex-1 scroll-smooth">
|
|
<div class="prose dark:prose-invert max-w-none">
|
|
<div class="mb-6">
|
|
<h3 class="text-lg text-[#111418] dark:text-white mb-2">About the Role</h3>
|
|
<p id="modal-desc" class="text-[#617589] dark:text-gray-400 text-sm leading-relaxed">
|
|
Lead design initiatives across our core products...
|
|
</p>
|
|
</div>
|
|
|
|
<div class="mb-6">
|
|
<h3 class="text-lg text-[#111418] dark:text-white mb-2">Key Responsibilities</h3>
|
|
<ul id="modal-responsibilities" class="list-disc pl-5 text-[#617589] dark:text-gray-400 text-sm leading-relaxed space-y-1"></ul>
|
|
</div>
|
|
|
|
<div class="mb-6">
|
|
<h3 class="text-lg text-[#111418] dark:text-white mb-2">Requirements</h3>
|
|
<ul id="modal-requirements" class="list-disc pl-5 text-[#617589] dark:text-gray-400 text-sm leading-relaxed space-y-1"></ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Footer -->
|
|
<!-- Job Detail Modal Footer (修改部分) -->
|
|
<div class="p-5 border-t border-gray-100 dark:border-gray-700 bg-gray-50/80 dark:bg-[#151f28]/80 backdrop-blur-md flex flex-col gap-3">
|
|
<!-- 主按钮 -->
|
|
<a id="modal-apply-btn" href="#" class="flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg h-12 bg-primary hover:bg-blue-600 text-white text-base transition-all shadow-md active:scale-[0.98] group">
|
|
<span class="material-symbols-outlined"></span>
|
|
Apply via Email
|
|
</a>
|
|
|
|
<!-- 新增:邮箱文本提示 (兜底方案) -->
|
|
<p class="text-center text-xs text-[#617589] dark:text-gray-400">
|
|
Or email us directly at
|
|
<!-- select-all 允许用户点击一次即可全选邮箱 -->
|
|
<span class="text-[#111418] dark:text-white font-mono font-medium select-all cursor-text hover:text-primary transition-colors" id="email-link">zhoushu@nenghui.com</span>
|
|
</p>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Scripts -->
|
|
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
|
|
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
|
|
|
|
<script>
|
|
// --- Enhanced Data Source ---
|
|
const jobsData = [
|
|
{
|
|
id: 1,
|
|
title: "Photovoltaic Field Engineer",
|
|
type: "Engineering",
|
|
dept: "Eng",
|
|
location: "Iraq",
|
|
image: "https://nenghui.com/wp-content/uploads/2026/02/job-1.avif",
|
|
color: "bg-primary/90 border-white/10 text-white",
|
|
desc: "",
|
|
responsibilities: ["Responsible for on-site supervision, installation guidance, and problem-solving for photovoltaic and energy storage projects, ensuring construction complies with design specifications and safety standards.",
|
|
"Inspect the construction site, coordinate the installation team, and conduct system commissioning and performance testing.",
|
|
"Collect on-site data and report project progress, quality issues, and customer feedback.",
|
|
"Provide customer training and technical support to ensure normal system operation and customer satisfaction.",
|
|
"Responsible for site surveys and technical solution design.",
|
|
"xResponsible for after-sales troubleshooting."
|
|
],
|
|
requirements: [
|
|
"Full-time college diploma or above, majoring in electrical engineering or related fields, with basic conversational English skills;",
|
|
"At least 1 year of experience in photovoltaic construction, understanding of photovoltaic construction details, and experience in on-site construction guidance;",
|
|
"Responsible, meticulous, and with good professional ethics and communication and coordination skills;",
|
|
"Able to accept long-term relocation to the Middle East; the company provides accommodation and overseas commercial insurance."
|
|
]
|
|
},
|
|
{
|
|
id: 11,
|
|
title: "Overseas Sales Manager",
|
|
type: "Sales",
|
|
dept: "Sale",
|
|
location: "ShangHai",
|
|
image: "https://nenghui.com/wp-content/uploads/2026/02/job-2.avif",
|
|
color: "bg-primary/90 border-white/10 text-white",
|
|
desc: "",
|
|
responsibilities: ["Develop the commercial and industrial energy storage and large-scale energy storage markets in Europe, identify and secure overseas energy storage orders and projects, and achieve company business goals, in accordance with the company's business strategy.",
|
|
"Travel overseas as arranged by the company and as needed to conduct market research and customer visits, track and evaluate customer creditworthiness and purchasing intentions, and establish and maintain a regional customer resource pool.",
|
|
"Participate in overseas industry exhibitions and seminars to develop customer resources and expand business channels.",
|
|
"Assist the company in organizing overseas product launches and promoting brand marketing.",
|
|
|
|
|
|
],
|
|
requirements: [
|
|
"Bachelor's degree or above, with preference given to candidates majoring in international trade, English, or German.",
|
|
"At least 3 years of experience in the new energy industry trade, with preference given to candidates with experience in electrical, photovoltaic, or lithium battery energy storage related products.",
|
|
"Fluent in spoken English and proficient in written communication, including international business emails.",
|
|
"Familiar with various international trade terms and risk control, and proficient in using international social media and foreign trade customer acquisition software.",
|
|
"Excellent communication and teamwork skills.",
|
|
]
|
|
},
|
|
// {
|
|
// id: 2,
|
|
// title: "Lead Backend Engineer",
|
|
// type: "Engineering",
|
|
// dept: "Eng",
|
|
// location: "San Francisco",
|
|
// image: "https://images.unsplash.com/photo-1555099962-4199c345e5dd?ixlib=rb-4.0.3&auto=format&fit=crop&w=1000&q=80",
|
|
// color: "bg-emerald-500/20 border-white/10 text-emerald-100",
|
|
// desc: "Join our backend team to architect scalable systems that handle millions of requests. You will be responsible for the core infrastructure and API development.",
|
|
// responsibilities: ["Design and implement scalable APIs.", "Optimize database performance and queries.", "Mentor junior engineers and review code."],
|
|
// requirements: ["Strong proficiency in Python, Go, or Java.", "Experience with distributed systems and microservices.", "Familiarity with AWS or Google Cloud."]
|
|
// },
|
|
{
|
|
id: 3,
|
|
title: "Business Development Manager ",
|
|
type: "Development",
|
|
dept: "Development",
|
|
location: "Cambodia",
|
|
image: "https://nenghui.com/wp-content/uploads/2026/02/job-3.avif",
|
|
color: "bg-purple-500/90 border-white/10 text-purple-100",
|
|
desc: "",
|
|
responsibilities: ["Develop commercial and industrial photovoltaic (PV) projects within the assigned region, establishing strong client relationships, in accordance with the company's business strategy and development requirements.",
|
|
"Handle all necessary procedures for project approval and grid connection, including preliminary data collection, site visits, and initial assessments of compliance and economic feasibility.",
|
|
"Establish and improve distribution channels for commercial and industrial PV and energy storage projects within the assigned region, fostering a favorable development environment.",
|
|
"Maintain relationships with local government/power grid authorities and relevant departments to promote project cooperation."
|
|
],
|
|
requirements: ["Bachelor's degree or above, any major, at least 2 years of experience in PV projects; experienced business professionals with large-scale project development experience are preferred.",
|
|
"Familiar with the local/industry PV market and proficient in the development process of commercial and industrial power plants.",
|
|
"Strong communication and execution skills, and excellent teamwork ability.",
|
|
"Keen market insight, existing social or industry client resources, and strong ability to acquire project opportunities/leads are preferred."
|
|
]
|
|
},
|
|
// {
|
|
// id: 4,
|
|
// title: "Financing Director/Manager",
|
|
// type: "Financing",
|
|
// dept: "Financing",
|
|
// location: "ShangHai",
|
|
// image: "https://nenghui.com/wp-content/uploads/2026/02/job-1.avif",
|
|
// color: "bg-blue-500/90 border-white/10 text-blue-100",
|
|
// desc: "",
|
|
// responsibilities: ["Build and deploy machine learning models.", "Perform exploratory data analysis.", "Create data visualizations for stakeholders."],
|
|
// requirements: ["Master's or PhD in Statistics, CS, or related field.", "Proficiency in Python, R, and SQL.", "Experience with TensorFlow or PyTorch."]
|
|
// }
|
|
];
|
|
const email = 'zhoushu@nenghui.com'
|
|
const emailLink = document.getElementById('email-link');
|
|
if (emailLink) {
|
|
emailLink.innerText = email;
|
|
}
|
|
let swiperInstance = null;
|
|
const container = document.getElementById('jobs-container');
|
|
const noResultsEl = document.getElementById('no-results');
|
|
const searchInput = document.getElementById('job-search');
|
|
|
|
const modal = document.getElementById('job-detail-modal');
|
|
|
|
function openJobModal(jobId) {
|
|
const job = jobsData.find(j => j.id === jobId);
|
|
if (!job) return;
|
|
|
|
// Populate Data
|
|
document.getElementById('modal-title').textContent = job.title;
|
|
document.getElementById('modal-location').textContent = job.location;
|
|
document.getElementById('modal-desc').textContent = job.desc;
|
|
|
|
const tag = document.getElementById('modal-tag');
|
|
tag.textContent = job.type;
|
|
tag.className = `inline-flex items-center justify-center px-2.5 py-0.5 rounded-full text-xs font-semibold border ${job.color}`;
|
|
|
|
const respList = document.getElementById('modal-responsibilities');
|
|
respList.innerHTML = job.responsibilities.map(item => `<li>${item}</li>`).join('');
|
|
|
|
const reqList = document.getElementById('modal-requirements');
|
|
reqList.innerHTML = job.requirements.map(item => `<li>${item}</li>`).join('');
|
|
|
|
const subject = encodeURIComponent(`Application for ${job.title} - [Your Name]`);
|
|
const body = encodeURIComponent(`Dear Hiring Team,\n\nI am writing to express my interest in the ${job.title} position.\n\nPlease find my resume attached.\n\nBest regards,\n[Your Name]`);
|
|
document.getElementById('modal-apply-btn').href = `mailto:${email}?subject=${subject}&body=${body}`;
|
|
|
|
// [修复] 强制重置滚动条位置到顶部
|
|
document.getElementById('modal-body').scrollTop = 0;
|
|
|
|
modal.classList.add('open');
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
|
|
function closeJobModal() {
|
|
modal.classList.remove('open');
|
|
document.body.style.overflow = '';
|
|
}
|
|
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape' && modal.classList.contains('open')) {
|
|
closeJobModal();
|
|
}
|
|
});
|
|
|
|
function renderJobs(data) {
|
|
container.innerHTML = '';
|
|
|
|
if (data.length === 0) {
|
|
noResultsEl.classList.remove('hidden');
|
|
return;
|
|
} else {
|
|
noResultsEl.classList.add('hidden');
|
|
}
|
|
|
|
data.forEach((job, index) => {
|
|
const slide = document.createElement('div');
|
|
slide.className = 'swiper-slide w-[85vw] sm:w-[320px] md:w-[380px]';
|
|
slide.setAttribute('data-aos', 'fade-up');
|
|
slide.setAttribute('data-aos-delay', window.innerWidth < 640 ? 0 : (index % 5) * 100);
|
|
|
|
slide.innerHTML = `
|
|
<div class="flex flex-col h-full rounded-xl bg-white dark:bg-[#1a2632] shadow-[0_4px_20px_rgb(0,0,0,0.06)] hover:shadow-[0_20px_40px_rgb(0,0,0,0.1)] dark:shadow-none dark:hover:shadow-[0_20px_40px_rgba(0,0,0,0.4)] overflow-hidden group transition-all duration-300 border border-gray-100 dark:border-gray-800 hover:border-gray-200 dark:hover:border-gray-700">
|
|
<div class="h-40 sm:h-48 w-full relative overflow-hidden">
|
|
<div class="card-image-bg absolute inset-0 bg-cover bg-center" style='background-image: url("${job.image}");'></div>
|
|
<div class="absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent"></div>
|
|
<div class="absolute bottom-4 left-4 z-10">
|
|
<span class="inline-flex items-center justify-center px-2.5 py-0.5 sm:px-3 sm:py-1 rounded-full text-xs font-semibold ${job.color} backdrop-blur-md shadow-sm border border-white/10">${job.type}</span>
|
|
</div>
|
|
</div>
|
|
<div class="p-5 sm:p-6 flex flex-col flex-1 gap-3 sm:gap-4">
|
|
<div class="flex-1">
|
|
<h3 class="text-xl sm:text-2xl text-[#111418] dark:text-white leading-tight mb-2 group-hover:text-primary transition-colors">${job.title}</h3>
|
|
<div class="flex items-center gap-2 text-[#617589] dark:text-gray-400 text-xs sm:text-sm mb-3 sm:mb-4">
|
|
<span class="material-symbols-outlined text-sm sm:text-base"></span><span>${job.location}</span>
|
|
<span class="w-1 h-1 bg-gray-300 rounded-full mx-1"></span>
|
|
<span class="material-symbols-outlined text-sm sm:text-base"></span><span>Full-time</span>
|
|
</div>
|
|
<p class="text-[#617589] dark:text-gray-400 text-sm line-clamp-2 leading-relaxed">${job.desc}</p>
|
|
</div>
|
|
<button onclick="openJobModal(${job.id})" class="mt-auto w-full flex items-center justify-center gap-2 rounded-lg h-10 sm:h-12 bg-white dark:bg-gray-800 border-2 border-gray-100 dark:border-gray-700 text-[#111418] dark:text-white text-sm hover:border-primary hover:text-primary dark:hover:border-primary dark:hover:text-primary transition-all duration-300 group/btn active:scale-95">
|
|
View Details
|
|
</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
container.appendChild(slide);
|
|
});
|
|
}
|
|
|
|
function initSwiper() {
|
|
if (swiperInstance) {
|
|
swiperInstance.destroy(true, true);
|
|
}
|
|
|
|
swiperInstance = new Swiper(".mySwiper", {
|
|
slidesPerView: "auto",
|
|
centeredSlides: window.innerWidth < 640,
|
|
spaceBetween: 16,
|
|
grabCursor: true,
|
|
speed: 600,
|
|
resistance: true,
|
|
resistanceRatio: 0.65,
|
|
observer: true,
|
|
observeParents: true,
|
|
breakpoints: {
|
|
640: {
|
|
centeredSlides: false,
|
|
spaceBetween: 24,
|
|
}
|
|
},
|
|
navigation: {
|
|
nextEl: ".swiper-button-next-custom",
|
|
prevEl: ".swiper-button-prev-custom",
|
|
},
|
|
scrollbar: {
|
|
el: ".swiper-scrollbar",
|
|
draggable: true,
|
|
snapOnRelease: false,
|
|
},
|
|
mousewheel: {
|
|
forceToAxis: true,
|
|
},
|
|
keyboard: {
|
|
enabled: true,
|
|
onlyInViewport: true,
|
|
},
|
|
on: {
|
|
init: function(sw) { updateCounter(sw); },
|
|
slideChange: function(sw) { updateCounter(sw); },
|
|
slidesLengthChange: function(sw) { updateCounter(sw); },
|
|
resize: function(sw) {
|
|
sw.params.centeredSlides = window.innerWidth < 640;
|
|
sw.update();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateCounter(sw) {
|
|
const currentEl = document.getElementById('slide-current');
|
|
const totalEl = document.getElementById('slide-total');
|
|
|
|
let count = sw.slides.length;
|
|
if(count === 0) {
|
|
currentEl.textContent = "00";
|
|
totalEl.textContent = "00";
|
|
return;
|
|
}
|
|
let current = sw.activeIndex + 1;
|
|
currentEl.textContent = String(current).padStart(2, '0');
|
|
totalEl.textContent = String(count).padStart(2, '0');
|
|
}
|
|
|
|
searchInput.addEventListener('input', (e) => {
|
|
const query = e.target.value.toLowerCase().trim();
|
|
const filtered = jobsData.filter(job =>
|
|
job.title.toLowerCase().includes(query) ||
|
|
job.type.toLowerCase().includes(query)
|
|
);
|
|
renderJobs(filtered);
|
|
initSwiper();
|
|
setTimeout(() => { AOS.refresh(); }, 100);
|
|
});
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
AOS.init({
|
|
once: true,
|
|
offset: 30,
|
|
duration: 800,
|
|
easing: 'ease-out-cubic',
|
|
});
|
|
renderJobs(jobsData);
|
|
initSwiper();
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|