7 changed files with 484 additions and 261 deletions
Binary file not shown.
@ -1,7 +1,13 @@ |
|||||||
import Router from "./Router"; |
import Router from "./Router"; |
||||||
|
import ScrollToTop from "./components/ScrollToTop"; |
||||||
|
|
||||||
function App() { |
function App() { |
||||||
return <Router />; |
return ( |
||||||
|
<> |
||||||
|
<ScrollToTop /> |
||||||
|
<Router /> |
||||||
|
</> |
||||||
|
); |
||||||
} |
} |
||||||
|
|
||||||
export default App; |
export default App; |
||||||
|
|||||||
@ -0,0 +1,22 @@ |
|||||||
|
import { useEffect } from "react"; |
||||||
|
import { useLocation } from "react-router-dom"; |
||||||
|
import { ScrollTrigger } from "gsap/ScrollTrigger"; |
||||||
|
|
||||||
|
export default function ScrollToTop() { |
||||||
|
const { pathname } = useLocation(); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
// 이전 페이지 ScrollTrigger 전부 정리 (핀 잔재 제거) |
||||||
|
ScrollTrigger.getAll().forEach((t) => t.kill()); |
||||||
|
ScrollTrigger.clearScrollMemory(); |
||||||
|
window.history.scrollRestoration = "manual"; |
||||||
|
|
||||||
|
// 맨 위로 이동 |
||||||
|
window.scrollTo({ top: 0, behavior: "instant" }); |
||||||
|
|
||||||
|
// DOM 안정화 후 refresh |
||||||
|
requestAnimationFrame(() => ScrollTrigger.refresh()); |
||||||
|
}, [pathname]); |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
@ -1,157 +1,246 @@ |
|||||||
|
import { useEffect, useRef } from "react"; |
||||||
|
import { Link } from "react-router-dom"; |
||||||
|
import { gsap } from "gsap"; |
||||||
|
import { ScrollTrigger } from "gsap/ScrollTrigger"; |
||||||
import SubHero from "../../components/SubHero"; |
import SubHero from "../../components/SubHero"; |
||||||
import useFadeIn from "../../hooks/useFadeIn"; |
|
||||||
|
gsap.registerPlugin(ScrollTrigger); |
||||||
|
|
||||||
const COMPANY_NAV = [ |
const COMPANY_NAV = [ |
||||||
{ label: "회사소개", to: "/company/about" }, |
{ label: "회사소개", to: "/company/about" }, |
||||||
{ label: "연혁", to: "/company/history" }, |
{ label: "연혁", to: "/company/history" }, |
||||||
{ label: "고객 및 협력사", to: "/company/partners" }, |
{ label: "고객 및 협력사", to: "/company/partners" }, |
||||||
{ label: "찾아오시는 길", to: "/company/location" }, |
{ label: "찾아오시는 길", to: "/company/location" }, |
||||||
]; |
]; |
||||||
|
|
||||||
|
const STATS = [ |
||||||
|
{ num: 2010, suffix: "", label: "설립연도" }, |
||||||
|
{ num: 50, suffix: "+", label: "완료 프로젝트" }, |
||||||
|
{ num: 15, suffix: "+", label: "주요 고객사" }, |
||||||
|
{ num: 10, suffix: "+", label: "R&D 전문인력" }, |
||||||
|
]; |
||||||
|
|
||||||
const VALUES = [ |
const VALUES = [ |
||||||
{ |
{ num: "01", title: "기술 혁신", desc: "항공 데이터와 UTM 기술의 경계를 지속적으로 확장하며 미래 모빌리티 시대를 선도합니다.", img: "/images/img1.jpg" }, |
||||||
title: "기술 혁신", |
{ num: "02", title: "신뢰와 책임", desc: "공공·항공 분야의 핵심 인프라를 다루는 만큼 모든 서비스에 안전과 신뢰를 최우선으로 합니다.", img: "/images/img2.jpg" }, |
||||||
desc: "항공 데이터와 UTM 기술의 경계를 지속적으로 확장하며, 미래 모빌리티 시대를 선도합니다.", |
{ num: "03", title: "파트너십", desc: "고객사와 장기 파트너로서 구축부터 운영·유지보수까지 전 과정을 함께합니다.", img: "/images/img3.jpg" }, |
||||||
icon: ( |
{ num: "04", title: "전문성", desc: "항공 IT 분야 10년 이상의 전문 인력이 SI, R&D, 솔루션 개발을 일관되게 수행합니다.", img: "/images/img4.jpg" }, |
||||||
<svg viewBox="0 0 24 24"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg> |
|
||||||
), |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "신뢰와 책임", |
|
||||||
desc: "공공·항공 분야의 핵심 인프라를 다루는 만큼, 모든 서비스에 안전과 신뢰를 최우선으로 합니다.", |
|
||||||
icon: ( |
|
||||||
<svg viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg> |
|
||||||
), |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "파트너십", |
|
||||||
desc: "고객사와 장기 파트너로서 구축부터 운영·유지보수까지 전 과정을 함께합니다.", |
|
||||||
icon: ( |
|
||||||
<svg viewBox="0 0 24 24"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg> |
|
||||||
), |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "전문성", |
|
||||||
desc: "항공 IT 분야 10년 이상의 전문 인력이 SI, R&D, 솔루션 개발을 일관되게 수행합니다.", |
|
||||||
icon: ( |
|
||||||
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M12 8v4l3 3"/></svg> |
|
||||||
), |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "지속 성장", |
|
||||||
desc: "UAM·UATM 등 차세대 항공 기술을 선행 연구하며, 산업 변화에 능동적으로 대응합니다.", |
|
||||||
icon: ( |
|
||||||
<svg viewBox="0 0 24 24"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg> |
|
||||||
), |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "사회적 가치", |
|
||||||
desc: "안전한 하늘길과 신뢰 가능한 IT 인프라를 통해 사회 전반에 기여하는 기업으로 성장합니다.", |
|
||||||
icon: ( |
|
||||||
<svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg> |
|
||||||
), |
|
||||||
}, |
|
||||||
]; |
]; |
||||||
|
|
||||||
const AWARDS = [ |
const AWARDS = [ |
||||||
{ title: "인천 항공산업 선도기업 유망기업 선정", desc: "인천시 · 인천테크노파크" }, |
{ year: "2022", title: "인천 항공산업 선도기업 유망기업 선정", org: "인천시 · 인천테크노파크" }, |
||||||
{ title: "소프트웨어 품질인증 GS 인증 획득", desc: "한국정보통신기술협회(TTA)" }, |
{ year: "2021", title: "소프트웨어 품질인증 GS 인증 획득", org: "한국정보통신기술협회(TTA)" }, |
||||||
{ title: "기업부설연구소 인정", desc: "한국산업기술진흥협회" }, |
{ year: "2021", title: "기업부설연구소 인정", org: "한국산업기술진흥협회" }, |
||||||
{ title: "조달청 우수제품 지정", desc: "비행상황관제 시스템" }, |
{ year: "2020", title: "조달청 우수제품 지정", org: "비행상황관제 시스템" }, |
||||||
]; |
]; |
||||||
|
|
||||||
|
function animateCount(el, target, suffix, duration = 1600) { |
||||||
|
const from = target > 100 ? target - 4 : 0; |
||||||
|
let start = null; |
||||||
|
const step = ts => { |
||||||
|
if (!start) start = ts; |
||||||
|
const p = Math.min((ts - start) / duration, 1); |
||||||
|
const ease = 1 - Math.pow(1 - p, 3); |
||||||
|
el.textContent = Math.floor(from + (target - from) * ease) + suffix; |
||||||
|
if (p < 1) requestAnimationFrame(step); |
||||||
|
}; |
||||||
|
requestAnimationFrame(step); |
||||||
|
} |
||||||
|
|
||||||
export default function AboutPage() { |
export default function AboutPage() { |
||||||
const ref = useFadeIn(); |
const videoRef = useRef(null); |
||||||
|
const videoSecRef = useRef(null); |
||||||
|
const statRefs = useRef([]); |
||||||
|
const statDone = useRef(false); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
const ctx = gsap.context(() => { |
||||||
|
// 영상 패럴랙스 |
||||||
|
gsap.to(videoRef.current, { |
||||||
|
scale: 1.1, |
||||||
|
scrollTrigger: { trigger: videoSecRef.current, start: "top top", end: "bottom top", scrub: 2 }, |
||||||
|
}); |
||||||
|
gsap.to(".ab-vid-txt", { |
||||||
|
y: -80, opacity: 0, |
||||||
|
scrollTrigger: { trigger: videoSecRef.current, start: "top top", end: "55% top", scrub: 1 }, |
||||||
|
}); |
||||||
|
|
||||||
|
// 철학 텍스트 라인 |
||||||
|
gsap.fromTo(".ab-phil-line", |
||||||
|
{ opacity: 0, x: -40 }, |
||||||
|
{ opacity: 1, x: 0, stagger: 0.18, duration: 1, ease: "power3.out", |
||||||
|
scrollTrigger: { trigger: ".ab-phil", start: "top 68%" } } |
||||||
|
); |
||||||
|
// 철학 오른쪽 |
||||||
|
gsap.fromTo(".ab-phil-right", |
||||||
|
{ opacity: 0, x: 50 }, |
||||||
|
{ opacity: 1, x: 0, duration: 1.1, ease: "power3.out", |
||||||
|
scrollTrigger: { trigger: ".ab-phil", start: "top 68%" } } |
||||||
|
); |
||||||
|
gsap.fromTo(".ab-phil-body", |
||||||
|
{ opacity: 0, y: 24 }, |
||||||
|
{ opacity: 1, y: 0, duration: 0.8, ease: "power2.out", |
||||||
|
scrollTrigger: { trigger: ".ab-phil", start: "top 55%" } } |
||||||
|
); |
||||||
|
|
||||||
|
// 핵심가치 |
||||||
|
gsap.fromTo(".ab-val-item", |
||||||
|
{ opacity: 0, y: 40 }, |
||||||
|
{ opacity: 1, y: 0, stagger: 0.1, duration: 0.7, ease: "power3.out", |
||||||
|
scrollTrigger: { trigger: ".ab-vals", start: "top 72%" } } |
||||||
|
); |
||||||
|
|
||||||
|
// 수상 |
||||||
|
gsap.fromTo(".ab-awd-row", |
||||||
|
{ opacity: 0, y: 22 }, |
||||||
|
{ opacity: 1, y: 0, stagger: 0.1, duration: 0.6, ease: "power2.out", |
||||||
|
scrollTrigger: { trigger: ".ab-awds", start: "top 76%" } } |
||||||
|
); |
||||||
|
|
||||||
|
// CTA |
||||||
|
gsap.fromTo(".ab-cta-inner > *", |
||||||
|
{ opacity: 0, y: 28 }, |
||||||
|
{ opacity: 1, y: 0, stagger: 0.14, duration: 0.8, ease: "power2.out", |
||||||
|
scrollTrigger: { trigger: ".ab-cta", start: "top 75%" } } |
||||||
|
); |
||||||
|
|
||||||
|
// stats fade |
||||||
|
gsap.fromTo(".ab-si", |
||||||
|
{ opacity: 0, y: 32 }, |
||||||
|
{ opacity: 1, y: 0, stagger: 0.1, duration: 0.7, ease: "power3.out", |
||||||
|
scrollTrigger: { |
||||||
|
trigger: ".ab-stats", |
||||||
|
start: "top 78%", |
||||||
|
onEnter: () => { |
||||||
|
if (statDone.current) return; |
||||||
|
statDone.current = true; |
||||||
|
statRefs.current.forEach((el, i) => { |
||||||
|
if (!el) return; |
||||||
|
setTimeout(() => animateCount(el, STATS[i].num, STATS[i].suffix), i * 80); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
return () => ctx.revert(); |
||||||
|
}, []); |
||||||
|
|
||||||
return ( |
return ( |
||||||
<article ref={ref}> |
<article> |
||||||
<SubHero |
<SubHero |
||||||
label="Company" |
title={"가치를 실천하는\n항공 IT 전문기업"} |
||||||
title="가치를 실천하는 |
desc="팔네트웍스는 항공 데이터와 통합 관제 기술을 기반으로 안전한 하늘길을 만들어갑니다." |
||||||
항공 IT 전문기업" |
|
||||||
desc="팔네트웍스는 항공 데이터와 통합 관제 기술을 기반으로 안전한 하늘길과 신뢰할 수 있는 IT 서비스를 만들어갑니다." |
|
||||||
navItems={COMPANY_NAV} |
navItems={COMPANY_NAV} |
||||||
|
bgImage="/images/hero1.png" |
||||||
/> |
/> |
||||||
|
|
||||||
<div className="sub-content"> |
{/* 수치 */} |
||||||
|
<section className="ab-stats"> |
||||||
{/* 회사 개요 */} |
<div className="ab-stats-inner"> |
||||||
<section className="sub-section"> |
<span className="ab-stats-ew">PAL Networks in Numbers</span> |
||||||
<div className="about-overview"> |
<div className="ab-stats-grid"> |
||||||
<div className="about-overview-text sub-fade-in"> |
{STATS.map((s, i) => ( |
||||||
<span className="sub-section-eyebrow">About PAL Networks</span> |
<div className="ab-si" key={s.label}> |
||||||
<h2 className="sub-section-title">항공산업의 기술혁신을 |
<strong className="ab-si-num" ref={el => statRefs.current[i] = el}>{s.num}{s.suffix}</strong> |
||||||
선도하는 파트너</h2> |
<span className="ab-si-lbl">{s.label}</span> |
||||||
<p className="sub-section-lead"> |
<span className="ab-si-bar" /> |
||||||
팔네트웍스(PAL Networks)는 2010년 설립 이후 항공 예약 플랫폼, 비행상황관제 시스템, UTM(무인항공기 교통관리) 솔루션 등 항공 IT 분야의 핵심 기술을 개발·운영해 온 전문 기업입니다. |
|
||||||
</p> |
|
||||||
<p className="sub-section-lead" style={{ marginTop: "16px" }}> |
|
||||||
공공·민간 고객사의 시스템 구축부터 장기 운영·유지보수까지 전 과정을 책임지며, 인천광역시 로봇랜드에 본사를 두고 항공 미래 모빌리티(UAM/UATM) 기술을 선행 연구하고 있습니다. |
|
||||||
</p> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div className="about-overview-stats sub-fade-in"> |
|
||||||
<div className="about-stat"> |
|
||||||
<span className="about-stat-num">2010</span> |
|
||||||
<span className="about-stat-label">설립연도</span> |
|
||||||
</div> |
</div> |
||||||
<div className="about-stat"> |
))} |
||||||
<span className="about-stat-num">50<span className="about-stat-unit">+</span></span> |
</div> |
||||||
<span className="about-stat-label">완료 프로젝트</span> |
</div> |
||||||
</div> |
</section> |
||||||
<div className="about-stat"> |
|
||||||
<span className="about-stat-num">15<span className="about-stat-unit">+</span></span> |
{/* 영상 */} |
||||||
<span className="about-stat-label">주요 고객사</span> |
<section className="ab-vid" ref={videoSecRef}> |
||||||
</div> |
<video ref={videoRef} className="ab-vid-bg" src="/images/uam.mp4" autoPlay muted loop playsInline /> |
||||||
<div className="about-stat"> |
<div className="ab-vid-overlay" /> |
||||||
<span className="about-stat-num">10<span className="about-stat-unit">+</span></span> |
<div className="ab-vid-txt"> |
||||||
<span className="about-stat-label">R&D 전문 인력</span> |
<span className="ab-vid-kicker">PAL Networks × UAM</span> |
||||||
|
<h2 className="ab-vid-title">미래의 하늘을<br />설계합니다</h2> |
||||||
|
<p className="ab-vid-desc">도심항공교통(UAM)의 안전한 운항을 위한<br />통합 관제 기술을 연구·개발합니다</p> |
||||||
|
</div> |
||||||
|
</section> |
||||||
|
|
||||||
|
{/* 철학 */} |
||||||
|
<section className="ab-phil"> |
||||||
|
<div className="ab-phil-inner"> |
||||||
|
<div className="ab-phil-left"> |
||||||
|
<span className="ab-phil-ew">Our Philosophy</span> |
||||||
|
<span className="ab-phil-line">항공산업의</span> |
||||||
|
<span className="ab-phil-line">기술혁신을</span> |
||||||
|
<span className="ab-phil-line ab-phil-line--pt">선도합니다.</span> |
||||||
|
</div> |
||||||
|
<div className="ab-phil-right"> |
||||||
|
<div className="ab-phil-img-wrap"> |
||||||
|
<img src="/images/img1.jpg" alt="항공 관제" className="ab-phil-img" /> |
||||||
|
<div className="ab-phil-badge"> |
||||||
|
<span>2010년 설립 이후</span> |
||||||
|
<strong>항공 IT 한 길</strong> |
||||||
</div> |
</div> |
||||||
</div> |
</div> |
||||||
|
<p className="ab-phil-body">팔네트웍스는 2010년 설립 이후 항공 예약 플랫폼, 비행상황관제 시스템, UTM 솔루션까지 항공 IT 분야의 핵심 기술을 꾸준히 개발해왔습니다. 인천광역시 로봇랜드에서 UAM/UATM 미래 기술을 선행 연구하고 있습니다.</p> |
||||||
</div> |
</div> |
||||||
</section> |
</div> |
||||||
|
</section> |
||||||
{/* 핵심 가치 */} |
|
||||||
<section className="sub-section"> |
{/* 핵심가치 */} |
||||||
<span className="sub-section-eyebrow sub-fade-in">Core Values</span> |
<section className="ab-vals"> |
||||||
<h2 className="sub-section-title sub-fade-in">우리가 지키는 6가지 가치</h2> |
<div className="ab-vals-inner"> |
||||||
<div className="about-values"> |
<span className="ab-vals-ew">Core Values</span> |
||||||
{VALUES.map((v, i) => ( |
<h2 className="ab-vals-title">우리가 지키는 가치</h2> |
||||||
<div |
<div className="ab-vals-list"> |
||||||
key={v.title} |
{VALUES.map(v => ( |
||||||
className="about-value-card sub-fade-in" |
<div className="ab-val-item" key={v.num}> |
||||||
style={{ transitionDelay: `${i * 60}ms` }} |
<span className="ab-val-num">{v.num}</span> |
||||||
> |
<div className="ab-val-body"> |
||||||
<div className="about-value-icon">{v.icon}</div> |
<h3 className="ab-val-name">{v.title}</h3> |
||||||
<h3>{v.title}</h3> |
<p className="ab-val-desc">{v.desc}</p> |
||||||
<p>{v.desc}</p> |
</div> |
||||||
|
<div className="ab-val-img-wrap"> |
||||||
|
<img src={v.img} alt={v.title} className="ab-val-img" /> |
||||||
|
</div> |
||||||
</div> |
</div> |
||||||
))} |
))} |
||||||
</div> |
</div> |
||||||
</section> |
</div> |
||||||
|
</section> |
||||||
|
|
||||||
{/* 인증 및 수상 */} |
{/* 수상 */} |
||||||
<section className="sub-section"> |
<section className="ab-awds"> |
||||||
<span className="sub-section-eyebrow sub-fade-in">Certifications & Awards</span> |
<div className="ab-awds-inner"> |
||||||
<h2 className="sub-section-title sub-fade-in">인증 및 수상 이력</h2> |
<span className="ab-awds-ew">Certifications & Awards</span> |
||||||
<div className="about-awards"> |
<h2 className="ab-awds-title">인증 및 수상</h2> |
||||||
|
<ul className="ab-awds-list"> |
||||||
{AWARDS.map((a, i) => ( |
{AWARDS.map((a, i) => ( |
||||||
<div |
<li className="ab-awd-row" key={i}> |
||||||
key={a.title} |
<span className="ab-awd-yr">{a.year}</span> |
||||||
className="about-award-item sub-fade-in" |
<div className="ab-awd-bar" /> |
||||||
style={{ transitionDelay: `${i * 80}ms` }} |
|
||||||
> |
|
||||||
<div className="about-award-dot" /> |
|
||||||
<div> |
<div> |
||||||
<h4>{a.title}</h4> |
<strong className="ab-awd-name">{a.title}</strong> |
||||||
<p>{a.desc}</p> |
<span className="ab-awd-org">{a.org}</span> |
||||||
</div> |
</div> |
||||||
</div> |
</li> |
||||||
))} |
))} |
||||||
</div> |
</ul> |
||||||
</section> |
</div> |
||||||
|
</section> |
||||||
|
|
||||||
</div> |
{/* CTA */} |
||||||
|
<section className="ab-cta"> |
||||||
|
<div className="ab-cta-bg" /> |
||||||
|
<div className="ab-cta-glow" /> |
||||||
|
<div className="ab-cta-inner"> |
||||||
|
<span className="ab-cta-chip">Contact Us</span> |
||||||
|
<h2 className="ab-cta-title">팔네트웍스와<br />함께하세요</h2> |
||||||
|
<p className="ab-cta-desc">파트너십 문의, 채용, 사업 협력 등 무엇이든 편하게 연락주세요.</p> |
||||||
|
<div className="ab-cta-btns"> |
||||||
|
<Link to="/contact/inquiry" className="ab-cta-btn ab-cta-btn--w">문의하기</Link> |
||||||
|
<Link to="/contact/recruit" className="ab-cta-btn ab-cta-btn--g">채용 안내</Link> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</section> |
||||||
</article> |
</article> |
||||||
); |
); |
||||||
} |
} |
||||||
|
|||||||
Loading…
Reference in new issue