onsitesurvey/src/components/pdf/SurveySalePdf.tsx

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>
)
}