diff --git a/app/[locale]/jobs/JobsContent.tsx b/app/[locale]/jobs/JobsContent.tsx
new file mode 100644
index 0000000..eee0973
--- /dev/null
+++ b/app/[locale]/jobs/JobsContent.tsx
@@ -0,0 +1,291 @@
+"use client";
+
+import { useState, useRef, type FormEvent, type ChangeEvent } from "react";
+import { Link, useLocale, useTranslation } from "@/i18n/navigation";
+
+const positionOptions = [
+ { value: "content", labelZh: "内容运营", labelEn: "Content Operations" },
+ { value: "dev", labelZh: "前端/全栈开发", labelEn: "Frontend / Full-stack Dev" },
+ { value: "design", labelZh: "UI/UX 设计", labelEn: "UI/UX Design" },
+ { value: "marketing", labelZh: "市场推广", labelEn: "Marketing" },
+ { value: "other", labelZh: "其他", labelEn: "Other" },
+];
+
+interface FormData {
+ position: string;
+ name: string;
+ email: string;
+ phone: string;
+ intro: string;
+}
+
+function Field({
+ label,
+ children,
+}: {
+ label: string;
+ children: React.ReactNode;
+}) {
+ return (
+
+
+
{children}
+
+ );
+}
+
+function ChevronDown() {
+ return (
+
+ );
+}
+
+export default function JobsContent() {
+ const { t } = useTranslation("jobs");
+ const locale = useLocale();
+ const [form, setForm] = useState({
+ position: "",
+ name: "",
+ email: "",
+ phone: "",
+ intro: "",
+ });
+ const [resume, setResume] = useState(null);
+ const [resumeError, setResumeError] = useState(null);
+ const fileRef = useRef(null);
+
+ const set = (key: keyof FormData, value: string) =>
+ setForm((prev) => ({ ...prev, [key]: value }));
+
+ const handleSubmit = (e: FormEvent) => {
+ e.preventDefault();
+ setResumeError(null);
+ if (!resume) {
+ setResumeError(locale === "zh" ? "请上传简历(PDF 或 Word)" : "Please upload your resume (PDF or Word)");
+ return;
+ }
+ // 暂不提交,无业务逻辑
+ if (locale === "zh") {
+ alert("表单已填写完成,提交功能即将上线。");
+ } else {
+ alert("Form completed. Submit feature coming soon.");
+ }
+ };
+
+ const handleFileChange = (e: ChangeEvent) => {
+ const file = e.target.files?.[0];
+ if (!file) return;
+ const ext = file.name.split(".").pop()?.toLowerCase();
+ const allowed = ["pdf", "doc", "docx"];
+ if (!ext || !allowed.includes(ext)) {
+ setResumeError(locale === "zh" ? "请上传 PDF、DOC 或 DOCX 格式" : "Please upload PDF, DOC or DOCX");
+ return;
+ }
+ if (file.size > 10 * 1024 * 1024) {
+ setResumeError(locale === "zh" ? "文件大小不能超过 10MB" : "File size must be under 10MB");
+ return;
+ }
+ setResumeError(null);
+ setResume(file);
+ };
+
+ const removeResume = () => {
+ setResume(null);
+ setResumeError(null);
+ if (fileRef.current) fileRef.current.value = "";
+ };
+
+ const getLabel = (opt: (typeof positionOptions)[0]) =>
+ locale === "zh" ? opt.labelZh : opt.labelEn;
+
+ return (
+
+
+ {/* Banner */}
+
+
+
+
💼
+
+ {locale === "zh" ? "加入我们" : "Join Us"}
+
+
+
+
+
+
+
+ {t("title")}
+
+
+ {t("subtitle")}
+
+
+
+
+ {/* Form */}
+
+
+
+
+ ← {locale === "zh" ? "返回首页" : "Back to Home"}
+
+
+
+
+ );
+}
diff --git a/app/[locale]/jobs/page.tsx b/app/[locale]/jobs/page.tsx
new file mode 100644
index 0000000..954122d
--- /dev/null
+++ b/app/[locale]/jobs/page.tsx
@@ -0,0 +1,21 @@
+import type { Metadata } from "next";
+import Header from "../../components/Header";
+import Footer from "../../components/Footer";
+import JobsContent from "./JobsContent";
+
+export const metadata: Metadata = {
+ title: "招聘 | Careers",
+ description: "加入数字游民指南团队,我们正在招聘。",
+};
+
+export default function JobsPage() {
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+}
diff --git a/app/components/Footer.tsx b/app/components/Footer.tsx
index b4807b7..d753919 100644
--- a/app/components/Footer.tsx
+++ b/app/components/Footer.tsx
@@ -33,7 +33,7 @@ const footerSections = [
titleKey: "about" as const,
links: [
{ labelKey: "aboutUs" as const, href: "/about", internal: true },
- { labelKey: "contribute" as const, href: "#" },
+ { labelKey: "recruit" as const, href: "/jobs", internal: true, openInNewTab: true },
{ labelKey: "privacy" as const, href: "/privacy", internal: true, openInNewTab: true },
{ labelKey: "contact" as const, href: "#" },
],
diff --git a/content/themes/digital-nomad/messages/en.json b/content/themes/digital-nomad/messages/en.json
index cfe8bfe..3280eef 100644
--- a/content/themes/digital-nomad/messages/en.json
+++ b/content/themes/digital-nomad/messages/en.json
@@ -139,7 +139,7 @@
"jike": "Jike",
"github": "GitHub",
"aboutUs": "About Us",
- "contribute": "Contribute",
+ "recruit": "Careers",
"privacy": "Privacy",
"contact": "Contact"
},
@@ -164,6 +164,20 @@
"teamTitle": "Team Members",
"teamDesc": "We are digital nomads who love remote work"
},
+ "jobs": {
+ "title": "Careers",
+ "subtitle": "Join the Digital Nomad Guide team. Remote work, location freedom.",
+ "position": "Position",
+ "name": "Name",
+ "email": "Email",
+ "phone": "Phone",
+ "intro": "Introduction",
+ "introPlaceholder": "Briefly introduce your experience, skills and motivation",
+ "resume": "Resume",
+ "resumeHint": "PDF, DOC or DOCX, max 10MB",
+ "resumeUpload": "Click to upload resume",
+ "submit": "Submit Application"
+ },
"auth": {
"title": "Login / Sign up",
"email": "Email",
diff --git a/content/themes/digital-nomad/messages/zh.json b/content/themes/digital-nomad/messages/zh.json
index 9e17bd5..75a278c 100644
--- a/content/themes/digital-nomad/messages/zh.json
+++ b/content/themes/digital-nomad/messages/zh.json
@@ -139,7 +139,7 @@
"jike": "即刻",
"github": "GitHub",
"aboutUs": "关于我们",
- "contribute": "贡献指南",
+ "recruit": "招聘",
"privacy": "隐私政策",
"contact": "联系我们"
},
@@ -164,6 +164,20 @@
"teamTitle": "团队成员",
"teamDesc": "我们是一群热爱自由工作的数字游民"
},
+ "jobs": {
+ "title": "招聘",
+ "subtitle": "加入数字游民指南团队,远程工作,地点自由",
+ "position": "应聘职位",
+ "name": "姓名",
+ "email": "邮箱",
+ "phone": "手机",
+ "intro": "自我介绍",
+ "introPlaceholder": "请简要介绍您的经历、技能及应聘理由",
+ "resume": "简历",
+ "resumeHint": "支持 PDF、DOC、DOCX,最大 10MB",
+ "resumeUpload": "点击上传简历",
+ "submit": "提交申请"
+ },
"auth": {
"title": "登录 / 注册",
"email": "邮箱",