522 lines
29 KiB
HTML
522 lines
29 KiB
HTML
<!doctype html>
|
||
<html lang="fa" dir="rtl">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>مبانی طراحی رابط کاربری — آرش پاکدل · ایلو</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;500;600;700;800&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="styles.css" />
|
||
|
||
<style>
|
||
:root { --max-w: 1200px; }
|
||
body { background: var(--surface); }
|
||
|
||
.nav { position: sticky; top: 0; z-index: 50; background: rgba(255,255,255,.9); backdrop-filter: blur(12px); border-bottom: 1px solid var(--line-soft); }
|
||
.nav-inner { max-width: var(--max-w); margin: 0 auto; display: flex; align-items: center; gap: 24px; padding: 12px 24px; }
|
||
.nav-brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 16px; text-decoration: none; color: inherit; }
|
||
.nav-mark { width: 30px; height: 30px; border-radius: 8px; background: linear-gradient(140deg, var(--accent), var(--accent-2)); color: white; font-family: var(--font-en); font-weight: 700; font-size: 12px; display: grid; place-items: center; }
|
||
.crumbs-mini { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink-3); margin-inline-start: 12px; }
|
||
.crumbs-mini span:last-child { color: var(--ink-2); }
|
||
|
||
.ctop { max-width: var(--max-w); margin: 0 auto; padding: 28px 24px 0; }
|
||
.share-bar {
|
||
background: linear-gradient(135deg, var(--accent-soft), oklch(0.97 0.03 80));
|
||
border-radius: 12px;
|
||
padding: 12px 16px;
|
||
display: flex; align-items: center; gap: 12px;
|
||
font-size: 13px;
|
||
margin-bottom: 24px;
|
||
}
|
||
.share-bar .ic-wrap { width: 28px; height: 28px; border-radius: 8px; background: var(--accent); color: white; display: grid; place-items: center; }
|
||
|
||
/* hero */
|
||
.chero {
|
||
max-width: var(--max-w); margin: 0 auto;
|
||
padding: 0 24px;
|
||
display: grid; grid-template-columns: 1.5fr 1fr;
|
||
gap: 32px;
|
||
align-items: flex-start;
|
||
}
|
||
.chero-left { display: flex; flex-direction: column; gap: 18px; }
|
||
.chips { display: flex; gap: 8px; flex-wrap: wrap; }
|
||
.chero h1 { font-size: 40px; line-height: 1.2; letter-spacing: -0.02em; font-weight: 700; margin: 0; }
|
||
.chero .lead { font-size: 17px; line-height: 1.65; color: var(--ink-2); margin: 0; }
|
||
.chero-stats { display: flex; gap: 18px; font-size: 13px; color: var(--ink-3); flex-wrap: wrap; }
|
||
.chero-stats b { color: var(--ink); font-family: var(--font-num); font-weight: 600; }
|
||
.ins-row {
|
||
display: flex; align-items: center; gap: 12px;
|
||
padding: 14px 16px;
|
||
background: var(--surface-2);
|
||
border-radius: 12px;
|
||
border: 1px solid var(--line-soft);
|
||
}
|
||
|
||
/* preview */
|
||
.preview {
|
||
background: oklch(0.78 0.12 40);
|
||
border-radius: 16px;
|
||
aspect-ratio: 16/10;
|
||
position: relative;
|
||
overflow: hidden;
|
||
cursor: pointer;
|
||
box-shadow: 0 16px 40px oklch(0.6 0.10 40 / .25);
|
||
display: grid; place-items: center;
|
||
}
|
||
.preview .play-big {
|
||
width: 80px; height: 80px; border-radius: 50%;
|
||
background: rgba(255,255,255,.95); color: var(--accent);
|
||
display: grid; place-items: center;
|
||
box-shadow: 0 8px 24px rgba(0,0,0,.2);
|
||
transition: transform .2s;
|
||
}
|
||
.preview:hover .play-big { transform: scale(1.08); }
|
||
.preview .duration { position: absolute; bottom: 14px; inset-inline-start: 14px; background: rgba(0,0,0,.6); color: white; padding: 5px 12px; border-radius: 999px; font-size: 12px; }
|
||
|
||
.price-card {
|
||
background: var(--surface);
|
||
border: 1px solid var(--line);
|
||
border-radius: 14px;
|
||
padding: 20px;
|
||
box-shadow: 0 6px 20px rgba(0,0,0,.06);
|
||
display: flex; flex-direction: column; gap: 14px;
|
||
}
|
||
.price-row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
|
||
.price-now { font-size: 30px; font-weight: 700; font-family: var(--font-num); }
|
||
.price-unit { color: var(--ink-3); font-size: 13px; }
|
||
.price-old { font-family: var(--font-num); font-size: 14px; color: var(--ink-3); text-decoration: line-through; margin-inline-start: auto; }
|
||
.price-pct { background: var(--accent-soft); color: var(--accent-ink); padding: 3px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; }
|
||
.timer-pill { background: oklch(0.96 0.04 30); color: oklch(0.45 0.13 25); padding: 8px 12px; border-radius: 8px; font-size: 12px; display: flex; align-items: center; gap: 8px; font-family: var(--font-num); }
|
||
.price-ctas { display: flex; flex-direction: column; gap: 8px; }
|
||
.price-ctas .btn.full { width: 100%; justify-content: center; padding: 12px; font-size: 14px; font-weight: 600; }
|
||
.price-incl { display: flex; flex-direction: column; gap: 10px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
|
||
.price-incl-row { display: flex; gap: 10px; align-items: center; font-size: 12.5px; color: var(--ink-2); }
|
||
.price-incl-row .ic { color: var(--ink-3); flex-shrink: 0; }
|
||
|
||
/* sections */
|
||
section.s { max-width: var(--max-w); margin: 0 auto; padding: 56px 24px; }
|
||
.grid-main { display: grid; grid-template-columns: 1.5fr 1fr; gap: 32px; align-items: flex-start; }
|
||
.sticky-rail { position: sticky; top: 80px; }
|
||
|
||
.block-title { font-size: 22px; font-weight: 700; letter-spacing: -0.015em; margin: 0 0 20px; }
|
||
|
||
/* highlights box */
|
||
.highlights {
|
||
background: var(--surface-2);
|
||
border-radius: 16px;
|
||
padding: 28px;
|
||
border: 1px solid var(--line-soft);
|
||
}
|
||
.highlights-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
|
||
.h-item { display: flex; gap: 10px; font-size: 14px; line-height: 1.6; }
|
||
.h-check { width: 22px; height: 22px; border-radius: 6px; background: var(--accent-soft); color: var(--accent); display: grid; place-items: center; flex-shrink: 0; margin-top: 1px; }
|
||
|
||
/* curriculum */
|
||
.curr-mod { border: 1px solid var(--line); border-radius: 12px; margin-bottom: 10px; overflow: hidden; background: var(--surface); }
|
||
.curr-mod-h { padding: 16px 18px; display: flex; align-items: center; gap: 12px; cursor: pointer; }
|
||
.curr-mod-num { width: 30px; height: 30px; border-radius: 8px; background: var(--accent-soft); color: var(--accent-ink); display: grid; place-items: center; font-family: var(--font-num); font-weight: 700; font-size: 13px; }
|
||
.curr-mod-ttl { font-size: 14.5px; font-weight: 600; }
|
||
.curr-mod-meta { font-size: 12px; color: var(--ink-3); margin-inline-start: auto; font-family: var(--font-num); }
|
||
.curr-mod-body { border-top: 1px solid var(--line-soft); padding: 4px 0; }
|
||
.curr-lesson { display: flex; align-items: center; gap: 12px; padding: 10px 18px; font-size: 13px; }
|
||
.curr-lesson .li { width: 22px; height: 22px; border-radius: 6px; background: var(--surface-2); color: var(--ink-3); display: grid; place-items: center; }
|
||
.curr-lesson .free { background: var(--accent-soft); color: var(--accent-ink); padding: 2px 8px; border-radius: 999px; font-size: 10.5px; }
|
||
.curr-lesson .dur { color: var(--ink-3); margin-inline-start: auto; font-family: var(--font-num); font-size: 12px; }
|
||
|
||
/* about instructor */
|
||
.about-ins {
|
||
background: var(--surface);
|
||
border: 1px solid var(--line);
|
||
border-radius: 16px;
|
||
padding: 28px;
|
||
display: grid; grid-template-columns: auto 1fr; gap: 20px;
|
||
}
|
||
.about-ins .av-xl { width: 88px; height: 88px; border-radius: 50%; display: grid; place-items: center; color: white; font-size: 24px; font-weight: 700; }
|
||
.about-ins p { margin: 12px 0 0; font-size: 14px; line-height: 1.8; color: var(--ink-2); }
|
||
.about-stats { display: flex; gap: 24px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
|
||
.about-stats div { font-size: 12px; color: var(--ink-3); }
|
||
.about-stats b { display: block; font-size: 17px; color: var(--ink); font-family: var(--font-num); }
|
||
|
||
/* reviews */
|
||
.reviews-summary {
|
||
display: grid; grid-template-columns: auto 1fr; gap: 32px; align-items: center;
|
||
padding: 24px 28px;
|
||
background: var(--surface-2);
|
||
border-radius: 16px;
|
||
margin-bottom: 20px;
|
||
}
|
||
.big-rating { font-size: 56px; font-weight: 700; font-family: var(--font-num); line-height: 1; }
|
||
.bar-row { display: flex; align-items: center; gap: 10px; font-size: 12px; margin-bottom: 6px; }
|
||
.bar-row .star-num { font-family: var(--font-num); width: 14px; }
|
||
.bar-track { flex: 1; height: 6px; background: var(--line); border-radius: 999px; overflow: hidden; }
|
||
.bar-track > i { display: block; height: 100%; background: oklch(0.74 0.13 70); border-radius: 999px; }
|
||
.bar-row .pct { width: 36px; text-align: end; color: var(--ink-3); font-family: var(--font-num); }
|
||
|
||
.review-card { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 18px; margin-bottom: 12px; }
|
||
.review-h { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
|
||
.review-stars { display: flex; gap: 1px; }
|
||
|
||
/* faq */
|
||
.faq-card { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; margin-bottom: 10px; overflow: hidden; }
|
||
.faq-q { padding: 16px 18px; display: flex; justify-content: space-between; cursor: pointer; font-size: 14px; font-weight: 600; }
|
||
.faq-a { padding: 0 18px 16px; font-size: 13.5px; color: var(--ink-2); line-height: 1.8; border-top: 1px solid var(--line-soft); padding-top: 12px; }
|
||
|
||
/* related */
|
||
.related-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
|
||
.rc { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; cursor: pointer; }
|
||
.rc:hover { border-color: var(--accent); }
|
||
.rc-img { aspect-ratio: 16/9; }
|
||
.rc-body { padding: 12px 14px; }
|
||
|
||
@media (max-width: 900px) {
|
||
.chero, .grid-main, .highlights-grid, .related-grid, .reviews-summary { grid-template-columns: 1fr; }
|
||
.chero h1 { font-size: 28px; }
|
||
.sticky-rail { position: static; }
|
||
}
|
||
</style>
|
||
|
||
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
||
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
||
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
||
</head>
|
||
<body>
|
||
<div id="root"></div>
|
||
<script type="text/babel" src="icons.jsx"></script>
|
||
<script type="text/babel" src="student-data.jsx"></script>
|
||
<script type="text/babel">
|
||
const fa = (s) => String(s).replace(/\d/g, d => '۰۱۲۳۴۵۶۷۸۹'[d]);
|
||
|
||
function Countdown() {
|
||
const [t, setT] = React.useState({ d: 1, h: 18, m: 42, s: 11 });
|
||
React.useEffect(() => {
|
||
const id = setInterval(() => {
|
||
setT(v => {
|
||
let { d, h, m, s } = v;
|
||
s--; if (s < 0) { s = 59; m--; }
|
||
if (m < 0) { m = 59; h--; }
|
||
if (h < 0) { h = 23; d--; }
|
||
if (d < 0) return v;
|
||
return { d, h, m, s };
|
||
});
|
||
}, 1000);
|
||
return () => clearInterval(id);
|
||
}, []);
|
||
return <span><b>{fa(t.d)}</b> روز <b>{fa(String(t.h).padStart(2,'0'))}</b>:<b>{fa(String(t.m).padStart(2,'0'))}</b>:<b>{fa(String(t.s).padStart(2,'0'))}</b></span>;
|
||
}
|
||
|
||
function App() {
|
||
const c = window.STUDENT_DATA.COURSE_DETAIL;
|
||
const related = window.STUDENT_DATA.CATALOG.filter(x => x.id !== c.id).slice(0, 3);
|
||
const [openMod, setOpenMod] = React.useState(0);
|
||
const [openFaq, setOpenFaq] = React.useState(-1);
|
||
const [copied, setCopied] = React.useState(false);
|
||
|
||
const copy = async () => {
|
||
try {
|
||
await navigator.clipboard.writeText(window.location.href);
|
||
setCopied(true); setTimeout(() => setCopied(false), 2000);
|
||
} catch (e) {}
|
||
};
|
||
|
||
// first lesson of each module is "free preview" for demo
|
||
const sampleLessons = [
|
||
['آشنایی با دوره', 'این درس رایگان', 'برنامهی هفت هفتهای'],
|
||
['اصول ادراک بصری', 'تئوری گشتالت', 'تئوری رنگ کاربردی', 'تایپوگرافی پایه', 'گرید و سلسلهمراتب'],
|
||
['تایپوگرافی فارسی', 'تایپوگرافی انگلیسی', 'ترکیب تایپوگرافی'],
|
||
['کامپوننتهای پایه', 'الگوهای رایج طراحی'],
|
||
['پروژه پایانی - بریف', 'تحویل و بازخورد'],
|
||
];
|
||
|
||
return (
|
||
<>
|
||
{/* nav */}
|
||
<nav className="nav">
|
||
<div className="nav-inner">
|
||
<a className="nav-brand" href="Ilo Landing.html">
|
||
<div className="nav-mark">il</div>
|
||
ایلو
|
||
</a>
|
||
<div className="crumbs-mini">
|
||
<span>دورهها</span>
|
||
<Icon name="chevron" className="ic-sm" />
|
||
<span>طراحی</span>
|
||
<Icon name="chevron" className="ic-sm" />
|
||
<span>{c.title}</span>
|
||
</div>
|
||
<div style={{ marginInlineStart: 'auto', display: 'flex', gap: 8 }}>
|
||
<a className="btn sm" href="Ilo Auth.html" style={{ textDecoration: 'none' }}>ورود</a>
|
||
<a className="btn primary sm" href="Ilo Auth.html" style={{ textDecoration: 'none' }}>ثبتنام</a>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
{/* shared-via banner (when arriving from a teacher's link) */}
|
||
<div className="ctop">
|
||
<div className="share-bar">
|
||
<div className="ic-wrap"><Icon name="link" className="ic-sm" /></div>
|
||
<div style={{ flex: 1 }}>
|
||
<b>این دوره از طرف آرش پاکدل برای شما به اشتراک گذاشته شد</b>
|
||
<span style={{ color: 'var(--ink-3)', marginInlineStart: 8, fontSize: 12 }}>· شما بهعنوان مهمان این صفحه را میبینید</span>
|
||
</div>
|
||
<button className="btn sm" onClick={copy}>
|
||
<Icon name="copy" className="ic-sm" />
|
||
{copied ? 'کپی شد ✓' : 'کپی لینک صفحه'}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* hero */}
|
||
<header className="chero">
|
||
<div className="chero-left">
|
||
<div className="chips">
|
||
<span className="pill accent">پرفروش</span>
|
||
<span className="pill">طراحی</span>
|
||
<span className="pill">{c.level}</span>
|
||
<span className="pill">بهروزرسانی: {c.updated}</span>
|
||
</div>
|
||
<h1>{c.title}</h1>
|
||
<p className="lead">{c.tagline}</p>
|
||
<div className="chero-stats">
|
||
<span><Icon name="star" className="ic-sm" style={{ color: 'oklch(0.74 0.13 70)' }} /> <b>{fa(c.rating)}</b> ({fa(c.reviews)} نظر)</span>
|
||
<span><Icon name="users" className="ic-sm" /> <b>{fa(c.students)}</b> دانشجو</span>
|
||
<span><Icon name="clock" className="ic-sm" /> <b>{fa(c.hours)}</b> ساعت محتوا</span>
|
||
<span><Icon name="video" className="ic-sm" /> <b>{fa(c.lessons)}</b> درس</span>
|
||
<span><Icon name="globe" className="ic-sm" /> {c.language}</span>
|
||
</div>
|
||
<div className="ins-row">
|
||
<div className="av av-lg" style={{ background: c.instructor.color, width: 44, height: 44 }}>{c.instructor.initials}</div>
|
||
<div style={{ flex: 1 }}>
|
||
<div style={{ fontSize: 14, fontWeight: 600 }}>توسط {c.instructor.name}</div>
|
||
<div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2 }}>{c.instructor.topic}</div>
|
||
</div>
|
||
<button className="btn sm">دنبال کردن</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<div className="preview" style={{ background: c.color, marginBottom: 16 }}>
|
||
<div className="play-big"><Icon name="play" style={{ width: 32, height: 32 }} /></div>
|
||
<div className="duration">پیشنمایش رایگان · ۲ دقیقه</div>
|
||
</div>
|
||
|
||
<div className="price-card">
|
||
<div className="price-row">
|
||
<span className="price-now">{c.price}</span>
|
||
<span className="price-unit">تومان</span>
|
||
<span className="price-old">{c.oldPrice}</span>
|
||
<span className="price-pct">{c.discount} تخفیف</span>
|
||
</div>
|
||
<div className="timer-pill">
|
||
<Icon name="clock" className="ic-sm" />
|
||
<span>این تخفیف تا <Countdown /> باقی است</span>
|
||
</div>
|
||
<div className="price-ctas">
|
||
<a className="btn primary full" href="Ilo Checkout.html?course=p1" style={{ textDecoration: 'none' }}>
|
||
<Icon name="store" className="ic-sm" />
|
||
ثبتنام در دوره
|
||
</a>
|
||
<button className="btn full" style={{ width: '100%', justifyContent: 'center', padding: '10px' }}>
|
||
<Icon name="play" className="ic-sm" /> پیشنمایش رایگان
|
||
</button>
|
||
</div>
|
||
<div className="price-incl">
|
||
{[
|
||
{ ic: 'video', t: `${fa(c.lessons)} درس · ${fa(c.hours)} ساعت ویدیو` },
|
||
{ ic: 'file', t: 'فایلهای دانلودی + تمرینات عملی' },
|
||
{ ic: 'cert', t: 'گواهی پایان دوره با امضای مدرس' },
|
||
{ ic: 'phone', t: 'دسترسی مادامالعمر، روی هر دستگاه' },
|
||
{ ic: 'check', t: 'گارانتی بازگشت ۷ روزهی وجه' },
|
||
].map((x, i) => (
|
||
<div key={i} className="price-incl-row">
|
||
<Icon name={x.ic} className="ic ic-sm" />
|
||
<span>{x.t}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
<div style={{ borderTop: '1px solid var(--line-soft)', paddingTop: 12, display: 'flex', gap: 6, justifyContent: 'center' }}>
|
||
<button className="btn sm" title="اشتراکگذاری" onClick={copy}>
|
||
<Icon name="link" className="ic-sm" /> اشتراکگذاری
|
||
</button>
|
||
<button className="btn sm"><Icon name="send" className="ic-sm" /> ارسال در بله</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<div className="grid-main" style={{ maxWidth: 'var(--max-w)', margin: '0 auto', padding: '40px 24px 0' }}>
|
||
<div>
|
||
{/* highlights */}
|
||
<div className="highlights" style={{ marginBottom: 32 }}>
|
||
<h2 className="block-title" style={{ marginBottom: 16 }}>چی یاد میگیری</h2>
|
||
<div className="highlights-grid">
|
||
{c.highlights.map((h, i) => (
|
||
<div key={i} className="h-item">
|
||
<div className="h-check"><Icon name="check" className="ic-sm" /></div>
|
||
<span>{h}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* curriculum */}
|
||
<h2 className="block-title">سرفصل دوره</h2>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16, fontSize: 13, color: 'var(--ink-3)' }}>
|
||
<span><b style={{ color: 'var(--ink)' }}>{fa(c.curriculum.length)}</b> فصل · <b style={{ color: 'var(--ink)' }}>{fa(c.lessons)}</b> درس · <b style={{ color: 'var(--ink)' }}>{fa(c.hours)}</b> ساعت</span>
|
||
<button className="btn sm" onClick={() => setOpenMod(openMod === -1 ? 0 : -1)}>{openMod === -1 ? 'باز کردن همه' : 'بستن همه'}</button>
|
||
</div>
|
||
<div style={{ marginBottom: 32 }}>
|
||
{c.curriculum.map((m, i) => (
|
||
<div key={i} className="curr-mod">
|
||
<div className="curr-mod-h" onClick={() => setOpenMod(openMod === i ? -1 : i)}>
|
||
<div className="curr-mod-num">{fa(i+1)}</div>
|
||
<div className="curr-mod-ttl">{m.title}</div>
|
||
<div className="curr-mod-meta">{fa(m.lessons)} درس · {fa(m.minutes)} دقیقه</div>
|
||
<Icon name="chevron" className="ic-sm" style={{ color: 'var(--ink-3)', transform: openMod === i ? 'rotate(90deg)' : 'rotate(0)', transition: 'transform .2s' }} />
|
||
</div>
|
||
{openMod === i && (
|
||
<div className="curr-mod-body">
|
||
{(sampleLessons[i] || []).map((lt, li) => (
|
||
<div key={li} className="curr-lesson">
|
||
<div className="li"><Icon name="play" className="ic-sm" /></div>
|
||
<span>{lt}</span>
|
||
{i === 0 && li === 1 && <span className="free">رایگان</span>}
|
||
<span className="dur">{fa(8 + li)}:۰۰</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* about instructor */}
|
||
<h2 className="block-title">درباره مدرس</h2>
|
||
<div className="about-ins" style={{ marginBottom: 32 }}>
|
||
<div className="av-xl" style={{ background: c.instructor.color }}>{c.instructor.initials}</div>
|
||
<div>
|
||
<div style={{ fontSize: 19, fontWeight: 700 }}>{c.instructor.name}</div>
|
||
<div style={{ fontSize: 13, color: 'var(--ink-3)', marginTop: 4 }}>{c.instructor.topic}</div>
|
||
<p>آرش پاکدل ۱۰ سال در شرکتهای فناوری ایرانی بهعنوان طراح ارشد محصول کار کرده و تجربهی همکاری با تیمهای مهندسی، محصول و بازاریابی را دارد. علاقهاش آموزش طراحی به زبان ساده و کاربردی است.</p>
|
||
<div className="about-stats">
|
||
<div><b>{fa(c.instructor.rating)}</b><span>امتیاز</span></div>
|
||
<div><b>{fa(c.instructor.students)}</b><span>دانشجو</span></div>
|
||
<div><b>{fa(c.instructor.courses)}</b><span>دوره</span></div>
|
||
<div><b>۱۰</b><span>سال تجربه</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* reviews */}
|
||
<h2 className="block-title">نظرات دانشجویان</h2>
|
||
<div className="reviews-summary">
|
||
<div style={{ textAlign: 'center' }}>
|
||
<div className="big-rating">{fa(c.rating)}</div>
|
||
<div style={{ display: 'flex', justifyContent: 'center', gap: 1, marginTop: 4 }}>
|
||
{[1,2,3,4,5].map(n => <Icon key={n} name="star" className="ic-sm" style={{ color: 'oklch(0.74 0.13 70)', fill: 'oklch(0.78 0.13 70)' }} />)}
|
||
</div>
|
||
<div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 6 }}>از {fa(c.reviews)} نظر</div>
|
||
</div>
|
||
<div>
|
||
{[[5,82],[4,12],[3,4],[2,1],[1,1]].map(([s, p]) => (
|
||
<div key={s} className="bar-row">
|
||
<span className="star-num">{fa(s)}</span>
|
||
<Icon name="star" className="ic-sm" style={{ color: 'oklch(0.74 0.13 70)' }} />
|
||
<div className="bar-track"><i style={{ width: p + '%' }} /></div>
|
||
<span className="pct">{fa(p)}%</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
<div style={{ marginBottom: 32 }}>
|
||
{c.reviewsList.map((r, i) => (
|
||
<div key={i} className="review-card">
|
||
<div className="review-h">
|
||
<div className="av" style={{ background: r.color }}>{r.initials}</div>
|
||
<div style={{ flex: 1 }}>
|
||
<div style={{ fontSize: 14, fontWeight: 600 }}>{r.name}</div>
|
||
<div style={{ fontSize: 11.5, color: 'var(--ink-3)' }}>{r.when}</div>
|
||
</div>
|
||
<div className="review-stars">
|
||
{[1,2,3,4,5].map(n => <Icon key={n} name="star" className="ic-sm" style={{ color: n <= r.rating ? 'oklch(0.74 0.13 70)' : 'var(--line)', fill: n <= r.rating ? 'oklch(0.78 0.13 70)' : 'transparent' }} />)}
|
||
</div>
|
||
</div>
|
||
<p style={{ margin: 0, fontSize: 13.5, lineHeight: 1.8, color: 'var(--ink-2)' }}>{r.text}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* faq */}
|
||
<h2 className="block-title">سؤالات پرتکرار</h2>
|
||
<div>
|
||
{c.faq.map((f, i) => (
|
||
<div key={i} className="faq-card">
|
||
<div className="faq-q" onClick={() => setOpenFaq(openFaq === i ? -1 : i)}>
|
||
<span>{f.q}</span>
|
||
<Icon name={openFaq === i ? 'chevron' : 'plus'} className="ic-sm" style={{ color: 'var(--ink-3)', transform: openFaq === i ? 'rotate(90deg)' : 'none', transition: 'transform .2s' }} />
|
||
</div>
|
||
{openFaq === i && <div className="faq-a">{f.a}</div>}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* sticky rail */}
|
||
<div className="sticky-rail">
|
||
<div className="price-card" style={{ background: 'linear-gradient(150deg, var(--accent-soft), oklch(0.97 0.03 80))', borderColor: 'transparent' }}>
|
||
<div style={{ fontSize: 13, color: 'var(--ink-2)' }}>هنوز مطمئن نیستی؟</div>
|
||
<div style={{ fontSize: 16, fontWeight: 700 }}>یک پیشنمایش ۲ دقیقهای ببین</div>
|
||
<button className="btn primary full" style={{ width: '100%', justifyContent: 'center' }}>
|
||
<Icon name="play" className="ic-sm" /> پخش پیشنمایش
|
||
</button>
|
||
</div>
|
||
<div className="price-card" style={{ marginTop: 16 }}>
|
||
<div style={{ fontSize: 14, fontWeight: 600 }}>دوره را به دیگران معرفی کن</div>
|
||
<div style={{ fontSize: 12, color: 'var(--ink-3)' }}>اگر کسی از طریق لینک تو خرید کنه، ۱۰٪ تخفیف میگیره و تو هم اعتبار رایگان دریافت میکنی.</div>
|
||
<div style={{
|
||
background: 'var(--surface-2)', border: '1px solid var(--line)', borderRadius: 8,
|
||
padding: '8px 10px', fontSize: 12, fontFamily: 'var(--font-num)', direction: 'ltr',
|
||
display: 'flex', alignItems: 'center', gap: 8,
|
||
}}>
|
||
<Icon name="link" className="ic-sm" style={{ color: 'var(--ink-3)' }} />
|
||
<span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>ilo.ir/c/p1?ref=arash</span>
|
||
<button className="btn sm" onClick={copy} style={{ padding: '4px 10px' }}>
|
||
{copied ? '✓' : <Icon name="copy" className="ic-sm" />}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* related */}
|
||
<section className="s">
|
||
<h2 className="block-title">دورههای مرتبط</h2>
|
||
<div className="related-grid">
|
||
{related.map(r => (
|
||
<a key={r.id} className="rc" href="Ilo Course Page.html" style={{ textDecoration: 'none', color: 'inherit' }}>
|
||
<div className="rc-img" style={{ background: r.color }} />
|
||
<div className="rc-body">
|
||
<div style={{ fontSize: 11.5, color: 'var(--ink-3)' }}>{r.cat}</div>
|
||
<div style={{ fontSize: 14, fontWeight: 600, marginTop: 4 }}>{r.title}</div>
|
||
<div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2 }}>{r.instructor}</div>
|
||
<div style={{ marginTop: 10, display: 'flex', alignItems: 'baseline', gap: 6 }}>
|
||
<span className="num" style={{ fontSize: 14, fontWeight: 700 }}>{r.price}</span>
|
||
<span style={{ fontSize: 11, color: 'var(--ink-3)' }}>تومان</span>
|
||
</div>
|
||
</div>
|
||
</a>
|
||
))}
|
||
</div>
|
||
</section>
|
||
|
||
{/* sticky bottom mobile cta */}
|
||
<div style={{ height: 24 }} />
|
||
</>
|
||
);
|
||
}
|
||
|
||
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
|
||
</script>
|
||
</body>
|
||
</html>
|