Compare commits
4 Commits
2db78e6bec
...
b4691b029a
| Author | SHA1 | Date |
|---|---|---|
|
|
b4691b029a | |
|
|
4f6c30e249 | |
|
|
03c3c7ab21 | |
|
|
156dad59dc |
|
|
@ -2,7 +2,7 @@
|
||||||
* /test 페이지 + 향후 E2E·부하 테스트용 목업 병원 URL 데이터.
|
* /test 페이지 + 향후 E2E·부하 테스트용 목업 병원 URL 데이터.
|
||||||
*
|
*
|
||||||
* 7개 채널: homepage, youtube, instagram, facebook, naverPlace, naverBlog, gangnamUnni
|
* 7개 채널: homepage, youtube, instagram, facebook, naverPlace, naverBlog, gangnamUnni
|
||||||
* 빈 채널은 분석에서 제외됨. naverPlace는 수동 확인 필요(숫자 ID 기반).
|
* 빈 채널은 분석에서 제외됨.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface ChannelUrls {
|
export interface ChannelUrls {
|
||||||
|
|
@ -24,121 +24,121 @@ export const CLINICS: ClinicFixture[] = [
|
||||||
{
|
{
|
||||||
label: '뷰성형외과',
|
label: '뷰성형외과',
|
||||||
urls: {
|
urls: {
|
||||||
homepage: 'viewclinic.com',
|
homepage: 'https://www.viewclinic.com',
|
||||||
youtube: 'youtube.com/channel/UCQqqH3Klj2HQSHNNSVug-CQ',
|
youtube: 'https://www.youtube.com/@ViewclinicKR',
|
||||||
instagram: 'instagram.com/viewplastic',
|
instagram: 'https://www.instagram.com/viewplastic/',
|
||||||
facebook: 'facebook.com/viewps1',
|
facebook: 'https://www.facebook.com/viewps1/',
|
||||||
naverPlace: 'https://naver.me/x9BxGXkK',
|
naverPlace: 'https://m.place.naver.com/hospital/11709005',
|
||||||
naverBlog: 'blog.naver.com/viewclinicps',
|
naverBlog: 'https://blog.naver.com/viewclinicps',
|
||||||
gangnamUnni: 'gangnamunni.com/hospitals/189',
|
gangnamUnni: 'https://www.gangnamunni.com/hospitals/189',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '바노바기성형외과',
|
label: '바노바기성형외과',
|
||||||
urls: {
|
urls: {
|
||||||
homepage: 'banobagi.com',
|
homepage: 'https://www.banobagi.com',
|
||||||
youtube: 'youtube.com/c/banobagips',
|
youtube: 'https://www.youtube.com/c/banobagips',
|
||||||
instagram: 'instagram.com/banobagi_ps',
|
instagram: 'https://www.instagram.com/banobagi_ps/',
|
||||||
facebook: 'facebook.com/BanobagiPlasticSurgery',
|
facebook: 'https://www.facebook.com/BanobagiPlasticSurgery',
|
||||||
naverPlace: 'https://naver.me/xxY2yLr5',
|
naverPlace: 'https://m.place.naver.com/hospital/21033469',
|
||||||
naverBlog: 'blog.naver.com/banobagiprs',
|
naverBlog: 'https://blog.naver.com/banobagips',
|
||||||
gangnamUnni: 'gangnamunni.com/hospitals/23',
|
gangnamUnni: 'https://www.gangnamunni.com/hospitals/23',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'ID 성형외과',
|
label: '아이디병원',
|
||||||
urls: {
|
urls: {
|
||||||
homepage: 'idhospital.com',
|
homepage: 'https://www.idhospital.com',
|
||||||
youtube: 'youtube.com/user/IDhospital',
|
youtube: 'https://www.youtube.com/user/IDhospital',
|
||||||
instagram: 'instagram.com/idhospital',
|
instagram: 'https://www.instagram.com/idhospital',
|
||||||
facebook: 'facebook.com/idhospital0050',
|
facebook: 'https://www.facebook.com/idhospital0050',
|
||||||
naverPlace: 'https://naver.me/GtURpCEn',
|
naverPlace: 'https://m.place.naver.com/hospital/11548359',
|
||||||
naverBlog: '',
|
naverBlog: 'https://blog.naver.com/idfacial',
|
||||||
gangnamUnni: 'gangnamunni.com/hospitals/257',
|
gangnamUnni: 'https://www.gangnamunni.com/hospitals/257',
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'JK 성형외과',
|
|
||||||
urls: {
|
|
||||||
homepage: 'jkplastic.com',
|
|
||||||
youtube: 'youtube.com/channel/UC5F8dEt32hdp3cTeFyls4qg',
|
|
||||||
instagram: 'instagram.com/jkplasticsurgery_kr',
|
|
||||||
facebook: 'facebook.com/jkmedicalgroup',
|
|
||||||
naverPlace: 'https://naver.me/x67y6cAc',
|
|
||||||
naverBlog: 'blog.naver.com/jkstory1',
|
|
||||||
gangnamUnni: 'gangnamunni.com/hospitals/858',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '그랜드성형외과',
|
label: '그랜드성형외과',
|
||||||
urls: {
|
urls: {
|
||||||
homepage: 'grandsurgery.com',
|
homepage: 'https://www.grandsurgery.com',
|
||||||
youtube: 'youtube.com/channel/UCU2o_aHqsNFuqwtdzVM3xbQ',
|
youtube: 'https://www.youtube.com/channel/UCU2o_aHqsNFuqwtdzVM3xbQ',
|
||||||
instagram: 'instagram.com/grand_korea',
|
instagram: 'https://www.instagram.com/grand_korea/',
|
||||||
facebook: 'facebook.com/grandps.korea',
|
facebook: 'https://www.facebook.com/grandps.korea',
|
||||||
naverPlace: 'https://naver.me/Fw7MYKWK',
|
naverPlace: 'https://m.place.naver.com/hospital/12322994',
|
||||||
naverBlog: 'blog.naver.com/grandprs',
|
naverBlog: 'https://blog.naver.com/grandprs',
|
||||||
gangnamUnni: 'gangnamunni.com/hospitals/62',
|
gangnamUnni: 'https://www.gangnamunni.com/hospitals/62',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'BK 성형외과',
|
label: '원진성형외과',
|
||||||
urls: {
|
urls: {
|
||||||
homepage: 'bkhospital.com',
|
homepage: 'https://www.k-wonjin.co.kr',
|
||||||
youtube: 'youtube.com/channel/UChJONft3hemy5DGbXUveTFg',
|
youtube: 'https://www.youtube.com/@wjwonjin',
|
||||||
instagram: 'instagram.com/bkhospital_korea',
|
instagram: 'https://www.instagram.com/wonjin_official/',
|
||||||
facebook: '',
|
facebook: 'https://www.facebook.com/KwonjinPS',
|
||||||
naverPlace: 'https://naver.me/517CTH3W',
|
naverPlace: 'https://m.place.naver.com/hospital/11887873',
|
||||||
naverBlog: '',
|
naverBlog: 'https://blog.naver.com/popokpop',
|
||||||
gangnamUnni: '',
|
gangnamUnni: 'https://www.gangnamunni.com/hospitals/2500',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '톡스앤필',
|
label: '나나성형외과',
|
||||||
urls: {
|
urls: {
|
||||||
homepage: 'toxnfill.com',
|
homepage: 'https://www.nanaprs.com',
|
||||||
youtube: 'youtube.com/channel/UCFpFZkm7mclD-z_-j7FTUag',
|
youtube: 'https://www.youtube.com/@Nanaprstv',
|
||||||
instagram: 'instagram.com/toxnfill_official',
|
instagram: 'https://www.instagram.com/nanaprs/',
|
||||||
facebook: 'facebook.com/toxnfill.official',
|
facebook: 'https://www.facebook.com/nanaprs2',
|
||||||
naverPlace: 'https://naver.me/FvEmJIHA',
|
naverPlace: 'https://m.place.naver.com/hospital/1518147116',
|
||||||
naverBlog: 'blog.naver.com/toxnfill',
|
naverBlog: 'https://blog.naver.com/nanaprs1',
|
||||||
gangnamUnni: 'gangnamunni.com/hospitals/3702',
|
gangnamUnni: 'https://www.gangnamunni.com/hospitals/938',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '더 압구정 성형외과',
|
label: '디에이성형외과',
|
||||||
urls: {
|
urls: {
|
||||||
homepage: 'theclinic.co.kr',
|
homepage: 'https://daprs.com',
|
||||||
youtube: 'youtube.com/user/theplasticsurgery1',
|
youtube: 'https://www.youtube.com/channel/UC0wlA-w5JIt0G0EeWQf65AQ',
|
||||||
instagram: 'instagram.com/the_plasticsurgery',
|
instagram: 'https://www.instagram.com/da_plastic_surgery',
|
||||||
facebook: 'facebook.com/THEPS16445998',
|
facebook: 'https://www.facebook.com/daprs/',
|
||||||
naverPlace: '',
|
naverPlace: 'https://m.place.naver.com/hospital/33084820',
|
||||||
naverBlog: 'blog.naver.com/with_theps',
|
naverBlog: 'https://blog.naver.com/daprs',
|
||||||
gangnamUnni: 'gangnamunni.com/hospitals/30',
|
gangnamUnni: 'https://www.gangnamunni.com/hospitals/250',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '라마르 성형외과',
|
label: '노트성형외과',
|
||||||
urls: {
|
urls: {
|
||||||
homepage: 'lamarps.com',
|
homepage: 'http://notebreast.com',
|
||||||
youtube: '',
|
youtube: 'https://www.youtube.com/channel/UC2OIyb2serotqDyEzQYyCtA',
|
||||||
instagram: '',
|
instagram: 'https://www.instagram.com/note.prs/',
|
||||||
facebook: '',
|
facebook: 'https://www.facebook.com/noteprs2/',
|
||||||
naverPlace: '',
|
naverPlace: 'https://m.place.naver.com/hospital/1572670484',
|
||||||
naverBlog: '',
|
naverBlog: 'https://blog.naver.com/noteprs01',
|
||||||
gangnamUnni: '',
|
gangnamUnni: 'https://www.gangnamunni.com/hospitals/2186',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '오라클 성형외과',
|
label: '에이비성형외과',
|
||||||
urls: {
|
urls: {
|
||||||
homepage: 'oracleclinic.com',
|
homepage: 'https://www.abps.co.kr',
|
||||||
youtube: 'youtube.com/@oracle_medical_group',
|
youtube: 'https://www.youtube.com/@abplasticsurgery',
|
||||||
instagram: 'instagram.com/oraclemedicalgroup',
|
instagram: 'https://www.instagram.com/ab_plasticsurgery_kr/',
|
||||||
facebook: 'facebook.com/oracleclinickr',
|
facebook: 'https://www.facebook.com/profile.php?id=100063560996454',
|
||||||
naverPlace: 'https://naver.me/GhbU3VtK',
|
naverPlace: 'https://m.place.naver.com/hospital/1304260302',
|
||||||
naverBlog: '',
|
naverBlog: 'https://blog.naver.com/abps20',
|
||||||
gangnamUnni: 'gangnamunni.com/hospitals/125',
|
gangnamUnni: 'https://www.gangnamunni.com/hospitals/3004',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '제이준성형외과',
|
||||||
|
urls: {
|
||||||
|
homepage: 'http://www.jjprs.com',
|
||||||
|
youtube: 'https://www.youtube.com/channel/UC1p4msJnetDKeOW-B4nlwZA',
|
||||||
|
instagram: 'https://www.instagram.com/jayjunps/',
|
||||||
|
facebook: 'https://www.facebook.com/jayjunps',
|
||||||
|
naverPlace: 'https://m.place.naver.com/hospital/36294945',
|
||||||
|
naverBlog: 'https://blog.naver.com/gusrlf00',
|
||||||
|
gangnamUnni: 'https://www.gangnamunni.com/hospitals/139',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,26 @@
|
||||||
/**
|
/**
|
||||||
* /test — 고정 병원 fixture 를 디폴트로 채워 분석 플로우를 빠르게 검증하는 dev 페이지.
|
* /test — 고정 병원 fixture 를 디폴트로 채워 분석 플로우를 빠르게 검증하는 dev 페이지.
|
||||||
*
|
*
|
||||||
* - 진입 시 PINNED_LABEL fixture 로 form prefill
|
* - 상단 칩 그룹으로 10개 fixture 중 선택 (디폴트 PINNED_LABEL)
|
||||||
|
* - 선택 변경 시 MultiChannelInput 을 `key` 로 강제 리마운트 → 깔끔 prefill
|
||||||
* - DevOnly 가드 아래 등록되어 localhost 에서만 접근
|
* - DevOnly 가드 아래 등록되어 localhost 에서만 접근
|
||||||
*/
|
*/
|
||||||
|
import { useState } from 'react'
|
||||||
import { useNavigate } from 'react-router'
|
import { useNavigate } from 'react-router'
|
||||||
import MultiChannelInput, { type AnalyzePayload } from '@/features/channels/components/MultiChannelInput'
|
import MultiChannelInput, { type AnalyzePayload } from '@/features/channels/components/MultiChannelInput'
|
||||||
import { CLINICS } from '../fixtures/mockUrls'
|
import { CLINICS } from '../fixtures/mockUrls'
|
||||||
|
|
||||||
const PINNED_LABEL = '뷰성형외과'
|
const PINNED_LABEL = '뷰성형외과'
|
||||||
|
|
||||||
function pickIndex(): number {
|
function pickInitialIndex(): number {
|
||||||
const i = CLINICS.findIndex((c) => c.label === PINNED_LABEL)
|
const i = CLINICS.findIndex((c) => c.label === PINNED_LABEL)
|
||||||
return i >= 0 ? i : 0
|
return i >= 0 ? i : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TestPrefillPage() {
|
export default function TestPrefillPage() {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const clinic = CLINICS[pickIndex()]
|
const [selectedIdx, setSelectedIdx] = useState<number>(pickInitialIndex)
|
||||||
|
const clinic = CLINICS[selectedIdx]
|
||||||
|
|
||||||
const handleAnalyze = (payload: AnalyzePayload) => {
|
const handleAnalyze = (payload: AnalyzePayload) => {
|
||||||
navigate('/report/loading', {
|
navigate('/report/loading', {
|
||||||
|
|
@ -38,9 +41,35 @@ export default function TestPrefillPage() {
|
||||||
<h1 className="text-3xl font-bold text-primary-900">
|
<h1 className="text-3xl font-bold text-primary-900">
|
||||||
prefill 테스트
|
prefill 테스트
|
||||||
</h1>
|
</h1>
|
||||||
|
<p className="mt-2 text-sm text-slate-600">
|
||||||
|
병원을 선택하면 아래 입력 폼이 해당 fixture URL 로 자동 채워집니다.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-6 flex flex-wrap gap-2" role="tablist" aria-label="병원 fixture 선택">
|
||||||
|
{CLINICS.map((c, i) => {
|
||||||
|
const active = i === selectedIdx
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={c.label}
|
||||||
|
type="button"
|
||||||
|
role="tab"
|
||||||
|
aria-selected={active}
|
||||||
|
onClick={() => setSelectedIdx(i)}
|
||||||
|
className={
|
||||||
|
active
|
||||||
|
? 'px-3 py-1.5 rounded-full text-xs font-medium bg-gradient-to-r from-[#4F1DA1] to-[#021341] text-white shadow-sm'
|
||||||
|
: 'px-3 py-1.5 rounded-full text-xs font-medium bg-white/80 backdrop-blur-sm text-slate-700 border border-slate-200 hover:border-slate-300 hover:bg-white transition'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{c.label}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MultiChannelInput
|
<MultiChannelInput
|
||||||
|
key={clinic.label}
|
||||||
variant="hero"
|
variant="hero"
|
||||||
initialUrls={clinic.urls}
|
initialUrls={clinic.urls}
|
||||||
onAnalyze={handleAnalyze}
|
onAnalyze={handleAnalyze}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import { motion } from 'motion/react';
|
import { motion } from 'motion/react';
|
||||||
import { Instagram, AlertCircle, FileText, Users, Eye, ExternalLink } from 'lucide-react';
|
import { Instagram, ExternalLink } from 'lucide-react';
|
||||||
import { SectionWrapper } from './ui/SectionWrapper';
|
import { SectionWrapper } from './ui/SectionWrapper';
|
||||||
import { EmptyState } from './ui/EmptyState';
|
import { EmptyState } from './ui/EmptyState';
|
||||||
import { MetricCard } from './ui/MetricCard';
|
|
||||||
import { DiagnosisRow } from './ui/DiagnosisRow';
|
import { DiagnosisRow } from './ui/DiagnosisRow';
|
||||||
import type { InstagramAudit as InstagramAuditType, InstagramAccount } from '@/features/report/types/report';
|
import type { InstagramAudit as InstagramAuditType, InstagramAccount } from '@/features/report/types/report';
|
||||||
|
|
||||||
|
|
@ -68,25 +67,12 @@ function AccountCard({ account, index }: { key?: string | number; account: Insta
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Format & reels */}
|
{/* Format */}
|
||||||
<div className="space-y-2 mb-4">
|
<div className="space-y-2 mb-4">
|
||||||
<div className="flex items-center justify-between text-sm">
|
<div className="flex items-center justify-between text-sm">
|
||||||
<span className="text-slate-500">콘텐츠 포맷</span>
|
<span className="text-slate-500">콘텐츠 포맷</span>
|
||||||
<span className="font-medium text-[#0A1128]">{account.contentFormat}</span>
|
<span className="font-medium text-[#0A1128]">{account.contentFormat}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between text-sm">
|
|
||||||
<span className="text-slate-500">릴스 수</span>
|
|
||||||
<span className={`font-medium ${account.reelsCount === 0 ? 'text-[#7C3A4B]' : 'text-[#0A1128]'}`}>
|
|
||||||
{account.reelsCount === 0 ? (
|
|
||||||
<span className="inline-flex items-center gap-1">
|
|
||||||
<AlertCircle size={14} className="text-[#D4889A]" />
|
|
||||||
0 (미운영)
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
account.reelsCount
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Highlights */}
|
{/* Highlights */}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,24 @@ function nonEmpty<T>(arr: T[] | null | undefined): arr is T[] {
|
||||||
return Array.isArray(arr) && arr.length > 0;
|
return Array.isArray(arr) && arr.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasClinicSnapshotData(s: MarketingReport['clinicSnapshot'] | null | undefined): boolean {
|
||||||
|
if (!s) return false;
|
||||||
|
return !!(
|
||||||
|
s.name ||
|
||||||
|
s.nameEn ||
|
||||||
|
s.location ||
|
||||||
|
s.phone ||
|
||||||
|
s.domain ||
|
||||||
|
s.established ||
|
||||||
|
(s.staffCount ?? 0) > 0 ||
|
||||||
|
(s.overallRating ?? 0) > 0 ||
|
||||||
|
(s.totalReviews ?? 0) > 0 ||
|
||||||
|
s.leadDoctor?.name ||
|
||||||
|
nonEmpty(s.certifications) ||
|
||||||
|
s.registryData
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function ReportBody({ data }: ReportBodyProps) {
|
export default function ReportBody({ data }: ReportBodyProps) {
|
||||||
// 각 audit에서 핸들 끌어와 헤더의 바로가기 버튼에 전달
|
// 각 audit에서 핸들 끌어와 헤더의 바로가기 버튼에 전달
|
||||||
const socialHandles = {
|
const socialHandles = {
|
||||||
|
|
@ -56,7 +74,7 @@ export default function ReportBody({ data }: ReportBodyProps) {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SectionErrorBoundary>
|
<SectionErrorBoundary>
|
||||||
{hasValue(data.clinicSnapshot) && data.clinicSnapshot.name ? (
|
{hasClinicSnapshotData(data.clinicSnapshot) ? (
|
||||||
<ClinicSnapshot data={data.clinicSnapshot} targetUrl={data.targetUrl} socialHandles={socialHandles} />
|
<ClinicSnapshot data={data.clinicSnapshot} targetUrl={data.targetUrl} socialHandles={socialHandles} />
|
||||||
) : (
|
) : (
|
||||||
<EmptySection id="clinic-snapshot" title="Clinic Overview" subtitle="병원 기본 정보" />
|
<EmptySection id="clinic-snapshot" title="Clinic Overview" subtitle="병원 기본 정보" />
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export default function YouTubeAudit({ data }: YouTubeAuditProps) {
|
||||||
label="구독자"
|
label="구독자"
|
||||||
value={formatNumber(data.subscribers)}
|
value={formatNumber(data.subscribers)}
|
||||||
icon={<Users size={20} />}
|
icon={<Users size={20} />}
|
||||||
subtext={data.subscriberRank}
|
subtext={data.subscriberRank ?? undefined}
|
||||||
/>
|
/>
|
||||||
<MetricCard
|
<MetricCard
|
||||||
label="총 영상 수"
|
label="총 영상 수"
|
||||||
|
|
@ -45,13 +45,22 @@ export default function YouTubeAudit({ data }: YouTubeAuditProps) {
|
||||||
value={formatNumber(data.totalViews)}
|
value={formatNumber(data.totalViews)}
|
||||||
icon={<Eye size={20} />}
|
icon={<Eye size={20} />}
|
||||||
/>
|
/>
|
||||||
|
{data.weeklyViewGrowth ? (
|
||||||
<MetricCard
|
<MetricCard
|
||||||
label="주간 성장"
|
label="주간 성장"
|
||||||
value={`+${formatNumber(data.weeklyViewGrowth.absolute)}`}
|
value={`${data.weeklyViewGrowth.absolute >= 0 ? '+' : ''}${formatNumber(data.weeklyViewGrowth.absolute)}`}
|
||||||
icon={<TrendingUp size={20} />}
|
icon={<TrendingUp size={20} />}
|
||||||
subtext={`${data.weeklyViewGrowth.percentage > 0 ? '+' : ''}${data.weeklyViewGrowth.percentage}%`}
|
subtext={`${data.weeklyViewGrowth.percentage > 0 ? '+' : ''}${data.weeklyViewGrowth.percentage}%`}
|
||||||
trend={data.weeklyViewGrowth.percentage > 0 ? 'up' : data.weeklyViewGrowth.percentage < 0 ? 'down' : 'neutral'}
|
trend={data.weeklyViewGrowth.percentage > 0 ? 'up' : data.weeklyViewGrowth.percentage < 0 ? 'down' : 'neutral'}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<MetricCard
|
||||||
|
label="주간 성장"
|
||||||
|
value="-"
|
||||||
|
icon={<TrendingUp size={20} />}
|
||||||
|
subtext="데이터 없음"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Channel info card */}
|
{/* Channel info card */}
|
||||||
|
|
@ -86,8 +95,8 @@ export default function YouTubeAudit({ data }: YouTubeAuditProps) {
|
||||||
<p className="text-sm text-slate-600 mb-4">{data.channelDescription}</p>
|
<p className="text-sm text-slate-600 mb-4">{data.channelDescription}</p>
|
||||||
<div className="flex flex-wrap gap-3 text-sm text-slate-500">
|
<div className="flex flex-wrap gap-3 text-sm text-slate-500">
|
||||||
<span>개설일: {data.channelCreatedDate}</span>
|
<span>개설일: {data.channelCreatedDate}</span>
|
||||||
<span>평균 영상 길이: {data.avgVideoLength}</span>
|
<span>평균 영상 길이: {data.avgVideoLength ?? '-'}</span>
|
||||||
<span>업로드 빈도: {data.uploadFrequency}</span>
|
<span>업로드 빈도: {data.uploadFrequency ?? '-'}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Linked URLs */}
|
{/* Linked URLs */}
|
||||||
|
|
|
||||||
|
|
@ -87,12 +87,12 @@ export interface YouTubeAudit {
|
||||||
subscribers: number;
|
subscribers: number;
|
||||||
totalVideos: number;
|
totalVideos: number;
|
||||||
totalViews: number;
|
totalViews: number;
|
||||||
weeklyViewGrowth: { absolute: number; percentage: number };
|
weeklyViewGrowth: { absolute: number; percentage: number } | null;
|
||||||
estimatedMonthlyRevenue: { min: number; max: number };
|
estimatedMonthlyRevenue: { min: number; max: number } | null;
|
||||||
avgVideoLength: string;
|
avgVideoLength: string | null;
|
||||||
uploadFrequency: string;
|
uploadFrequency: string | null;
|
||||||
channelCreatedDate: string;
|
channelCreatedDate: string;
|
||||||
subscriberRank: string;
|
subscriberRank: string | null;
|
||||||
channelDescription: string;
|
channelDescription: string;
|
||||||
linkedUrls: { label: string; url: string }[];
|
linkedUrls: { label: string; url: string }[];
|
||||||
playlists: string[];
|
playlists: string[];
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,13 @@
|
||||||
*/
|
*/
|
||||||
import type { ClinicResponseHospitalNameEn } from './clinicResponseHospitalNameEn';
|
import type { ClinicResponseHospitalNameEn } from './clinicResponseHospitalNameEn';
|
||||||
import type { ClinicResponseRoadAddress } from './clinicResponseRoadAddress';
|
import type { ClinicResponseRoadAddress } from './clinicResponseRoadAddress';
|
||||||
import type { ClinicResponseUrl } from './clinicResponseUrl';
|
|
||||||
import type { ClinicResponseRawData } from './clinicResponseRawData';
|
|
||||||
|
|
||||||
export interface ClinicResponse {
|
export interface ClinicResponse {
|
||||||
hospital_id: string;
|
hospital_id: string;
|
||||||
hospital_name: string;
|
hospital_name: string;
|
||||||
hospital_name_en: ClinicResponseHospitalNameEn;
|
hospital_name_en: ClinicResponseHospitalNameEn;
|
||||||
road_address: ClinicResponseRoadAddress;
|
road_address: ClinicResponseRoadAddress;
|
||||||
url: ClinicResponseUrl;
|
|
||||||
status: string;
|
status: string;
|
||||||
raw_data: ClinicResponseRawData;
|
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
/**
|
|
||||||
* Generated by orval v7.21.0 🍺
|
|
||||||
* Do not edit manually.
|
|
||||||
* FastAPI
|
|
||||||
* OpenAPI spec version: 0.1.0
|
|
||||||
*/
|
|
||||||
import type { ClinicResponseRawDataAnyOf } from './clinicResponseRawDataAnyOf';
|
|
||||||
|
|
||||||
export type ClinicResponseRawData = ClinicResponseRawDataAnyOf | null;
|
|
||||||
|
|
@ -4,30 +4,31 @@
|
||||||
* FastAPI
|
* FastAPI
|
||||||
* OpenAPI spec version: 0.1.0
|
* OpenAPI spec version: 0.1.0
|
||||||
*/
|
*/
|
||||||
import type { LeadDoctor } from './leadDoctor';
|
import type { ClinicSnapshotName } from './clinicSnapshotName';
|
||||||
import type { PriceRange } from './priceRange';
|
import type { ClinicSnapshotNameEn } from './clinicSnapshotNameEn';
|
||||||
|
import type { ClinicSnapshotStaffCount } from './clinicSnapshotStaffCount';
|
||||||
|
import type { ClinicSnapshotLeadDoctor } from './clinicSnapshotLeadDoctor';
|
||||||
|
import type { ClinicSnapshotOverallRating } from './clinicSnapshotOverallRating';
|
||||||
|
import type { ClinicSnapshotTotalReviews } from './clinicSnapshotTotalReviews';
|
||||||
|
import type { ClinicSnapshotLocation } from './clinicSnapshotLocation';
|
||||||
|
import type { ClinicSnapshotPhone } from './clinicSnapshotPhone';
|
||||||
|
import type { ClinicSnapshotDomain } from './clinicSnapshotDomain';
|
||||||
import type { ClinicSnapshotLogoImages } from './clinicSnapshotLogoImages';
|
import type { ClinicSnapshotLogoImages } from './clinicSnapshotLogoImages';
|
||||||
import type { ClinicSnapshotBrandColors } from './clinicSnapshotBrandColors';
|
import type { ClinicSnapshotBrandColors } from './clinicSnapshotBrandColors';
|
||||||
import type { ClinicSnapshotSource } from './clinicSnapshotSource';
|
import type { ClinicSnapshotSource } from './clinicSnapshotSource';
|
||||||
import type { ClinicSnapshotRegistryData } from './clinicSnapshotRegistryData';
|
import type { ClinicSnapshotRegistryData } from './clinicSnapshotRegistryData';
|
||||||
|
|
||||||
export interface ClinicSnapshot {
|
export interface ClinicSnapshot {
|
||||||
name: string;
|
name?: ClinicSnapshotName;
|
||||||
nameEn: string;
|
nameEn?: ClinicSnapshotNameEn;
|
||||||
established: string;
|
staffCount?: ClinicSnapshotStaffCount;
|
||||||
yearsInBusiness: number;
|
leadDoctor?: ClinicSnapshotLeadDoctor;
|
||||||
staffCount: number;
|
overallRating?: ClinicSnapshotOverallRating;
|
||||||
leadDoctor: LeadDoctor;
|
totalReviews?: ClinicSnapshotTotalReviews;
|
||||||
overallRating: number;
|
certifications?: string[];
|
||||||
totalReviews: number;
|
location?: ClinicSnapshotLocation;
|
||||||
priceRange: PriceRange;
|
phone?: ClinicSnapshotPhone;
|
||||||
certifications: string[];
|
domain?: ClinicSnapshotDomain;
|
||||||
mediaAppearances: string[];
|
|
||||||
medicalTourism: string[];
|
|
||||||
location: string;
|
|
||||||
nearestStation: string;
|
|
||||||
phone: string;
|
|
||||||
domain: string;
|
|
||||||
logoImages?: ClinicSnapshotLogoImages;
|
logoImages?: ClinicSnapshotLogoImages;
|
||||||
brandColors?: ClinicSnapshotBrandColors;
|
brandColors?: ClinicSnapshotBrandColors;
|
||||||
source?: ClinicSnapshotSource;
|
source?: ClinicSnapshotSource;
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,4 @@
|
||||||
* OpenAPI spec version: 0.1.0
|
* OpenAPI spec version: 0.1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export type ClinicResponseRawDataAnyOf = { [key: string]: unknown };
|
export type ClinicSnapshotDomain = string | null;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
import type { LeadDoctor } from './leadDoctor';
|
||||||
|
|
||||||
|
export type ClinicSnapshotLeadDoctor = LeadDoctor | null;
|
||||||
|
|
@ -5,8 +5,4 @@
|
||||||
* OpenAPI spec version: 0.1.0
|
* OpenAPI spec version: 0.1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface PriceRange {
|
export type ClinicSnapshotLocation = string | null;
|
||||||
min: string;
|
|
||||||
max: string;
|
|
||||||
currency: string;
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type ClinicSnapshotName = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type ClinicSnapshotNameEn = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type ClinicSnapshotOverallRating = number | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type ClinicSnapshotPhone = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type ClinicSnapshotStaffCount = number | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type ClinicSnapshotTotalReviews = number | null;
|
||||||
|
|
@ -7,10 +7,11 @@
|
||||||
import type { FacebookPage } from './facebookPage';
|
import type { FacebookPage } from './facebookPage';
|
||||||
import type { DiagnosisItem } from './diagnosisItem';
|
import type { DiagnosisItem } from './diagnosisItem';
|
||||||
import type { BrandInconsistency } from './brandInconsistency';
|
import type { BrandInconsistency } from './brandInconsistency';
|
||||||
|
import type { FacebookAuditConsolidationRecommendation } from './facebookAuditConsolidationRecommendation';
|
||||||
|
|
||||||
export interface FacebookAudit {
|
export interface FacebookAudit {
|
||||||
pages: FacebookPage[];
|
pages?: FacebookPage[];
|
||||||
diagnosis: DiagnosisItem[];
|
diagnosis?: DiagnosisItem[];
|
||||||
brandInconsistencies: BrandInconsistency[];
|
brandInconsistencies?: BrandInconsistency[];
|
||||||
consolidationRecommendation: string;
|
consolidationRecommendation?: FacebookAuditConsolidationRecommendation;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookAuditConsolidationRecommendation = string | null;
|
||||||
|
|
@ -4,27 +4,41 @@
|
||||||
* FastAPI
|
* FastAPI
|
||||||
* OpenAPI spec version: 0.1.0
|
* OpenAPI spec version: 0.1.0
|
||||||
*/
|
*/
|
||||||
import type { Language } from './language';
|
import type { FacebookPageUrl } from './facebookPageUrl';
|
||||||
|
import type { FacebookPagePageName } from './facebookPagePageName';
|
||||||
|
import type { FacebookPageLanguage } from './facebookPageLanguage';
|
||||||
|
import type { FacebookPageLabel } from './facebookPageLabel';
|
||||||
|
import type { FacebookPageFollowers } from './facebookPageFollowers';
|
||||||
|
import type { FacebookPageFollowing } from './facebookPageFollowing';
|
||||||
|
import type { FacebookPageCategory } from './facebookPageCategory';
|
||||||
|
import type { FacebookPageBio } from './facebookPageBio';
|
||||||
|
import type { FacebookPageLogo } from './facebookPageLogo';
|
||||||
|
import type { FacebookPageLogoDescription } from './facebookPageLogoDescription';
|
||||||
|
import type { FacebookPageLink } from './facebookPageLink';
|
||||||
|
import type { FacebookPageLinkedDomain } from './facebookPageLinkedDomain';
|
||||||
|
import type { FacebookPageReviews } from './facebookPageReviews';
|
||||||
|
import type { FacebookPageRecentPostAge } from './facebookPageRecentPostAge';
|
||||||
|
import type { FacebookPageHasWhatsapp } from './facebookPageHasWhatsapp';
|
||||||
import type { FacebookPagePostFrequency } from './facebookPagePostFrequency';
|
import type { FacebookPagePostFrequency } from './facebookPagePostFrequency';
|
||||||
import type { FacebookPageTopContentType } from './facebookPageTopContentType';
|
import type { FacebookPageTopContentType } from './facebookPageTopContentType';
|
||||||
import type { FacebookPageEngagement } from './facebookPageEngagement';
|
import type { FacebookPageEngagement } from './facebookPageEngagement';
|
||||||
|
|
||||||
export interface FacebookPage {
|
export interface FacebookPage {
|
||||||
url: string;
|
url?: FacebookPageUrl;
|
||||||
pageName: string;
|
pageName?: FacebookPagePageName;
|
||||||
language: Language;
|
language?: FacebookPageLanguage;
|
||||||
label: string;
|
label?: FacebookPageLabel;
|
||||||
followers: number;
|
followers?: FacebookPageFollowers;
|
||||||
following: number;
|
following?: FacebookPageFollowing;
|
||||||
category: string;
|
category?: FacebookPageCategory;
|
||||||
bio: string;
|
bio?: FacebookPageBio;
|
||||||
logo: string;
|
logo?: FacebookPageLogo;
|
||||||
logoDescription: string;
|
logoDescription?: FacebookPageLogoDescription;
|
||||||
link: string;
|
link?: FacebookPageLink;
|
||||||
linkedDomain: string;
|
linkedDomain?: FacebookPageLinkedDomain;
|
||||||
reviews: number;
|
reviews?: FacebookPageReviews;
|
||||||
recentPostAge: string;
|
recentPostAge?: FacebookPageRecentPostAge;
|
||||||
hasWhatsapp: boolean;
|
hasWhatsapp?: FacebookPageHasWhatsapp;
|
||||||
postFrequency?: FacebookPagePostFrequency;
|
postFrequency?: FacebookPagePostFrequency;
|
||||||
topContentType?: FacebookPageTopContentType;
|
topContentType?: FacebookPageTopContentType;
|
||||||
engagement?: FacebookPageEngagement;
|
engagement?: FacebookPageEngagement;
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,4 @@
|
||||||
* OpenAPI spec version: 0.1.0
|
* OpenAPI spec version: 0.1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export type ClinicResponseUrl = string | null;
|
export type FacebookPageBio = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageCategory = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageFollowers = number | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageFollowing = number | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageHasWhatsapp = boolean | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageLabel = string | null;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
import type { Language } from './language';
|
||||||
|
|
||||||
|
export type FacebookPageLanguage = Language | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageLink = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageLinkedDomain = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageLogo = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageLogoDescription = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPagePageName = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageRecentPostAge = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageReviews = number | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type FacebookPageUrl = string | null;
|
||||||
|
|
@ -61,15 +61,21 @@ export * from './clinicHistoryResponse';
|
||||||
export * from './clinicHistoryResponseMetricsTimeseries';
|
export * from './clinicHistoryResponseMetricsTimeseries';
|
||||||
export * from './clinicResponse';
|
export * from './clinicResponse';
|
||||||
export * from './clinicResponseHospitalNameEn';
|
export * from './clinicResponseHospitalNameEn';
|
||||||
export * from './clinicResponseRawData';
|
|
||||||
export * from './clinicResponseRawDataAnyOf';
|
|
||||||
export * from './clinicResponseRoadAddress';
|
export * from './clinicResponseRoadAddress';
|
||||||
export * from './clinicResponseUrl';
|
|
||||||
export * from './clinicSnapshot';
|
export * from './clinicSnapshot';
|
||||||
export * from './clinicSnapshotBrandColors';
|
export * from './clinicSnapshotBrandColors';
|
||||||
|
export * from './clinicSnapshotDomain';
|
||||||
|
export * from './clinicSnapshotLeadDoctor';
|
||||||
|
export * from './clinicSnapshotLocation';
|
||||||
export * from './clinicSnapshotLogoImages';
|
export * from './clinicSnapshotLogoImages';
|
||||||
|
export * from './clinicSnapshotName';
|
||||||
|
export * from './clinicSnapshotNameEn';
|
||||||
|
export * from './clinicSnapshotOverallRating';
|
||||||
|
export * from './clinicSnapshotPhone';
|
||||||
export * from './clinicSnapshotRegistryData';
|
export * from './clinicSnapshotRegistryData';
|
||||||
export * from './clinicSnapshotSource';
|
export * from './clinicSnapshotSource';
|
||||||
|
export * from './clinicSnapshotStaffCount';
|
||||||
|
export * from './clinicSnapshotTotalReviews';
|
||||||
export * from './colorSwatch';
|
export * from './colorSwatch';
|
||||||
export * from './contentCountSummary';
|
export * from './contentCountSummary';
|
||||||
export * from './contentCountSummaryType';
|
export * from './contentCountSummaryType';
|
||||||
|
|
@ -81,10 +87,26 @@ export * from './diagnosisItem';
|
||||||
export * from './diagnosisItemEvidenceIds';
|
export * from './diagnosisItemEvidenceIds';
|
||||||
export * from './estimatedRevenue';
|
export * from './estimatedRevenue';
|
||||||
export * from './facebookAudit';
|
export * from './facebookAudit';
|
||||||
|
export * from './facebookAuditConsolidationRecommendation';
|
||||||
export * from './facebookPage';
|
export * from './facebookPage';
|
||||||
|
export * from './facebookPageBio';
|
||||||
|
export * from './facebookPageCategory';
|
||||||
export * from './facebookPageEngagement';
|
export * from './facebookPageEngagement';
|
||||||
|
export * from './facebookPageFollowers';
|
||||||
|
export * from './facebookPageFollowing';
|
||||||
|
export * from './facebookPageHasWhatsapp';
|
||||||
|
export * from './facebookPageLabel';
|
||||||
|
export * from './facebookPageLanguage';
|
||||||
|
export * from './facebookPageLink';
|
||||||
|
export * from './facebookPageLinkedDomain';
|
||||||
|
export * from './facebookPageLogo';
|
||||||
|
export * from './facebookPageLogoDescription';
|
||||||
|
export * from './facebookPagePageName';
|
||||||
export * from './facebookPagePostFrequency';
|
export * from './facebookPagePostFrequency';
|
||||||
|
export * from './facebookPageRecentPostAge';
|
||||||
|
export * from './facebookPageReviews';
|
||||||
export * from './facebookPageTopContentType';
|
export * from './facebookPageTopContentType';
|
||||||
|
export * from './facebookPageUrl';
|
||||||
export * from './fileListItem';
|
export * from './fileListItem';
|
||||||
export * from './fileListItemSizeBytes';
|
export * from './fileListItemSizeBytes';
|
||||||
export * from './fileType';
|
export * from './fileType';
|
||||||
|
|
@ -93,6 +115,18 @@ export * from './fileUploadResponseSizeBytes';
|
||||||
export * from './fontSpec';
|
export * from './fontSpec';
|
||||||
export * from './hTTPValidationError';
|
export * from './hTTPValidationError';
|
||||||
export * from './instagramAccount';
|
export * from './instagramAccount';
|
||||||
|
export * from './instagramAccountBio';
|
||||||
|
export * from './instagramAccountCategory';
|
||||||
|
export * from './instagramAccountContentFormat';
|
||||||
|
export * from './instagramAccountFollowers';
|
||||||
|
export * from './instagramAccountFollowing';
|
||||||
|
export * from './instagramAccountHandle';
|
||||||
|
export * from './instagramAccountLabel';
|
||||||
|
export * from './instagramAccountLanguage';
|
||||||
|
export * from './instagramAccountPosts';
|
||||||
|
export * from './instagramAccountProfileLink';
|
||||||
|
export * from './instagramAccountProfilePhoto';
|
||||||
|
export * from './instagramAccountReelsCount';
|
||||||
export * from './instagramAudit';
|
export * from './instagramAudit';
|
||||||
export * from './kPIMetric';
|
export * from './kPIMetric';
|
||||||
export * from './language';
|
export * from './language';
|
||||||
|
|
@ -115,7 +149,6 @@ export * from './planApiResponseClinicName';
|
||||||
export * from './planApiResponseClinicNameEn';
|
export * from './planApiResponseClinicNameEn';
|
||||||
export * from './planApiResponseRepurposingProposals';
|
export * from './planApiResponseRepurposingProposals';
|
||||||
export * from './platformStrategy';
|
export * from './platformStrategy';
|
||||||
export * from './priceRange';
|
|
||||||
export * from './registryData';
|
export * from './registryData';
|
||||||
export * from './registryDataBranches';
|
export * from './registryDataBranches';
|
||||||
export * from './registryDataBrandGroup';
|
export * from './registryDataBrandGroup';
|
||||||
|
|
@ -159,5 +192,16 @@ export * from './websiteAuditSnsLinksDetail';
|
||||||
export * from './weeklyViewGrowth';
|
export * from './weeklyViewGrowth';
|
||||||
export * from './workflowStep';
|
export * from './workflowStep';
|
||||||
export * from './youTubeAudit';
|
export * from './youTubeAudit';
|
||||||
|
export * from './youTubeAuditAvgVideoLength';
|
||||||
|
export * from './youTubeAuditChannelCreatedDate';
|
||||||
|
export * from './youTubeAuditChannelDescription';
|
||||||
|
export * from './youTubeAuditChannelName';
|
||||||
|
export * from './youTubeAuditEstimatedMonthlyRevenue';
|
||||||
|
export * from './youTubeAuditHandle';
|
||||||
|
export * from './youTubeAuditSubscribers';
|
||||||
|
export * from './youTubeAuditTotalVideos';
|
||||||
|
export * from './youTubeAuditTotalViews';
|
||||||
|
export * from './youTubeAuditUploadFrequency';
|
||||||
|
export * from './youTubeAuditWeeklyViewGrowth';
|
||||||
export * from './youTubeRepurposeItem';
|
export * from './youTubeRepurposeItem';
|
||||||
export * from './youTubeRepurposeItemType';
|
export * from './youTubeRepurposeItemType';
|
||||||
|
|
@ -4,20 +4,31 @@
|
||||||
* FastAPI
|
* FastAPI
|
||||||
* OpenAPI spec version: 0.1.0
|
* OpenAPI spec version: 0.1.0
|
||||||
*/
|
*/
|
||||||
import type { Language } from './language';
|
import type { InstagramAccountHandle } from './instagramAccountHandle';
|
||||||
|
import type { InstagramAccountLanguage } from './instagramAccountLanguage';
|
||||||
|
import type { InstagramAccountLabel } from './instagramAccountLabel';
|
||||||
|
import type { InstagramAccountPosts } from './instagramAccountPosts';
|
||||||
|
import type { InstagramAccountFollowers } from './instagramAccountFollowers';
|
||||||
|
import type { InstagramAccountFollowing } from './instagramAccountFollowing';
|
||||||
|
import type { InstagramAccountCategory } from './instagramAccountCategory';
|
||||||
|
import type { InstagramAccountProfileLink } from './instagramAccountProfileLink';
|
||||||
|
import type { InstagramAccountReelsCount } from './instagramAccountReelsCount';
|
||||||
|
import type { InstagramAccountContentFormat } from './instagramAccountContentFormat';
|
||||||
|
import type { InstagramAccountProfilePhoto } from './instagramAccountProfilePhoto';
|
||||||
|
import type { InstagramAccountBio } from './instagramAccountBio';
|
||||||
|
|
||||||
export interface InstagramAccount {
|
export interface InstagramAccount {
|
||||||
handle: string;
|
handle?: InstagramAccountHandle;
|
||||||
language: Language;
|
language?: InstagramAccountLanguage;
|
||||||
label: string;
|
label?: InstagramAccountLabel;
|
||||||
posts: number;
|
posts?: InstagramAccountPosts;
|
||||||
followers: number;
|
followers?: InstagramAccountFollowers;
|
||||||
following: number;
|
following?: InstagramAccountFollowing;
|
||||||
category: string;
|
category?: InstagramAccountCategory;
|
||||||
profileLink: string;
|
profileLink?: InstagramAccountProfileLink;
|
||||||
highlights: string[];
|
highlights?: string[];
|
||||||
reelsCount: number;
|
reelsCount?: InstagramAccountReelsCount;
|
||||||
contentFormat: string;
|
contentFormat?: InstagramAccountContentFormat;
|
||||||
profilePhoto: string;
|
profilePhoto?: InstagramAccountProfilePhoto;
|
||||||
bio: string;
|
bio?: InstagramAccountBio;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type InstagramAccountBio = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type InstagramAccountCategory = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type InstagramAccountContentFormat = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type InstagramAccountFollowers = number | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type InstagramAccountFollowing = number | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type InstagramAccountHandle = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type InstagramAccountLabel = string | null;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
import type { Language } from './language';
|
||||||
|
|
||||||
|
export type InstagramAccountLanguage = Language | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type InstagramAccountPosts = number | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type InstagramAccountProfileLink = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type InstagramAccountProfilePhoto = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type InstagramAccountReelsCount = number | null;
|
||||||
|
|
@ -8,6 +8,6 @@ import type { InstagramAccount } from './instagramAccount';
|
||||||
import type { DiagnosisItem } from './diagnosisItem';
|
import type { DiagnosisItem } from './diagnosisItem';
|
||||||
|
|
||||||
export interface InstagramAudit {
|
export interface InstagramAudit {
|
||||||
accounts: InstagramAccount[];
|
accounts?: InstagramAccount[];
|
||||||
diagnosis: DiagnosisItem[];
|
diagnosis?: DiagnosisItem[];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,5 @@ export type Language = typeof Language[keyof typeof Language];
|
||||||
export const Language = {
|
export const Language = {
|
||||||
KR: 'KR',
|
KR: 'KR',
|
||||||
EN: 'EN',
|
EN: 'EN',
|
||||||
|
WW: 'WW',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
||||||
|
|
@ -4,27 +4,35 @@
|
||||||
* FastAPI
|
* FastAPI
|
||||||
* OpenAPI spec version: 0.1.0
|
* OpenAPI spec version: 0.1.0
|
||||||
*/
|
*/
|
||||||
import type { WeeklyViewGrowth } from './weeklyViewGrowth';
|
import type { YouTubeAuditChannelName } from './youTubeAuditChannelName';
|
||||||
import type { EstimatedRevenue } from './estimatedRevenue';
|
import type { YouTubeAuditHandle } from './youTubeAuditHandle';
|
||||||
|
import type { YouTubeAuditSubscribers } from './youTubeAuditSubscribers';
|
||||||
|
import type { YouTubeAuditTotalVideos } from './youTubeAuditTotalVideos';
|
||||||
|
import type { YouTubeAuditTotalViews } from './youTubeAuditTotalViews';
|
||||||
|
import type { YouTubeAuditWeeklyViewGrowth } from './youTubeAuditWeeklyViewGrowth';
|
||||||
|
import type { YouTubeAuditEstimatedMonthlyRevenue } from './youTubeAuditEstimatedMonthlyRevenue';
|
||||||
|
import type { YouTubeAuditAvgVideoLength } from './youTubeAuditAvgVideoLength';
|
||||||
|
import type { YouTubeAuditUploadFrequency } from './youTubeAuditUploadFrequency';
|
||||||
|
import type { YouTubeAuditChannelCreatedDate } from './youTubeAuditChannelCreatedDate';
|
||||||
|
import type { YouTubeAuditChannelDescription } from './youTubeAuditChannelDescription';
|
||||||
import type { LinkedUrl } from './linkedUrl';
|
import type { LinkedUrl } from './linkedUrl';
|
||||||
import type { TopVideo } from './topVideo';
|
import type { TopVideo } from './topVideo';
|
||||||
import type { DiagnosisItem } from './diagnosisItem';
|
import type { DiagnosisItem } from './diagnosisItem';
|
||||||
|
|
||||||
export interface YouTubeAudit {
|
export interface YouTubeAudit {
|
||||||
channelName: string;
|
channelName?: YouTubeAuditChannelName;
|
||||||
handle: string;
|
handle?: YouTubeAuditHandle;
|
||||||
subscribers: number;
|
subscribers?: YouTubeAuditSubscribers;
|
||||||
totalVideos: number;
|
totalVideos?: YouTubeAuditTotalVideos;
|
||||||
totalViews: number;
|
totalViews?: YouTubeAuditTotalViews;
|
||||||
weeklyViewGrowth: WeeklyViewGrowth;
|
weeklyViewGrowth?: YouTubeAuditWeeklyViewGrowth;
|
||||||
estimatedMonthlyRevenue: EstimatedRevenue;
|
estimatedMonthlyRevenue?: YouTubeAuditEstimatedMonthlyRevenue;
|
||||||
avgVideoLength: string;
|
avgVideoLength?: YouTubeAuditAvgVideoLength;
|
||||||
uploadFrequency: string;
|
uploadFrequency?: YouTubeAuditUploadFrequency;
|
||||||
channelCreatedDate: string;
|
channelCreatedDate?: YouTubeAuditChannelCreatedDate;
|
||||||
subscriberRank: string;
|
channelDescription?: YouTubeAuditChannelDescription;
|
||||||
channelDescription: string;
|
linkedUrls?: LinkedUrl[];
|
||||||
linkedUrls: LinkedUrl[];
|
playlists?: string[];
|
||||||
playlists: string[];
|
topVideos?: TopVideo[];
|
||||||
topVideos: TopVideo[];
|
diagnosis?: DiagnosisItem[];
|
||||||
diagnosis: DiagnosisItem[];
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type YouTubeAuditAvgVideoLength = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type YouTubeAuditChannelCreatedDate = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type YouTubeAuditChannelDescription = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type YouTubeAuditChannelName = string | null;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
import type { EstimatedRevenue } from './estimatedRevenue';
|
||||||
|
|
||||||
|
export type YouTubeAuditEstimatedMonthlyRevenue = EstimatedRevenue | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type YouTubeAuditHandle = string | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type YouTubeAuditSubscribers = number | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type YouTubeAuditTotalVideos = number | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type YouTubeAuditTotalViews = number | null;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type YouTubeAuditUploadFrequency = string | null;
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/**
|
||||||
|
* Generated by orval v7.21.0 🍺
|
||||||
|
* Do not edit manually.
|
||||||
|
* FastAPI
|
||||||
|
* OpenAPI spec version: 0.1.0
|
||||||
|
*/
|
||||||
|
import type { WeeklyViewGrowth } from './weeklyViewGrowth';
|
||||||
|
|
||||||
|
export type YouTubeAuditWeeklyViewGrowth = WeeklyViewGrowth | null;
|
||||||
Loading…
Reference in New Issue