폼전송 기능 수정
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import type { Block, ButtonBlockProps, FormBlockProps } from "@/features/editor/state/editorStore";
|
||||
import { NumericPropertyControl } from "@/features/editor/components/NumericPropertyControl";
|
||||
import { computeFormControllerPublicTokens } from "@/features/editor/utils/formHelpers";
|
||||
|
||||
interface FormControllerPanelProps {
|
||||
block: Block; // type === "form"
|
||||
@@ -13,8 +15,59 @@ interface FormControllerPanelProps {
|
||||
export function FormControllerPanel({ block, blocks, selectedBlockId, updateBlock }: FormControllerPanelProps) {
|
||||
if (!selectedBlockId || block.id !== selectedBlockId) return null;
|
||||
|
||||
const [showSheetsGuide, setShowSheetsGuide] = useState(false);
|
||||
|
||||
const formProps = block.props as FormBlockProps;
|
||||
|
||||
const sheetsScriptExample = (() => {
|
||||
const tokens = computeFormControllerPublicTokens(block, blocks);
|
||||
const fieldNames = tokens.fields.map((f) => f.name).filter((name) => !!name);
|
||||
|
||||
if (fieldNames.length === 0) {
|
||||
return (
|
||||
"function doPost(e) {\n" +
|
||||
' var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("시트1");\n' +
|
||||
" if (!sheet) { sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0]; }\n" +
|
||||
" var params = e.parameter; // x-www-form-urlencoded\n" +
|
||||
" var row = [\n" +
|
||||
' params.name || "",\n' +
|
||||
' params.email || "",\n' +
|
||||
' params.message || "",\n' +
|
||||
" new Date(),\n" +
|
||||
" ];\n" +
|
||||
" sheet.appendRow(row);\n" +
|
||||
" return ContentService\n" +
|
||||
" .createTextOutput(JSON.stringify({ ok: true }))\n" +
|
||||
" .setMimeType(ContentService.MimeType.JSON);\n" +
|
||||
"}"
|
||||
);
|
||||
}
|
||||
|
||||
const headerNames = [...fieldNames, "createdAt"];
|
||||
const rowLines = fieldNames.map((name) => ` params.${name} || "",`);
|
||||
rowLines.push(" new Date(),");
|
||||
|
||||
const lines: string[] = [];
|
||||
lines.push("function doPost(e) {");
|
||||
lines.push(' var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("시트1");');
|
||||
lines.push(" if (!sheet) { sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0]; }");
|
||||
lines.push(" var params = e.parameter; // x-www-form-urlencoded");
|
||||
lines.push(" // 시트의 1행 헤더는 다음과 같이 맞춰 주세요:");
|
||||
lines.push(` // ${headerNames.join(", ")}`);
|
||||
lines.push(" var row = [");
|
||||
for (const line of rowLines) {
|
||||
lines.push(line);
|
||||
}
|
||||
lines.push(" ];");
|
||||
lines.push(" sheet.appendRow(row);");
|
||||
lines.push(" return ContentService");
|
||||
lines.push(" .createTextOutput(JSON.stringify({ ok: true }))");
|
||||
lines.push(" .setMimeType(ContentService.MimeType.JSON);");
|
||||
lines.push("}");
|
||||
|
||||
return lines.join("\n");
|
||||
})();
|
||||
|
||||
return (
|
||||
<div className="space-y-4 text-xs">
|
||||
<p className="text-slate-400">
|
||||
@@ -40,9 +93,9 @@ export function FormControllerPanel({ block, blocks, selectedBlockId, updateBloc
|
||||
</div>
|
||||
|
||||
{formProps.submitTarget === "webhook" && (
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-3">
|
||||
<label className="flex flex-col gap-1">
|
||||
<span className="text-slate-400">Webhook / Google Sheets URL</span>
|
||||
<span className="text-slate-400">Webhook URL (예: Google Apps Script 웹 앱 URL)</span>
|
||||
<input
|
||||
className="w-full rounded border border-slate-700 bg-slate-950 px-2 py-1 text-xs outline-none focus:border-sky-500"
|
||||
placeholder="예: https://script.google.com/macros/s/.../exec"
|
||||
@@ -126,6 +179,16 @@ export function FormControllerPanel({ block, blocks, selectedBlockId, updateBloc
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex items-center gap-1 rounded border border-slate-700 bg-slate-900 px-2 py-1 text-[11px] text-slate-100 hover:bg-slate-800"
|
||||
onClick={() => setShowSheetsGuide(true)}
|
||||
>
|
||||
Google Sheets 연동 가이드
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@@ -325,6 +388,41 @@ export function FormControllerPanel({ block, blocks, selectedBlockId, updateBloc
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{showSheetsGuide && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-slate-950/70">
|
||||
<div className="w-full max-w-xl rounded border border-slate-800 bg-slate-950 px-4 py-3 shadow-lg">
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
<h4 className="text-[11px] font-semibold text-slate-100">Google Sheets 연동 가이드</h4>
|
||||
<button
|
||||
type="button"
|
||||
className="text-[11px] text-slate-400 hover:text-slate-100"
|
||||
onClick={() => setShowSheetsGuide(false)}
|
||||
aria-label="Google Sheets 연동 가이드 닫기"
|
||||
>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-[11px] text-slate-400 leading-relaxed">
|
||||
구글 시트 주소를 그대로 입력하는 것이 아니라, 시트에 연결된 Google Apps Script 웹 앱 URL 을 입력해야 합니다.
|
||||
아래 순서를 따르면 코드를 잘 모르는 사용자도 연동할 수 있습니다.
|
||||
</p>
|
||||
<ol className="list-decimal list-inside space-y-1 text-[11px] text-slate-400 mt-2">
|
||||
<li>Google Sheets 에서 새 스프레드시트를 만들고, 1행에 name, email, message 같은 헤더를 추가합니다.</li>
|
||||
<li>시트 메뉴의 "확장 프로그램 → 앱스 스크립트" 를 열고 아래 예제 코드를 붙여넣습니다.</li>
|
||||
<li>"배포 → 새 배포" 에서 웹 앱으로 배포한 뒤, 발급된 웹 앱 URL(…/exec) 을 Webhook URL 칸에 붙여넣습니다.</li>
|
||||
</ol>
|
||||
<div className="mt-2 space-y-1">
|
||||
<span className="text-[11px] text-slate-400">예시 Apps Script 코드</span>
|
||||
<textarea
|
||||
className="w-full h-40 rounded border border-slate-800 bg-slate-950 px-2 py-1 text-[11px] font-mono text-slate-200"
|
||||
readOnly
|
||||
value={sheetsScriptExample}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user