339 lines
15 KiB
TypeScript
339 lines
15 KiB
TypeScript
import fs from 'fs'
|
|
import path from 'path'
|
|
import { Font, Page, Text, View, StyleSheet } from '@react-pdf/renderer'
|
|
import { radioEtcData, selectBoxOptions, supplementaryFacilities, roofMaterial } from '@/types/Survey'
|
|
import { SurveyBasicInfo } from '@/types/Survey'
|
|
|
|
Font.register({
|
|
family: 'NotoSansJP',
|
|
src: `data:font/ttf;base64,${fs.readFileSync(path.resolve(process.cwd(), 'src/components/pdf/NotoSansJP-Regular.ttf')).toString('base64')}`,
|
|
})
|
|
|
|
const styles = StyleSheet.create({
|
|
page: {
|
|
padding: 15,
|
|
fontFamily: 'NotoSansJP',
|
|
fontSize: 8,
|
|
backgroundColor: '#fff',
|
|
},
|
|
header: {
|
|
padding: '15px 15px 15px',
|
|
borderBottom: '2px solid #2E3A59',
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
alignItems: 'center',
|
|
},
|
|
title: {
|
|
fontSize: 14,
|
|
color: '#101010',
|
|
fontWeight: 'bold',
|
|
fontFamily: 'NotoSansJP',
|
|
},
|
|
headerRight: {
|
|
flexDirection: 'row',
|
|
alignItems: 'flex-start',
|
|
},
|
|
headerLeft: {
|
|
marginRight: 15,
|
|
alignItems: 'flex-end',
|
|
},
|
|
headerLabel: {
|
|
fontSize: 9,
|
|
color: '#101010',
|
|
fontWeight: 'bold',
|
|
fontFamily: 'NotoSansJP',
|
|
textAlign: 'right',
|
|
margin: 0,
|
|
},
|
|
headerValue: {
|
|
fontSize: 9,
|
|
color: '#FF5656',
|
|
fontWeight: 400,
|
|
fontFamily: 'NotoSansJP',
|
|
margin: 0,
|
|
},
|
|
section: {
|
|
padding: '20px 15px 8px',
|
|
},
|
|
sectionTitle: {
|
|
fontSize: 10,
|
|
fontFamily: 'NotoSansJP',
|
|
color: '#101010',
|
|
fontWeight: 'bold',
|
|
marginBottom: 8,
|
|
},
|
|
table: {
|
|
width: '100%',
|
|
},
|
|
tableRow: {
|
|
flexDirection: 'row',
|
|
minHeight: 28,
|
|
},
|
|
tableHeader: {
|
|
padding: 6,
|
|
backgroundColor: '#F5F6FA',
|
|
fontSize: 9,
|
|
fontWeight: 'bold',
|
|
color: '#101010',
|
|
border: '1px solid #2E3A59',
|
|
fontFamily: 'NotoSansJP',
|
|
justifyContent: 'flex-start',
|
|
alignItems: 'center',
|
|
},
|
|
tableCell: {
|
|
padding: 6,
|
|
fontSize: 9,
|
|
fontWeight: 500,
|
|
color: '#FF5656',
|
|
border: '1px solid #2E3A59',
|
|
fontFamily: 'NotoSansJP',
|
|
justifyContent: 'flex-start',
|
|
alignItems: 'center',
|
|
},
|
|
tableHeaderSmall: {
|
|
width: 50,
|
|
},
|
|
tableHeaderMedium: {
|
|
width: 85,
|
|
},
|
|
tableHeaderLarge: {
|
|
width: 110,
|
|
},
|
|
tableCellFlex1: {
|
|
flex: 1,
|
|
},
|
|
tableCellFlex2: {
|
|
flex: 2,
|
|
},
|
|
tableCellFlex07: {
|
|
flex: 0.5745,
|
|
},
|
|
memoBox: {
|
|
padding: 6,
|
|
fontSize: 9,
|
|
fontWeight: 400,
|
|
fontFamily: 'NotoSansJP',
|
|
color: '#FF5656',
|
|
border: '1px solid #2E3A59',
|
|
minHeight: 100,
|
|
width: '100%',
|
|
},
|
|
sectionNoPadding: {
|
|
padding: '10px 15px',
|
|
},
|
|
marginL: {
|
|
marginLeft: -1,
|
|
},
|
|
marginT: {
|
|
marginTop: -1,
|
|
}
|
|
})
|
|
|
|
export default function SurveySalePdf({ survey }: { survey: SurveyBasicInfo }) {
|
|
return (
|
|
<Page size="A4" style={styles.page}>
|
|
{/* Header */}
|
|
<View style={styles.header}>
|
|
<Text style={styles.title}>HWJ 現地調査シート</Text>
|
|
<View style={styles.headerRight}>
|
|
<View style={styles.headerLeft}>
|
|
<Text style={styles.headerLabel}>現地調査販賣店名</Text>
|
|
<Text style={styles.headerValue}>{survey?.store ?? '-'}</Text>
|
|
</View>
|
|
{survey?.constructionPoint && (
|
|
<View style={styles.headerLeft}>
|
|
<Text style={styles.headerLabel}>現地調査施工店名</Text>
|
|
<Text style={styles.headerValue}>{survey?.constructionPoint ?? '-'}</Text>
|
|
</View>
|
|
)}
|
|
<View>
|
|
<Text style={styles.headerLabel}>現地阴買日</Text>
|
|
<Text style={styles.headerValue}>{survey?.investigationDate ?? '-'}</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
|
|
{/* Customer Info */}
|
|
<View style={styles.section}>
|
|
<View style={styles.table}>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderSmall]}>お客様名</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL]}>{survey?.customerName ?? '-'}</Text>
|
|
</View>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderSmall, styles.marginT]}>ご住所</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL, styles.marginT]}>
|
|
{survey?.postCode ? `(${survey?.postCode}) ${survey?.address} ${survey?.addressDetail}` : '-'}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
|
|
{/* Electric Info */}
|
|
<View style={styles.section}>
|
|
<Text style={styles.sectionTitle}>も気開係</Text>
|
|
<View style={styles.table}>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium]}>雨気契约容国</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL]}>{survey?.detailInfo?.contractCapacity ?? '-'}</Text>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginL]}>電気契約会社</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL]}>{survey?.detailInfo?.retailCompany ?? '-'}</Text>
|
|
</View>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginT]}>電気付带設備</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL, styles.marginT]}>
|
|
{survey?.detailInfo?.supplementaryFacilities
|
|
? supplementaryFacilities
|
|
.filter((facility) => survey?.detailInfo?.supplementaryFacilities?.includes(facility.id.toString()))
|
|
.map((facility) => facility.name)
|
|
.join(', ') + (survey?.detailInfo?.supplementaryFacilitiesEtc ? `, ${survey?.detailInfo?.supplementaryFacilitiesEtc}` : '')
|
|
: survey?.detailInfo?.supplementaryFacilitiesEtc
|
|
? `${survey?.detailInfo?.supplementaryFacilitiesEtc}`
|
|
: '-'}
|
|
</Text>
|
|
</View>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginT]}>設置希望システム</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL, styles.marginT]}>
|
|
{survey?.detailInfo?.installationSystem === null && survey?.detailInfo?.installationSystemEtc === null
|
|
? '-'
|
|
: survey?.detailInfo?.installationSystemEtc
|
|
? `${survey?.detailInfo?.installationSystemEtc}`
|
|
: selectBoxOptions.installationSystem.find((system) => system.id.toString() === survey?.detailInfo?.installationSystem)?.name}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
|
|
{/* Roof Info */}
|
|
<View style={styles.section}>
|
|
<Text style={styles.sectionTitle}>屋根眀係</Text>
|
|
<View style={styles.table}>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium]}>築年数</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL]}>
|
|
{survey?.detailInfo?.constructionYear === '1'
|
|
? '新築'
|
|
: survey?.detailInfo?.constructionYearEtc
|
|
? `既築 (${survey?.detailInfo?.constructionYear}年)`
|
|
: '-'}
|
|
</Text>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginL]}>至根材</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex07, styles.marginL, styles.marginL]}>
|
|
{survey?.detailInfo?.roofMaterial === null && survey?.detailInfo?.roofMaterialEtc === null
|
|
? '-'
|
|
: roofMaterial
|
|
.filter((material) => survey?.detailInfo?.roofMaterial?.includes(material.id.toString()))
|
|
.map((material) => material.name)
|
|
.join(', ')}
|
|
{survey?.detailInfo?.roofMaterialEtc ? `, ${survey?.detailInfo?.roofMaterialEtc}` : ''}
|
|
</Text>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginL]}>座根形状</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex07, styles.marginL]}>
|
|
{selectBoxOptions.roofShape.find((shape) => shape.id.toString() === survey?.detailInfo?.roofShape)?.name ??
|
|
(survey?.detailInfo?.roofShapeEtc ? ` ${survey?.detailInfo?.roofShapeEtc}` : '-')}
|
|
</Text>
|
|
</View>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginT]}>座根勾配</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL, styles.marginT, styles.marginL]}>
|
|
{survey?.detailInfo?.roofSlope ? `${survey?.detailInfo?.roofSlope} 寸` : '-'}
|
|
</Text>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginL, styles.marginT]}>住宅樠造</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex2, styles.marginL, styles.marginL, styles.marginT]}>
|
|
{radioEtcData.houseStructure.find((structure) => structure.id.toString() === survey?.detailInfo?.houseStructure)?.label ??
|
|
(survey?.detailInfo?.houseStructureEtc ? ` ${survey?.detailInfo?.houseStructureEtc}` : '-')}
|
|
</Text>
|
|
</View>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginT]}>並木材質</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL, styles.marginT]}>
|
|
{radioEtcData.rafterMaterial.find((material) => material.id.toString() === survey?.detailInfo?.rafterMaterial)?.label ??
|
|
(survey?.detailInfo?.rafterMaterialEtc ? ` ${survey?.detailInfo?.rafterMaterialEtc}` : '-')}
|
|
</Text>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginL, styles.marginT]}>垂木サイズ</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex2, styles.marginL, styles.marginL, styles.marginT]}>
|
|
{selectBoxOptions.rafterSize.find((size) => size.id.toString() === survey?.detailInfo?.rafterSize)?.name ??
|
|
(survey?.detailInfo?.rafterSizeEtc ? ` ${survey?.detailInfo?.rafterSizeEtc}` : '-')}
|
|
</Text>
|
|
</View>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginT]}>垂木ピッチ</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL, styles.marginT]}>
|
|
{selectBoxOptions.rafterPitch.find((pitch) => pitch.id.toString() === survey?.detailInfo?.rafterPitch)?.name ??
|
|
(survey?.detailInfo?.rafterPitchEtc ? ` ${survey?.detailInfo?.rafterPitchEtc}` : '-')}
|
|
</Text>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginL, styles.marginT]}>垂木方向</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex2, styles.marginL, styles.marginT]}>
|
|
{radioEtcData.rafterDirection.find((direction) => direction.id.toString() === survey?.detailInfo?.rafterDirection)?.label ?? '-'}
|
|
</Text>
|
|
</View>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginT]}>野地板種類</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL, styles.marginT]}>
|
|
{selectBoxOptions.openFieldPlateKind.find((kind) => kind.id.toString() === survey?.detailInfo?.openFieldPlateKind)?.name ??
|
|
(survey?.detailInfo?.openFieldPlateKindEtc ? `${survey?.detailInfo?.openFieldPlateKindEtc}` : '-')}
|
|
</Text>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginL, styles.marginT]}>野地板厚さ</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex2, styles.marginL, styles.marginT]}>
|
|
{survey?.detailInfo?.openFieldPlateThickness ? `${survey?.detailInfo?.openFieldPlateThickness}mm` : '-'}
|
|
</Text>
|
|
</View>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginT]}>兩漏の形跡</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL, styles.marginT]}>
|
|
{survey?.detailInfo?.leakTrace ? 'あり' : 'なし'}
|
|
</Text>
|
|
</View>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginT]}>ルーフィング種類</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL, styles.marginT]}>
|
|
{radioEtcData.waterproofMaterial.find((material) => material.id.toString() === survey?.detailInfo?.waterproofMaterial)?.label ??
|
|
(survey?.detailInfo?.waterproofMaterialEtc ? ` ${survey?.detailInfo?.waterproofMaterialEtc}` : '-')}
|
|
</Text>
|
|
</View>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginT]}>断熱材の有無</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL, styles.marginT]}>
|
|
{radioEtcData.insulationPresence.find((presence) => presence.id.toString() === survey?.detailInfo?.insulationPresence)?.label}
|
|
{survey?.detailInfo?.insulationPresenceEtc ? `, ${survey?.detailInfo?.insulationPresenceEtc}` : ''}
|
|
</Text>
|
|
</View>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderMedium, styles.marginT]}>屋根構造の順番</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL, styles.marginT]}>
|
|
{radioEtcData.structureOrder.find((order) => order.id.toString() === survey?.detailInfo?.structureOrder)?.label ??
|
|
(survey?.detailInfo?.structureOrderEtc ? `${survey?.detailInfo?.structureOrderEtc}` : '-')}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
|
|
{/* Installation Availability */}
|
|
<View style={styles.sectionNoPadding}>
|
|
<View style={styles.table}>
|
|
<View style={styles.tableRow}>
|
|
<Text style={[styles.tableHeader, styles.tableHeaderLarge]}>区根製品名設置可否確認</Text>
|
|
<Text style={[styles.tableCell, styles.tableCellFlex1, styles.marginL]}>
|
|
{survey?.detailInfo?.installationAvailability === null && survey.detailInfo?.installationAvailabilityEtc === null
|
|
? '-'
|
|
: selectBoxOptions.installationAvailability.find(
|
|
(availability) => availability.id.toString() === survey?.detailInfo?.installationAvailability,
|
|
)?.name}
|
|
{survey?.detailInfo?.installationAvailabilityEtc ? `, ${survey?.detailInfo?.installationAvailabilityEtc}` : ''}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
|
|
{/* Memo */}
|
|
<View style={styles.section}>
|
|
<Text style={styles.sectionTitle}>メモ</Text>
|
|
<View style={styles.memoBox}>
|
|
<Text>{survey?.detailInfo?.memo ?? '-'}</Text>
|
|
</View>
|
|
</View>
|
|
</Page>
|
|
)
|
|
}
|