왜 만들었나
러시아 환자는 한국 병원 정보를 자기 언어로 찾기 어렵고, 연락도 주로 메신저로 합니다. 회원가입 없이 시술을 담아 입력칸 몇 개만 채우면 문의가 끝나도록 만들었습니다.
주요 기능
- 러시아어·한국어·영어 전환 (브라우저 언어 자동 감지)
- 증상·시술 키워드 검색 (러/한/영 이름·설명·키워드 동시 검색)
- '내 플랜'에 여러 시술 담기, 가격 범위 합계 표시
- 문의 내용을 메시지로 자동 작성해 Telegram·WhatsApp으로 연결
- #/admin 문의 관리 화면 (상태 변경·CSV 내보내기)
숫자로 보면
어떻게 동작하나
데이터 로드
categories·procedures·clinics JSON 세 개를 Promise.all로 불러와 DB 객체에 담고, 저장된 플랜에서 없는 시술 id를 걸러냅니다.
assets/app.js해시 라우팅
route()가 #/c/:id, #/clinic/:id, #/admin을 보고 카테고리·병원·관리 화면 중 하나를 그립니다.
assets/app.js검색
searchResults()가 시술의 러/한/영 이름·설명·카테고리명·키워드를 한 문자열로 합쳐, 입력한 단어가 모두 들어 있는 시술만 남깁니다.
assets/app.js플랜 담기
togglePlan()이 시술 id 배열을 localStorage에 저장하고, 화면의 모든 담기 버튼과 하단 플랜 바를 함께 갱신합니다.
assets/app.js문의 제출
submitLead()가 이름·연락처·동의를 확인한 뒤 leads 스키마와 같은 모양의 객체를 저장하고, buildMessage()로 만든 글을 wa.me 링크에 넣거나 텔레그램용으로 클립보드에 복사합니다.
assets/app.jsDB 이관 준비
같은 필드 구조를 Postgres 테이블 4개로 정의하고, leads는 익명 insert만, 조회·수정은 인증 사용자만 허용하는 RLS 정책을 걸어 두었습니다.
supabase/schema.sql
핵심 코드
function buildMessage(d, items) {
const lines = [t('msg_head'), ''];
lines.push(`${t('msg_proc')}: ` + (items.length ? '' : t('msg_general')));
items.forEach(p => { const cl = p.clinic && clinicById(p.clinic); lines.push(`• ${L(p.name)}${cl ? ` — ${cl.name}` : ''} (${priceShort(p)})`); });
lines.push('', `${t('msg_name')}: ${d.name}`);
if (d.city) lines.push(`${t('msg_city')}: ${d.city}`);
lines.push(`${t('msg_contact')}: ${d.channel} ${d.contact}`);
if (d.message) lines.push(`${t('msg_note')}: ${d.message}`);
return lines.join('\n');
}플랜에 담은 시술과 입력값으로 메신저에 바로 보낼 문의 메시지를 현재 언어로 조립합니다.

