_index.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. <!doctype html>
  2. <html lang="{{ .Lang }}">
  3. <head>
  4. {{ partial "head" . }}
  5. <link rel="canonical" href="{{ .Permalink }}">
  6. <title>
  7. {{ block "title" . }}
  8. {{ .Title}}{{ if ne .Title .Site.Title }} | {{ .Site.Title }}{{ end }}
  9. {{ end }}
  10. </title>
  11. <!-- Bootstrap CSS -->
  12. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.1.3/css/bootstrap.min.css"
  13. integrity="sha512-GQGU0fMMi238uA+a/bdWJfpUGKUkBdgfFdgBm72SUQ6BeyWjoY/ton0tEjH+OSH9iP4Dfh+7HM0I9f5eR0L/4w=="
  14. crossorigin="anonymous" referrerpolicy="no-referrer" />
  15. <link href='{{ "css/style.css" | relURL }}' rel="stylesheet">
  16. <style>
  17. .container {
  18. width: 100%;
  19. margin-bottom: 12px;
  20. font-weight: 500;
  21. }
  22. h1 {
  23. margin-bottom: 3rem;
  24. text-align: center;
  25. font-weight: bold;
  26. }
  27. .form-wrapper {
  28. display: flex;
  29. flex-direction: column;
  30. gap: 24px;
  31. padding: 16px 0;
  32. border-radius: 8px;
  33. }
  34. /* 上傳 */
  35. .upload-section {
  36. display: flex;
  37. flex-direction: column;
  38. }
  39. .file-input {
  40. padding: 8px;
  41. font-size: 14px;
  42. border: 1px solid #ccc;
  43. border-radius: 6px;
  44. cursor: pointer;
  45. }
  46. /* .upload-section {
  47. width: 100%;
  48. }
  49. .file-input {
  50. display: none;
  51. }
  52. .upload-btn {
  53. color: #920783;
  54. background-color: #ffffff;
  55. border: 1px solid #920783;
  56. font-weight: 500;
  57. border-radius: 8px;
  58. font-size: 14px;
  59. padding: 10px 20px;
  60. margin-right: 8px;
  61. margin-bottom: 8px;
  62. transition: all 0.3s ease;
  63. cursor: pointer;
  64. }
  65. .upload-btn:hover {
  66. background-color: #920783;
  67. color: #ffffff;
  68. } */
  69. /* 圖片預覽 */
  70. .preview {
  71. margin-top: 8px;
  72. }
  73. .preview-img {
  74. max-height: 240px;
  75. object-fit: cover;
  76. border-radius: 8px;
  77. }
  78. /* 文字輸入 */
  79. .text-section {
  80. width: 100%;
  81. }
  82. .text-area {
  83. width: 100%;
  84. height: 160px;
  85. border: 1px solid #ccc;
  86. border-radius: 8px;
  87. padding: 12px;
  88. resize: none;
  89. font-size: 14px;
  90. transition: all 0.3s ease;
  91. }
  92. /* 選項 */
  93. .options {
  94. margin-top: 16px;
  95. }
  96. .options-title {
  97. margin-bottom: 8px;
  98. font-weight: 500;
  99. font-size: 1.25rem;
  100. }
  101. .option-item {
  102. display: block;
  103. cursor: pointer;
  104. margin-bottom: 4px;
  105. }
  106. /* 送出按鈕 */
  107. .submit-btn {
  108. display: flex;
  109. align-items: center;
  110. justify-content: center;
  111. gap: 8px;
  112. color: #ffffff;
  113. background-color: var(--sub-color);
  114. border: 1px solid transparent;
  115. font-weight: 500;
  116. border-radius: 8px;
  117. padding: 10px 50px;
  118. margin-right: 8px;
  119. margin-bottom: 8px;
  120. transition: all 0.3s ease;
  121. cursor: pointer;
  122. text-decoration: none;
  123. }
  124. .submit-btn:hover {
  125. background-color: #ffffff;
  126. color: var(--sub-color);
  127. border: 1px solid var(--sub-color);
  128. }
  129. .submit-btn:disabled {
  130. opacity: 0.6;
  131. cursor: not-allowed;
  132. }
  133. /* 讀取動畫 */
  134. .spinner {
  135. animation: spin 1s linear infinite;
  136. height: 20px;
  137. width: 20px;
  138. color: white;
  139. }
  140. .spinner-bg {
  141. opacity: 0.25;
  142. }
  143. .spinner-path {
  144. opacity: 0.75;
  145. }
  146. @keyframes spin {
  147. to {
  148. transform: rotate(360deg);
  149. }
  150. }
  151. .contact-input {
  152. display: flex;
  153. flex-direction: column;
  154. margin-bottom: 16px;
  155. }
  156. .contact-input input {
  157. padding: 10px 12px;
  158. border: 1px solid #ccc;
  159. border-radius: 6px;
  160. font-size: 14px;
  161. transition: all 0.3s ease;
  162. }
  163. .contact-input input:focus,
  164. .text-area:focus {
  165. outline: none;
  166. border-color: var(--sub-color);
  167. box-shadow: none;
  168. }
  169. label span {
  170. color: red;
  171. }
  172. .bg-img {
  173. position: absolute;
  174. z-index: -1;
  175. top: -15vw;
  176. opacity: 0.5;
  177. }
  178. small {
  179. display: inline-block;
  180. color: #767676;
  181. font-weight: 500;
  182. }
  183. label {
  184. font-weight: 500;
  185. margin-bottom: 6px;
  186. }
  187. .title {
  188. color: var(--sub-color);
  189. text-align: center;
  190. }
  191. </style>
  192. {{ range .AlternativeOutputFormats -}}
  193. <link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
  194. {{ end -}}
  195. </head>
  196. <body>
  197. {{ block "header" . }}
  198. {{ partial "header" . }}
  199. {{ end }}
  200. <div class="container my-5 py-5 position-relative">
  201. <h1 class="text-center mb-0">
  202. Free PR Service <br> <small>新聞發布服務</small>
  203. </h1>
  204. <div class="row g-3 justify-content-center mt-5">
  205. <div class="col-md-11">
  206. <div class="d-flex flex-column align-items-center mb-5">
  207. <h2 class="title">🎤 免費新聞發布,讓您的品牌被更多人看見</h2>
  208. <p class="lead mt-3 text-center">
  209. 0 成本把您的產品、活動與品牌故事,<b>一鍵發布至新聞平台</b>,直達媒體與潛在客戶,輕鬆獲得曝光與關注!<br>
  210. 只要填寫以下表單,我們協助您<span style="white-space:nowrap;">潤稿 × 發布</span>,加速上稿與曝光。
  211. </p>
  212. <div class="row g-4 mb-5 py-3">
  213. <!-- 免費&省時 -->
  214. <div class="col-12 col-md-6 col-lg-3">
  215. <div class="card h-100 shadow-sm border-0">
  216. <div class="card-body text-center">
  217. <div class="fs-1 mb-3">⏱️</div>
  218. <h5 class="card-title">免費&省時</h5>
  219. <p class="card-text">填表 2 分鐘,其他交給我們。</p>
  220. </div>
  221. </div>
  222. </div>
  223. <!-- 專人協助 -->
  224. <div class="col-12 col-md-6 col-lg-3">
  225. <div class="card h-100 shadow-sm border-0">
  226. <div class="card-body text-center">
  227. <div class="fs-1 mb-3">🙋</div>
  228. <h5 class="card-title">專人協助</h5>
  229. <p class="card-text">整理重點、統一格式,提升可讀與採用率。</p>
  230. </div>
  231. </div>
  232. </div>
  233. <!-- 快速擴散 -->
  234. <div class="col-12 col-md-6 col-lg-3">
  235. <div class="card h-100 shadow-sm border-0">
  236. <div class="card-body text-center">
  237. <div class="fs-1 mb-3">📢</div>
  238. <h5 class="card-title">快速擴散</h5>
  239. <p class="card-text">依主題分類投遞至合適媒體/平台,提高被看見的機會。</p>
  240. </div>
  241. </div>
  242. </div>
  243. <!-- 彈性主題 -->
  244. <div class="col-12 col-md-6 col-lg-3">
  245. <div class="card h-100 shadow-sm border-0">
  246. <div class="card-body text-center">
  247. <div class="fs-1 mb-3">✨</div>
  248. <h5 class="card-title">彈性主題</h5>
  249. <p class="card-text">新品上市、活動/展覽、里程碑公告、合作/募資、招募訊息…</p>
  250. </div>
  251. </div>
  252. </div>
  253. </div>
  254. <!-- <ul class="my-5" aria-label="服務重點">
  255. <li><strong>免費&省時:</strong>填表 2 分鐘,其他交給我們。</li>
  256. <li><strong>專人協助:</strong>整理重點、統一格式,提升可讀與採用率。</li>
  257. <li><strong>快速擴散:</strong>依主題分類投遞至合適媒體/平台,提高被看見的機會。</li>
  258. <li><strong>彈性主題:</strong>新品上市、活動/展覽、里程碑公告、合作/募資、招募訊息…</li>
  259. </ul> -->
  260. <a href="#prForm" class="submit-btn" aria-label="前往表單填寫,開始免費發布">👉 立即填寫,免費發布</a>
  261. <small class="subtle">提交後,我們將盡快與您確認新聞稿並安排發布。</small>
  262. </div>
  263. </div>
  264. <div class="col-md-8">
  265. <form id="prForm" class="pt-5">
  266. <div class="contact-input mb-4">
  267. <label for="email">
  268. Email <span>(*) mandatory</span>
  269. <br> <small>電子郵件</small>
  270. </label>
  271. <input type="text" id="email" placeholder="Enter your email" />
  272. </div>
  273. <div class="contact-input mb-4">
  274. <label for="headline">
  275. News Headline <span>(*) mandatory</span> <br> <small>新聞標題</small>
  276. </label>
  277. <input type="text" id="headline" placeholder="Enter news headline" />
  278. </div>
  279. <div class="contact-input mb-4">
  280. <label for="contactId">LINE ID / WhatsApp ID</label>
  281. <input type="text" id="contactId" placeholder="Enter your LINE or WhatsApp ID" />
  282. </div>
  283. <div class="form-wrapper">
  284. <div class="text-section mb-2">
  285. <label for="newsText" class="form-label">News Content <span>(*) mandatory</span>
  286. <br><small>新聞內文</small></label>
  287. <textarea id="newsText" placeholder="Enter news content..." class="text-area"></textarea>
  288. </div>
  289. <div class="upload-section mb-2">
  290. <label for="fileInput">Select Image <span>(*) mandatory</span> <br><small>選擇圖片</small></label>
  291. <input type="file" id="fileInput" class="file-input" accept="image/*" />
  292. <div id="preview" class="preview"></div>
  293. <!-- <input type="file" id="fileInput" class="file-input" accept="image/*" />
  294. <button type="button" id="uploadBtn" class="upload-btn">Select Image <br> 選擇圖片 </button>
  295. <div id="preview" class="preview"></div> -->
  296. </div>
  297. <!-- 上傳名單 (Excel/CSV) -->
  298. <div class="upload-section mb-2">
  299. <label for="listInput">Upload List<br><small>上傳名單(Excel / CSV)</small></label>
  300. <input type="file" id="listInput" class="file-input"
  301. accept=".csv,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
  302. </div>
  303. </div>
  304. <!-- <div class="options">
  305. <p class="options-title mb-0">Publishing Platform (optional, multiple choices allowed)</p>
  306. <small class="mb-3">發布平台(可多選,非必填)</small>
  307. <label class="option-item"><input type="checkbox" value="經濟日報網路版" />
  308. Economic Daily <br>
  309. <small class="ms-3">&nbsp;經濟日報網路版</small>
  310. </label>
  311. <label class="option-item"><input type="checkbox" value="工商時報網路版" /> Commercial Times <br>
  312. <small class="ms-3">&nbsp;工商時報網路版</small></label>
  313. <label class="option-item"><input type="checkbox" value="Yahoo 新聞" /> Yahoo News <br> <small
  314. class="ms-3">&nbsp;Yahoo
  315. 新聞</small></label>
  316. </div> -->
  317. <div class="d-flex justify-content-center mt-4">
  318. <button type="button" id="submitBtn" class="submit-btn">
  319. <span>Submit <br> 送出</span>
  320. </button>
  321. </div>
  322. </form>
  323. </div>
  324. <!-- <div class="col-md-8">
  325. <section class="mt-5 py-5 bg-light">
  326. <div class="container text-center">
  327. <h3 class="fw-bold mb-4">Case Studies <br> <small class="mt-1">新聞發布案例</small></h3>
  328. <a href="https://drive.google.com/drive/folders/1n0uWt_VSQ_B8S8UZD5cf9i9L6x4dGKHu?usp=sharing"
  329. target="_blank" class="btn btn-lg px-4 fw-bold" style="background-color:#ea5413; color:#fff;">
  330. Explore Case Studies <br> <small class="text-white">查看案例集</small>
  331. </a>
  332. </div>
  333. </section>
  334. </div> -->
  335. </div>
  336. </div>
  337. {{ block "footer" . }}
  338. {{ partial "footer" . }}
  339. {{ end }}
  340. <!-- Bootstrap and Popper -->
  341. <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.1.3/js/bootstrap.bundle.min.js"
  342. integrity="sha512-pax4MlgXjHEPfCwcJLQhigY7+N8rt6bVvWLFyUMuxShv170X53TRzGPmPkZmGBhk+jikR8WBM4yl7A9WMHHqvg=="
  343. crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  344. <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
  345. <script>
  346. const fileInput = document.getElementById("fileInput");
  347. // const uploadBtn = document.getElementById("uploadBtn");
  348. const preview = document.getElementById("preview");
  349. const email = document.getElementById("email");
  350. const headline = document.getElementById("headline");
  351. const newsText = document.getElementById("newsText");
  352. const contactId = document.getElementById("contactId");
  353. const submitBtn = document.getElementById("submitBtn");
  354. const optionCheckboxes = document.querySelectorAll(".options input[type=checkbox]");
  355. let file = null;
  356. let fileName = "";
  357. let previewUrl = null;
  358. let listFile = null;
  359. let listFileName = "";
  360. let isLoading = false;
  361. // // 觸發檔案選擇
  362. // uploadBtn.addEventListener("click", () => {
  363. // fileInput.click();
  364. // });
  365. // 選擇圖片
  366. fileInput.addEventListener("change", (e) => {
  367. const f = e.target.files[0];
  368. if (f) {
  369. file = f;
  370. previewUrl = URL.createObjectURL(f);
  371. fileName = f.name;
  372. preview.innerHTML = `<img src="${previewUrl}" class="preview-img" />`;
  373. // uploadBtn.textContent = fileName;
  374. }
  375. });
  376. const listInput = document.getElementById("listInput");
  377. // 上傳名單
  378. listInput.addEventListener("change", function () {
  379. const f = this.files && this.files[0] ? this.files[0] : null;
  380. if (!f) {
  381. listFile = null;
  382. listFileName = "";
  383. return;
  384. }
  385. // 格式檢查(.csv/.xls/.xlsx)
  386. const okTypes = [
  387. "text/csv",
  388. "application/vnd.ms-excel",
  389. "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  390. ];
  391. const okExt = [".csv", ".xls", ".xlsx"];
  392. const lowerName = f.name.toLowerCase();
  393. const pass =
  394. okTypes.includes(f.type) ||
  395. okExt.some((ext) => lowerName.endsWith(ext));
  396. if (!pass) {
  397. listFile = null;
  398. listFileName = "";
  399. listInput.value = ""; // 清空
  400. Swal.fire({
  401. title: "請選擇 .csv / .xls / .xlsx 檔案",
  402. icon: "warning",
  403. confirmButtonColor: "#910784",
  404. });
  405. return;
  406. }
  407. listFile = f;
  408. listFileName = f.name;
  409. console.log('listFile', listFile);
  410. console.log('listFileName', listFileName);
  411. // 顯示檔名與大小
  412. const sizeKB = Math.round(f.size / 1024);
  413. });
  414. // 送出表單
  415. submitBtn.addEventListener("click", async () => {
  416. console.log('送出表單');
  417. if (isLoading) return;
  418. // 檢查檔案
  419. if (!file) {
  420. Swal.fire({
  421. title: "請上傳圖片",
  422. icon: "warning",
  423. confirmButtonColor: "#910784",
  424. });
  425. return;
  426. }
  427. // 檢查標題
  428. if (!headline.value.trim()) {
  429. Swal.fire({
  430. title: "請輸入新聞標題",
  431. icon: "warning",
  432. confirmButtonColor: "#910784",
  433. });
  434. return;
  435. }
  436. // 檢查文字
  437. if (!newsText.value.trim()) {
  438. Swal.fire({
  439. title: "請輸入新聞稿文字",
  440. icon: "warning",
  441. confirmButtonColor: "#910784",
  442. });
  443. return;
  444. }
  445. // 檢查信箱
  446. if (!email.value.trim()) {
  447. Swal.fire({
  448. title: "請輸入 Email",
  449. icon: "warning",
  450. confirmButtonColor: "#910784",
  451. });
  452. return;
  453. }
  454. // 取得勾選選項
  455. const selectedOptions = Array.from(optionCheckboxes)
  456. .filter(cb => cb.checked)
  457. .map(cb => cb.value);
  458. isLoading = true;
  459. submitBtn.disabled = true;
  460. submitBtn.textContent = "處理中...";
  461. const formData = new FormData();
  462. formData.append("email", email.value);
  463. formData.append("image", file);
  464. formData.append("text", newsText.value);
  465. formData.append("title", headline.value);
  466. formData.append("contact_id", contactId.value);
  467. selectedOptions.forEach(opt => formData.append("options", opt));
  468. try {
  469. const response = await fetch("https://cmm.ai:10001/auth/add_form_record", {
  470. method: "POST",
  471. body: formData
  472. });
  473. const result = await response.json();
  474. console.log("handleSubmit", result);
  475. Swal.fire({
  476. title: "送出成功!",
  477. icon: "success",
  478. confirmButtonColor: "#e47140",
  479. }).then(() => {
  480. // 清空圖片相關
  481. file = null;
  482. previewUrl = null;
  483. fileName = "";
  484. preview.innerHTML = "";
  485. // input type=file,需要手動 reset
  486. document.getElementById("fileInput").value = "";
  487. // 清空名單相關
  488. listFile = null;
  489. listFileName = "";
  490. document.getElementById("listInput").value = "";
  491. // 清空其他欄位
  492. email.value = "";
  493. headline.value = "";
  494. newsText.value = "";
  495. contactId.value = "";
  496. optionCheckboxes.forEach(cb => cb.checked = false);
  497. // uploadBtn.textContent = "選擇圖片";
  498. });
  499. } catch (error) {
  500. console.error("error", error);
  501. } finally {
  502. isLoading = false;
  503. submitBtn.disabled = false;
  504. submitBtn.innerHTML = "<span>Submit <br> 送出</span>";
  505. }
  506. });
  507. </script>
  508. <script src="/js/main.js"></script>
  509. </body>
  510. </html>