// Main content sections: Business, Brands, CEO, Careers, Contact, Company, Footer // Exposes to window. const { useEffect: _useEffect, useState: _useState, useRef: _useRef } = React; // ---------- Section head ---------- function SectionHead({ eyebrow, title, meta, dark }) { return (
{eyebrow}

{window.renderTokens(title)}

{meta &&
{meta}
}
); } // ---------- News / お知らせ ---------- function NewsSection({ content }) { const raw = content.news; if (!raw) return null; const items = Array.isArray(raw) ? raw : [raw]; // 旧形式(単一オブジェクト)も許容 if (items.length === 0) return null; return (
{items.map((c, i) => { const Tag = c.url ? "a" : "div"; const linkProps = c.url ? { href: c.url, target: "_blank", rel: "noopener noreferrer" } : {}; return (
{c.badge} {c.date}

{c.title}

{c.body &&

{c.body}

} {(c.url || c.note) && (
{c.url && ( {c.urlLabel}↗ )} {c.note && {c.note}}
)}
); })}
); } // ---------- Business ---------- function BusinessSection({ content }) { const c = content.business; return (
{c.cards.map((card) => ( ))}
); } function BizIcon({ n }) { // simple iconography: shapes (no realistic SVGs) if (n === "04") return ( ); if (n === "01") return ( ); if (n === "02") return ( ); return ( ); } // ---------- Brands ---------- function BrandsSection({ content }) { const c = content.brands; return (
{c.items.map((b, i) => (
{String(i + 1).padStart(2, "0")} / {String(c.items.length).padStart(2, "0")}
{b.nameEn}

{b.name}

{b.tagline}

{b.body}

{b.tags.map((t) => {t})}
{b.city} · EST. {b.since}
{b.urlLabel} ↗
{b.instagram && ( INSTAGRAM {b.instagramLabel || "Instagram"} ↗ )}
))}
); } // ---------- CEO Message ---------- function CeoSection({ content }) { const c = content.ceo; return (

{c.quote}

{c.name}
{c.role}
{c.body.map((p, i) =>

{p}

)}
); } // ---------- COO Profile ---------- function CooSection({ content }) { const c = content.coo; if (!c) return null; return (

{c.quote}

{c.name}
{c.role}
{c.body.map((p, i) =>

{p}

)} {(c.blocks || []).map((b, i) => (

{b.h}

{b.p}

))} {c.facts && (
{c.facts.map((f, i) => (
{f.n}{f.unit}
{f.t}
))}
)}
); } // ---------- Careers ---------- function CareersSection({ content }) { const c = content.careers; const APPLY_URL = "https://doteppan.com/contact"; return (
{c.tagWords.map((w, i) => ( {w.text}{i < c.tagWords.length - 1 ? " " : ""} ))}

{c.lead}

{/* Stats: 12店舗 / 90% / 10倍 */}
{c.stats.map((s) => (
{s.n}{s.unit}
{s.t}
))}
{/* Values */}
{c.values.map((v) => (
{v.vn}

{v.h}

{v.p}

))}
{/* Job openings */}
04

{c.openingsTitle}

{c.openingsNote}

{c.openings.map((o) => (
{o.num}

{o.title}

{o.body}

{o.location &&
{o.location}
}
{c.applyCta} →
))}
{/* Career path / grades */}
05

{c.gradesTitle}

{c.grades.map((g) => (
{g.gn} {g.name}
{g.role} {g.desc}
{g.pay}{g.payUnit}
))}
{/* Requirements */}
06

{c.reqsTitle}

{c.reqs.map((r) => (
{r.k}
{r.v}
))}
{/* Hiring flow */}
{c.flow.map((f) => (
{f.n}
{f.b}
{f.s}
))}
{/* Apply CTA */}

{c.applyTitle}

{c.applyLead}

{c.applyCta} →
doteppan.com/contact ↗
); } // ---------- Contact ---------- function ContactSection({ content, lang }) { const c = content.contact; const L = c.labels; const [form, setForm] = _useState({ type: [], name: "", company: "", email: "", message: "", website: "", // ハニーポット(画面には出さない。botだけが埋める) }); const [errors, setErrors] = _useState({}); const [touched, setTouched] = _useState({}); const [submitting, setSubmitting] = _useState(false); const [done, setDone] = _useState(false); const set = (k, v) => setForm((f) => ({ ...f, [k]: v })); const toggleType = (t) => { setForm((f) => ({ ...f, type: f.type.includes(t) ? f.type.filter((x) => x !== t) : [...f.type, t], })); }; const validate = (f) => { const e = {}; if (!f.type || f.type.length === 0) e.type = L.errType; if (!f.name.trim()) e.name = L.errReq; if (!f.email.trim()) e.email = L.errReq; else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(f.email)) e.email = L.errEmail; if (!f.message.trim()) e.message = L.errReq; return e; }; _useEffect(() => { setErrors(validate(form)); }, [form, lang]); const handleBlur = (k) => setTouched((t) => ({ ...t, [k]: true })); // ★ お問い合わせの送信先(Google Apps Script のウェブアプリURL) // 受信先のメールアドレス・自動返信の文面は Apps Script 側の「コード.gs」で設定します。 // デプロイしたURL(https://script.google.com/macros/s/.../exec)をここに貼ってください。 // 差し替え手順は 受信フォーム_設定手順.txt を参照。 const FORM_ENDPOINT = "https://script.google.com/macros/s/AKfycbzdO8zKshvMRxsjdp-_JSj3kdKfYaR2zzKqVpvMCGwtJTVO8XTh8zGcr0wRDNHlp-8EAg/exec"; const submit = async (e) => { e.preventDefault(); setTouched({ type: true, name: true, email: true, message: true }); const errs = validate(form); setErrors(errs); if (Object.keys(errs).length > 0) return; setSubmitting(true); try { // Content-Type を text/plain にすると CORS の事前確認(preflight)が走らず、 // Apps Script のウェブアプリへそのまま送れる。中身は JSON のまま。 const res = await fetch(FORM_ENDPOINT, { method: "POST", headers: { "Content-Type": "text/plain;charset=utf-8" }, body: JSON.stringify({ type: form.type.join("、"), name: form.name, company: form.company, email: form.email, message: form.message, website: form.website, // 人には見えない欄。入っていれば bot として破棄される page: location.pathname, lang: lang, }), }); const out = await res.json().catch(() => ({ ok: res.ok })); setSubmitting(false); if (out.ok) { setDone(true); } else { alert("送信に失敗しました。お手数ですが partner@teppan-jp.com までご連絡ください。"); } } catch (err) { setSubmitting(false); alert("通信エラーが発生しました。お手数ですが partner@teppan-jp.com までご連絡ください。"); } }; const showErr = (k) => touched[k] && errors[k]; return (

{c.lead}

{done ? (
★

{c.thanks}

{c.thanksSub}

) : (
{/* ハニーポット:スパム対策。人には見えないので何も入らない */}
{c.types.map((t) => ( ))}
{showErr("type") && {errors.type}}
set("name", e.target.value)} onBlur={() => handleBlur("name")} /> {showErr("name") && {errors.name}}
set("company", e.target.value)} />
set("email", e.target.value)} onBlur={() => handleBlur("email")} /> {showErr("email") && {errors.email}}
{showErr("message") && {errors.message}}
)}
); } // ---------- Company ---------- function CompanySection({ content }) { const c = content.company; return (

{c.historyTitle}

{c.history.map((h, i) => (
{h.year}
{h.items ? h.items.map((t, j) =>
{t}
) : h.text}
))}

{c.factsTitle}

{c.facts.map((f, i) => (
{f.k}
{f.v}
))}
); } // ---------- FAQ / よくあるご質問 ---------- function FaqSection({ content }) { const c = content.faq; if (!c || !c.items) return null; return (
{c.items.map((it, i) => (
{it.q}

{it.a}

))}
); } // ---------- Footer ---------- function SiteFooter({ content }) { const f = content.footer; return ( ); } Object.assign(window, { NewsSection, FaqSection, BusinessSection, BrandsSection, CeoSection, CooSection, CareersSection, ContactSection, CompanySection, SiteFooter, });