✅ 1단계. 앱 구조 설계 (기본 틀 구성)
📦 목표
- 전체 페이지 구성 계획
- 기본 라우팅 구조 (React-Router)
- 폴더 및 컴포넌트 구조 정리
📁 폴더 구조 예시
/src
├── /components
│ ├── QuietIntroCard.jsx
│ ├── QuietChecklist.jsx
│ ├── QuietTreatmentCards.jsx
│ ├── QnaCardSlider.jsx
│ ├── QnaChatSearch.jsx
│ └── ...
├── /data
│ ├── checklistItems.js
│ ├── qnaList.js
│ └── cardDataSet.js
├── App.js
└── firebase.js
📌 라우팅 구조 예시
경로 페이지 설명
/ | 홈: 소개 + 추천 질문 |
/checklist | ADHD 자가진단 |
/quiet-adhd | 조용한 ADHD 전용 섹션 |
/treatment | 치료 방법 안내 |
/faq | 질문 슬라이드 전체 보기 |
/result | 진단 결과 및 다음 단계 |
✅ 2단계. 자가진단 기능 구현 (Checklist + 결과 안내)
🎯 목표
- ADHD 의심 여부를 간단히 확인할 수 있는 보호자용 체크리스트 구현
- 체크 결과에 따라 실시간 피드백 표시
- 추후 Firestore에 저장 또는 챗봇 추천과 연동 가능
🧩 컴포넌트명: AdhdChecklist.jsx
import React, { useState } from "react";
const checklistItems = [
"멍한 상태로 있는 시간이 많다",
"과제를 시작하거나 끝내는 데 어려움이 있다",
"자주 물건을 잃어버리거나 정리를 못한다",
"지시를 들은 듯하면서도 수행을 잘 못한다",
"말수가 적고 자기 표현이 부족하다",
"감정 표현이 적고 반응이 느리다"
];
const AdhdChecklist = () => {
const [answers, setAnswers] = useState({});
const checkedCount = Object.values(answers).filter(Boolean).length;
const handleCheck = (index, value) => {
setAnswers((prev) => ({ ...prev, [index]: value }));
};
return (
<div style={styles.card}>
<h2>조용한 ADHD 자가진단 체크리스트</h2>
<ul>
{checklistItems.map((item, idx) => (
<li key={idx}>
<label>
<input
type="checkbox"
checked={answers[idx] || false}
onChange={(e) => handleCheck(idx, e.target.checked)}
/>{" "}
{item}
</label>
</li>
))}
</ul>
<div style={styles.feedback}>
{checkedCount >= 4 ? (
<p style={{ color: "red" }}>
⚠️ 조용한 ADHD 특성이 의심됩니다. 전문가 상담이 필요할 수 있습니다.
</p>
) : (
<p style={{ color: "green" }}>
체크 항목이 적습니다. 그러나 계속 관찰이 필요할 수 있습니다.
</p>
)}
</div>
</div>
);
};
const styles = {
card: {
background: "#fff",
padding: "20px",
borderRadius: "12px",
boxShadow: "0 4px 10px rgba(0,0,0,0.1)",
maxWidth: "600px",
margin: "0 auto",
fontFamily: "sans-serif"
},
feedback: {
marginTop: "20px",
fontWeight: "bold"
}
};
export default AdhdChecklist;
✅ 연결 방식
- App.js 또는 /checklist 페이지에서 렌더링
- 상태값은 추후 Firestore 저장 또는 PDF 다운로드 기능으로 확장 가능
- 체크 항목 수를 기준으로 챗봇 추천에도 연동 가능
🧠 향후 확장 아이디어 (선택 적용)
기능 설명
✅ 항목별 피드백 | 각 문항 옆에 도움말 툴팁 표시 |
✅ PDF 출력 | 보호자가 결과를 상담 시 활용 가능 |
✅ 카드형 결과 안내 | 슬라이드형 요약 결과 안내 카드로 전환 |
✅ 3단계. 조용한 ADHD 전용 정보 카드 구현
🎯 목표
- 조용한 ADHD에 대한 개념, 증상, 오해, 진단 시기 등 보호자 대상 정보 카드 제작
- 카드 슬라이드 형태(Swiper)로 구성하여 모바일 UX 최적화
- 향후 챗봇 추천 질문과 연결 가능
🧩 주요 컴포넌트 구성
컴포넌트명 역할
QuietIntroCard.jsx | 조용한 ADHD 개념 소개 |
QuietSymptomCards.jsx | 주요 증상 슬라이드 카드 |
QuietTreatmentCards.jsx | 치료 및 대처법 안내 카드 |
QuietOutcomeFlow.jsx | 치료 지연 시 흐름도 안내 카드 |
✅ QuietIntroCard.jsx
import React from 'react';
const QuietIntroCard = () => (
<div style={styles.card}>
<h2>조용한 ADHD란?</h2>
<p>
겉으로는 얌전하고 착한 아이처럼 보이지만, 실제로는 주의력 부족과 자기조절 어려움을 겪는 ADHD의 한 유형입니다.
</p>
<ul>
<li>멍한 시간 많음</li>
<li>학습 속도 느림</li>
<li>감정 표현 부족</li>
<li>과제 시작 어려움</li>
</ul>
</div>
);
const styles = {
card: {
background: "#ffffff",
padding: "24px",
borderRadius: "12px",
boxShadow: "0 4px 8px rgba(0,0,0,0.1)",
margin: "16px auto",
maxWidth: "600px",
fontFamily: "sans-serif"
}
};
export default QuietIntroCard;
✅ QuietSymptomCards.jsx (슬라이드 구성)
import React from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/css';
const symptoms = [
"지시를 듣고도 잊는 일이 잦음",
"스스로 시작하지 못하고 기다림",
"멍하거나 반응이 느림",
"정리정돈, 준비 시간이 오래 걸림"
];
const QuietSymptomCards = () => (
<div style={{ maxWidth: "600px", margin: "auto" }}>
<h3>조용한 ADHD 주요 증상</h3>
<Swiper spaceBetween={20} slidesPerView={1}>
{symptoms.map((text, i) => (
<SwiperSlide key={i}>
<div style={styles.slide}>{text}</div>
</SwiperSlide>
))}
</Swiper>
</div>
);
const styles = {
slide: {
padding: "20px",
background: "#f5f5f5",
borderRadius: "12px",
boxShadow: "0 2px 6px rgba(0,0,0,0.1)",
minHeight: "120px",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: "18px"
}
};
export default QuietSymptomCards;
✅ QuietOutcomeFlow.jsx (치료 지연 시 결과 흐름도)
import React from 'react';
const stages = [
"초기 학습 실패",
"과제 회피 및 성취감 저하",
"자존감 하락 및 자기 부정",
"우울/불안, 대인 기피",
"진로 포기 및 사회기능 저하"
];
const QuietOutcomeFlow = () => (
<div style={styles.container}>
<h3>치료 시기를 놓치면?</h3>
<div style={styles.flow}>
{stages.map((stage, index) => (
<div key={index}>
<div style={styles.box}>{stage}</div>
{index < stages.length - 1 && <span style={styles.arrow}>↓</span>}
</div>
))}
</div>
</div>
);
const styles = {
container: {
background: "#fff",
padding: "20px",
borderRadius: "12px",
boxShadow: "0 2px 6px rgba(0,0,0,0.1)",
textAlign: "center"
},
flow: {
marginTop: "12px",
display: "flex",
flexDirection: "column",
alignItems: "center"
},
box: {
padding: "10px 16px",
background: "#f0f0f0",
borderRadius: "8px",
margin: "8px 0"
},
arrow: {
fontSize: "24px",
color: "#bbb"
}
};
export default QuietOutcomeFlow;
📌 통합 구성 페이지 예시: /quiet-adhd
import QuietIntroCard from './QuietIntroCard';
import QuietSymptomCards from './QuietSymptomCards';
import QuietOutcomeFlow from './QuietOutcomeFlow';
const QuietAdhdPage = () => (
<>
<QuietIntroCard />
<QuietSymptomCards />
<QuietOutcomeFlow />
</>
);
export default QuietAdhdPage;
✅ 4단계. Q&A 챗봇 추천 기능 구현 (자연어 질문 → 유사 Q&A 카드 매칭)
🎯 목표
- 보호자가 질문을 입력하면, 관련 키워드를 기반으로 가장 유사한 Q&A 카드 추천
- 추천된 카드의 슬라이드(QnaCardSlider)로 자동 연결
- 향후 OpenAI Embedding 기반 추천도 적용 가능
🧩 컴포넌트: QnaChatSearch.jsx
import React, { useState } from "react";
import { qnaList } from "../data/qnaList"; // 질문 DB import
const QnaChatSearch = ({ onSelect }) => {
const [input, setInput] = useState("");
const [matched, setMatched] = useState(null);
const searchQna = () => {
const lower = input.toLowerCase();
const result = qnaList
.map((item) => ({
...item,
score: item.keywords.filter(k => lower.includes(k)).length
}))
.sort((a, b) => b.score - a.score)[0];
if (result && result.score > 0) {
setMatched(result);
onSelect(result.id); // 카드 연결
} else {
setMatched(null);
}
};
return (
<div>
<input
value={input}
onChange={e => setInput(e.target.value)}
placeholder="궁금한 점을 입력하세요"
style={{ padding: "10px", width: "80%" }}
/>
<button onClick={searchQna}>검색</button>
{matched && (
<div style={{ marginTop: "10px", color: "green" }}>
👉 관련 질문 추천: <strong>{matched.title}</strong>
</div>
)}
</div>
);
};
export default QnaChatSearch;
🗃️ 데이터 예시: qnaList.js
export const qnaList = [
{
id: "q1",
title: "ADHD는 유전되나요?",
keywords: ["유전", "부모", "가족력"]
},
{
id: "q2",
title: "조용한 ADHD는 어떤 특징이 있나요?",
keywords: ["조용한", "멍함", "말이 없음", "부주의"]
},
{
id: "q3",
title: "감정조절이 어렵고 자주 화를 냅니다.",
keywords: ["감정", "분노", "조절", "욱함"]
}
];
✅ 연결: 카드 슬라이드 컴포넌트 예시 (QnaCardSlider)
import { cardDataSet } from "../data/cardDataSet"; // 카드 DB
const App = () => {
const [selectedId, setSelectedId] = useState(null);
return (
<>
<QnaChatSearch onSelect={setSelectedId} />
{selectedId && <QnaCardSlider cards={cardDataSet[selectedId]} />}
</>
);
};
📌 UX 개선 제안
기능 설명
🔄 실시간 추천 | 입력 도중 자동 추천 |
💬 추천 버튼 | 자주 묻는 질문 바로가기 버튼 |
📚 유사도 점수 시각화 | 연관도 표시 (ex. 별점 or 색상) |
✅ 요약
- ✅ 보호자가 키워드 기반 질문 → 자동 추천
- ✅ 관련 카드 슬라이드로 연결
- ✅ Firestore나 JSON 기반 데이터 연결 가능
- ✅ 향후 Embedding → 의미 기반 추천 확장 가능
✅ 5단계. 카드 슬라이드 기반 Q&A 콘텐츠 구성
🎯 목표
- 자주 묻는 질문(FAQ)을 주제별로 카드 슬라이드 형식으로 구성
- 카드 하나당 핵심 메시지 1개로 구성
- 출처 및 논문 링크 포함 가능
- Swiper 슬라이드로 모바일 UX에 최적화
📁 예시 데이터 구조: cardDataSet.js
export const cardDataSet = {
q1: [
{
content: "ADHD는 유전성이 70~80%에 달하는 신경발달장애입니다."
},
{
content: "부모 중 한 명이 ADHD일 경우, 자녀에게도 유전될 가능성이 높습니다."
},
{
content: "하지만 환경적 개입으로 증상 발현을 조절할 수 있습니다."
},
{
content: "Faraone et al. (2005): ADHD 유전율 76%",
reference: {
title: "Faraone et al., 2005",
link: "https://doi.org/10.1016/j.biopsych.2005.02.017"
}
}
],
q2: [
{
content: "조용한 ADHD는 눈에 띄지 않지만 주의력 결핍과 정서적 어려움이 심할 수 있습니다."
},
{
content: "멍한 상태, 반응이 느림, 자기주도 부족 등의 양상으로 나타납니다."
},
{
content: "성격이 아닌 신경 발달 문제입니다."
}
]
};
🧩 컴포넌트: QnaCardSlider.jsx
import React from "react";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";
const QnaCardSlider = ({ cards }) => (
<Swiper spaceBetween={30} slidesPerView={1}>
{cards.map((card, idx) => (
<SwiperSlide key={idx}>
<div style={styles.card}>
<p>{card.content}</p>
{card.reference && (
<a
href={card.reference.link}
target="_blank"
rel="noopener noreferrer"
style={styles.ref}
>
📖 {card.reference.title}
</a>
)}
</div>
</SwiperSlide>
))}
</Swiper>
);
const styles = {
card: {
padding: "20px",
background: "#fff",
borderRadius: "12px",
boxShadow: "0 4px 8px rgba(0,0,0,0.1)",
minHeight: "140px"
},
ref: {
fontSize: "14px",
marginTop: "10px",
display: "block",
color: "#888"
}
};
export default QnaCardSlider;
✅ UX 디자인 팁
항목 제안
✅ 배경색 구분 | 각 카드 주제별 색상 또는 아이콘 |
✅ 글자 수 제한 | 카드당 200자 이내로 유지 |
✅ 키워드 강조 | 핵심 단어 굵게 또는 컬러 처리 |
🧠 연계 기능
연동 기능 설명
🔎 QnaChatSearch | 자동 질문 추천 → 카드 슬라이드 연결 |
📚 /faq 페이지 | 모든 Q&A 카드 리스트로 보기 |
✅ 즐겨찾기 | 마음에 든 카드 저장 (선택 기능) |
✅ 6단계. Firebase 대신 Google Sheets/Forms 연동 설계
🔧 선택지 1: Google Form 연동 (가장 쉬운 방법)
항목 설명
사용 방법 | 체크리스트 응답을 Google Form URL에 연결 |
특징 | 보호자가 입력 → 설문 제출 → Google Sheets 자동 기록 |
UX | 별도 페이지로 이동 (또는 iframe 내 삽입) |
✅ 장점
- 매우 빠르고 쉬운 설정
- 구글 시트에 자동 저장됨
- 개인정보 저장 안내 메시지 삽입 가능
📌 예시 흐름
- 앱 내 체크리스트 완료 후 버튼 노출
- “결과 요약 보기 / 의견 제출하기” 클릭
- Google Form 링크로 이동 or iframe으로 표시
- Google Sheets에 응답 저장됨
✅ 구글폼 연동 예시 버튼
결과 보내기 (기록은 남지 않아요)
✳️ 버튼 위 안내 문구:
“입력한 내용은 앱에 저장되지 않습니다.”
🔧 선택지 2: Google Sheets API 직접 연동
항목 설명
사용 방법 | 앱 내 응답을 API로 구글 시트에 POST 전송 |
인증 방식 | Google Apps Script 또는 OAuth2 인증 필요 |
UX | 사용자는 앱 내에서 바로 제출 가능 |
✅ 장점
- UX가 매끄럽고 바로 제출됨
- 자동화가 가능함
❗ 단점
- 개발자 등록/스크립트 실행 필요 (조금 복잡)
📌 추천 구성
방식 추천 용도
✅ Google Form | 간단한 설문/자가진단 결과 수집 |
✅ Google Sheets API | 자가진단 점수/문항별 선택 내용 저장 |
❌ Firebase | 개인 데이터 보관이 필요한 경우만 사용 |
// ✅ Google Apps Script 파일 (Sheets 연동 백엔드)
// ➤ Google Sheets에 직접 데이터를 기록하는 Web App 형식의 API입니다.
function doPost(e) {
var sheet = SpreadsheetApp.openById("YOUR_SHEET_ID").getSheetByName("응답");
var data = JSON.parse(e.postData.contents);
var timestamp = new Date();
sheet.appendRow([
timestamp,
data.name || "익명",
data.score || 0,
data.answers.join(", ") || "응답 없음"
]);
return ContentService.createTextOutput(
JSON.stringify({ result: "success" })
).setMimeType(ContentService.MimeType.JSON);
}
// ✅ 필요한 Google Sheet 예시 구조
// | Timestamp | Name | Score | Answers |
// ✅ WebApp으로 배포 시 필요 설정
// 1. Apps Script → 배포 → 새 배포
// 2. 유형: 웹 앱 / 누구나 액세스 가능 / 익명 실행 허용
// 3. 배포 URL 확보 → React 앱에서 이 주소로 POST 요청
/* ✅ React 앱에서 POST 요청 예시
fetch("https://script.google.com/macros/s/your-script-id/exec", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: "홍길동",
score: 5,
answers: ["멍함", "정리 안됨"]
})
})
.then((res) => res.json())
.then((data) => console.log("제출 결과:", data));
*/
✅ 정리: 구현 포인트
항목 구현 내용
🔒 안내 문구 | “이 앱은 정보를 저장하지 않으며, 결과는 Google 설문을 통해 익명으로 수집됩니다.” |
🔗 폼 링크 삽입 | 체크리스트 후 제출 버튼 or 결과 요약 후 연결 |
📋 응답 필드 | 점수 총합, 주요 체크 항목, 간단한 피드백 등 |
✅ 7단계. 결과 안내 UI 및 Google Sheets 전송 연동
🎯 목표
- 체크리스트 완료 후 결과를 보호자에게 직관적으로 안내
- 동시에 Google Sheets API에 데이터 익명 전송
- "앱에 정보가 저장되지 않는다"는 안내 포함
✅ 결과 안내 컴포넌트: ChecklistResult.jsx
import React from "react";
const ChecklistResult = ({ name = "익명 보호자", score, answers }) => {
const submitToSheet = async () => {
const response = await fetch("https://script.google.com/macros/s/your-script-id/exec", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name, score, answers })
});
const result = await response.json();
alert("결과가 성공적으로 제출되었습니다.");
console.log(result);
};
return (
자가진단 결과
✅ 이름: {name}
✅ 체크 항목 수: {score}개
📝 선택 항목: {answers.join(", ")}
{score >= 4 ? (⚠️ 조용한 ADHD 특성이 의심됩니다. 전문가 상담을 권장합니다.
) : (체크 항목은 적지만, 지속적 관찰이 필요할 수 있습니다.
)}🛡️ 이 앱은 개인정보를 저장하지 않으며, 입력 내용은 Google Sheets에 익명으로 전송됩니다.
);
};
const styles = {
card: {
background: "#fff",
padding: "24px",
borderRadius: "12px",
boxShadow: "0 4px 8px rgba(0,0,0,0.1)",
marginTop: "20px",
fontFamily: "sans-serif"
},
button: {
marginTop: "16px",
padding: "10px 18px",
fontWeight: "bold",
border: "none",
borderRadius: "8px",
backgroundColor: "#4CAF50",
color: "#fff",
cursor: "pointer"
},
privacy: {
marginTop: "16px",
fontSize: "13px",
color: "#888"
}
};
export default ChecklistResult;
✅ 통합 흐름 예시
import { useState } from "react";
import AdhdChecklist from "./AdhdChecklist";
import ChecklistResult from "./ChecklistResult";
const App = () => {
const [submitted, setSubmitted] = useState(false);
const [result, setResult] = useState({ score: 0, answers: [] });
return (
<div>
{!submitted ? (
<AdhdChecklist
onComplete={(score, answers) => {
setResult({ score, answers });
setSubmitted(true);
}}
/>
) : (
<ChecklistResult
name="익명 보호자"
score={result.score}
answers={result.answers}
/>
)}
</div>
);
};
※ AdhdChecklist에서 onComplete(score, answers) 콜백 전달 필요
📌 UX 최종 요약
항목 설명
✅ 실시간 결과 안내 | 체크 완료 후 점수와 항목 요약 |
✅ API 연동 | Google Sheets로 전송 |
✅ 익명성 안내 | 저장하지 않음 + 외부 전송 투명 안내 |
✅ 반응형 UI | 모바일에서도 시각적으로 일관되게 동작 |
✅ 8단계. 홈 화면 구성 및 전체 메뉴 연결 (앱의 중심 뼈대)
🎯 목표
- 앱 진입 시 보호자가 쉽게 탐색할 수 있도록 홈 화면 구성
- 자주 묻는 질문 추천, 진단, 카드 탐색 기능 연결
- React Router 기반으로 페이지 연결
✅ 홈 화면 UI: Home.jsx
import { Link } from "react-router-dom";
const Home = () => (
<div style={styles.container}>
<h1>🧠 ADHD 보호자 Q&A 앱</h1>
<p style={styles.intro}>자녀의 ADHD에 대해 궁금한 점을 질문하고, 체크하고, 배우세요.</p>
<ul style={styles.menu}>
<li><Link to="/checklist">✅ 자가진단 체크리스트</Link></li>
<li><Link to="/quiet-adhd">🔍 조용한 ADHD 알아보기</Link></li>
<li><Link to="/faq">💬 자주 묻는 질문 (Q&A 카드)</Link></li>
<li><Link to="/ask">🤖 궁금한 점 질문하기</Link></li>
</ul>
<p style={styles.note}>개발자: <strong>참리더</strong> | 이 앱은 정보를 저장하지 않습니다.</p>
</div>
);
const styles = {
container: {
padding: "24px",
fontFamily: "sans-serif",
textAlign: "center"
},
intro: {
marginTop: "8px",
fontSize: "16px",
color: "#666"
},
menu: {
listStyle: "none",
marginTop: "24px",
padding: 0
},
note: {
marginTop: "36px",
fontSize: "13px",
color: "#888"
}
};
export default Home;
✅ React Router 설정 (App.js 또는 Routes.js)
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import ChecklistPage from "./pages/ChecklistPage";
import QuietAdhdPage from "./pages/QuietAdhdPage";
import FaqPage from "./pages/FaqPage";
import AskPage from "./pages/AskPage";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/checklist" element={<ChecklistPage />} />
<Route path="/quiet-adhd" element={<QuietAdhdPage />} />
<Route path="/faq" element={<FaqPage />} />
<Route path="/ask" element={<AskPage />} />
</Routes>
</BrowserRouter>
);
}
export default App;
✅ 주요 연결 구성도
[홈]
├── ✅ /checklist → AdhdChecklist + ChecklistResult
├── 🔍 /quiet-adhd → 조용한 ADHD 정보 카드
├── 💬 /faq → 모든 Q&A 카드 슬라이드
├── 🤖 /ask → QnaChatSearch + 자동 추천
✅ 모바일 UI 예시 (Figma 참조)
- 버튼은 최소 48px 이상, 아이콘 사용
- 제목은 20
24px, 설명은 1416px - 전체 페이지는 1열 세로 스크롤 기반 구성
✅ 8단계 요약
항목 내용
📌 홈 메뉴 | 진단, 정보, 질문, 전체 FAQ 연결 |
🧭 경로 이동 | React Router 기반 메뉴 연결 |
🎨 UI 안내 | 직관적 + 보호자 중심 메뉴 구성 |
🙋 개발자 | 하단에 개발자: 참리더 명시 |
✅ 9단계. 앱 전체 스타일 통합 및 반응형 UI 최적화
🎯 목표
- 일관된 폰트, 여백, 카드 스타일을 전역에 적용
- 모바일 중심 UX 최적화 (세로 스크롤 구조, 버튼 터치 영역)
- Dark Mode 대비 고려 (선택)
✅ 1. 전역 스타일 정의 (App.css 또는 Tailwind 사용 시 기본 설정)
/* App.css */
body {
font-family: 'Noto Sans KR', sans-serif;
background-color: #f8f9fa;
margin: 0;
padding: 0;
color: #333;
}
h1, h2, h3 {
color: #222;
}
a {
text-decoration: none;
color: #3366cc;
}
button {
font-size: 16px;
padding: 10px 16px;
border-radius: 8px;
border: none;
cursor: pointer;
background-color: #4CAF50;
color: white;
}
button:hover {
background-color: #43a047;
}
✅ 2. 공통 카드 스타일 컴포넌트 CardWrapper.jsx
const CardWrapper = ({ children }) => (
<div style={{
backgroundColor: '#fff',
padding: '20px',
borderRadius: '12px',
boxShadow: '0 4px 8px rgba(0,0,0,0.1)',
margin: '16px auto',
maxWidth: '640px'
}}>
{children}
</div>
);
export default CardWrapper;
모든 정보 카드, 결과 안내, 체크리스트 등을 CardWrapper로 감싸서 통일된 디자인 유지
✅ 3. 반응형 구성 포인트
항목 모바일 최적화
✅ 폰트 크기 | 제목 20~24px, 본문 14~16px |
✅ 카드 너비 | max-width: 640px, width: 90vw 적용 |
✅ 버튼 크기 | 최소 높이 48px, 클릭 영역 충분히 확보 |
✅ 메뉴 구조 | 햄버거 메뉴 없이 단순한 수직 나열형 권장 |
✅ 레이아웃 | 세로 스크롤 중심 단일 컬럼 구조 사용 |
✅ 4. 다크모드 대응 (선택)
@media (prefers-color-scheme: dark) {
body {
background-color: #121212;
color: #eee;
}
.card {
background-color: #1e1e1e;
}
a {
color: #80bfff;
}
}
✅ 최종 앱 스타일 통일 체크리스트 ✅
항목 적용 여부
✅ 카드 배경, 그림자, 간격 통일 | ✔️ |
✅ 버튼 색상 및 마진 통일 | ✔️ |
✅ 반응형 폰트 및 여백 조정 | ✔️ |
✅ 모바일 기준 터치 영역 최적화 | ✔️ |
✅ 다크모드 고려 | (선택사항) |
✅ 10단계. 앱 배포 및 개발자 표시
🎯 목표
- 앱을 웹에서 누구나 접속 가능하도록 배포
- 하단 또는 메뉴에 “개발자: 참리더” 명확히 표기
- 선택적으로 PWA(앱처럼 설치 가능) 기능도 적용 가능
🛠️ 배포 방식 선택
방식 설명 추천
✅ Vercel | React + Git 연동 자동 배포 | ⭐ 추천 |
✅ Netlify | 쉬운 설정, 무료 호스팅 | 간편 |
✅ Firebase Hosting | 정적 사이트 배포 + 확장성 | 필요 시 |
✅ GitHub Pages | 기본 정적 배포, 무료 | 단순 |
✅ 예시: Vercel 배포 절차
- https://vercel.com 에서 GitHub 계정 연동
- Create Project → GitHub 저장소 선택
- Framework: React
- 자동 빌드 + 배포 진행
- https://your-project.vercel.app 형식으로 앱 주소 생성
✅ 개발자 표기
방법 1. 홈 하단
<p style={{ fontSize: "13px", color: "#999", marginTop: "24px" }}>
📌 개발자: <strong>참리더</strong><br />
본 앱은 보호자 교육을 위해 제작된 비영리 프로젝트입니다.
</p>
방법 2. 앱 전체 Footer 컴포넌트
const Footer = () => (
<footer style={{
textAlign: 'center',
fontSize: '12px',
color: '#888',
padding: '24px 0'
}}>
개발자: <strong>참리더</strong> | 정보는 앱에 저장되지 않습니다.
</footer>
);
모든 페이지에 포함하려면 <Footer />를 App.js에 삽입
✅ 결과 예시
🔗 https://adhd-parent-guide.vercel.app
📱 "ADHD 보호자 Q&A 앱"
🧑💻 개발자: 참리더
✅ PWA (선택 기능)
앱을 모바일 홈화면에 설치 가능한 형태로 만들 수 있습니다.
npm install react-pwa
manifest.json, serviceWorker 설정을 추가하면 ‘앱 설치’ 가능하게 됩니다. (필요하시면 이어서 도와드릴 수 있어요)
✅ 전체 개발 요약
단계 내용
1~2단계 | 자가진단 체크리스트 구현 |
3~5단계 | Q&A 카드 슬라이드, 챗봇 연동 |
6단계 | Google Sheets 익명 결과 전송 |
7~9단계 | 결과 안내, 스타일 통합, 반응형 최적화 |
✅ 10단계 | 배포 및 ‘개발자: 참리더’ 표시 |
🎉 완료되었습니다!
이제 보호자와 교사가 사용할 수 있는 완성형 ADHD Q&A 앱이 탄생했습니다.
필요하시면:
- 앱 설명서 / 운영 가이드
- 블로그 / 안내문 / 배너 이미지
- 추가 기능 (로그인, 댓글, 음성 인식 등)
도 함께 제작해드릴 수 있습니다.
어떤 후속 작업이 필요하신가요? 😊