- Preview
- Code
- Data (.dayta)
Example of a simple log summary email
Copy
import {
Html,
Head,
Preview,
Body,
Container,
Text,
Section,
Row,
Column,
} from '@react-email/components';
import { useDaytalog } from 'daytalog';
const DaySummary: React.FC = () => {
const { projectName, log, message } = useDaytalog();
const title = `DAY ${log.day()} - ${log.date()}`;
const datacols = [
log.ocf.files() && { label: 'Camera:', size: log.ocf.sizeAsTuple() },
log.sound.files() && { label: 'Sound:', size: log.sound.sizeAsTuple() },
log.proxy.files() && { label: 'Proxy:', size: log.proxy.sizeAsTuple() },
].filter(Boolean) as { label: string; size: [number, string] }[];
return (
<Html>
<Head>
<style>{`
@media only screen and (max-width:500px){
.col-pad { padding-right:0 !important; }
.title { font-size:24px !important; }
.big { font-size:20px !important; }
}
`}</style>
</Head>
<Preview>{`Backup Report - ${title} - ${projectName}`}</Preview>
<Body style={main}>
<Container style={container}>
<Section>
<Text style={titleStyle}>{title}</Text>
<Text style={description}>Project: {projectName.toUpperCase()}</Text>
</Section>
<Section style={section}>
<Text>
All footage has been successfully collected, backed up to{' '}
<strong>{log.ocf.copies().length}</strong> separate locations, and is in good
standing.
</Text>
<Text>{message}</Text>
<table role='presentation' cellPadding={0} cellSpacing={0} width='100%'>
<tbody>
{log.ocf.copies().map((copy, i) => (
<tr key={i}>
<td
style={{
width: 160,
fontWeight: 600,
padding: '6px 8px 6px 0',
whiteSpace: 'nowrap',
color: '#475569',
}}
>
✅ Verified Copy {i + 1}:
</td>
<td style={{ padding: '6px 0' }}>{copy.volumes}</td>
</tr>
))}
</tbody>
</table>
</Section>
{!!log.ocf.duration() && <Card label='Duration:' text={log.ocf.duration()} />}
{!!log.ocf.reels().length && (
<Card label='Camera Reels:' text={log.ocf.reels({ mergeRanges: true }).join(' ')} />
)}
<Row>
{datacols.map((c, i) => (
<Column
key={i}
className='col-pad'
style={i < datacols.length - 1 ? { paddingRight: '12px' } : undefined}
>
<Card label={c.label} size={c.size} />
</Column>
))}
</Row>
</Container>
</Body>
</Html>
);
};
const Card: React.FC<{ label: string; text?: string; size?: [number, string] }> = ({
label,
text,
size,
}) => (
<Section style={card}>
<Text style={cardTitle}>{label}</Text>
{text ? <Text style={cardText}>{text}</Text> : null}
{size ? <CardSize size={size} /> : null}
</Section>
);
const CardSize: React.FC<{ size: [number, string] }> = ({ size: [value, unit] }) => (
<Text style={cardText}>
{value}
<span style={{ fontSize: '16px' }}> {unit}</span>
</Text>
);
const main: React.CSSProperties = {
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"',
backgroundColor: '#ffffff',
color: '#334155',
};
const container: React.CSSProperties = {
maxWidth: '480px',
margin: '0 auto',
padding: '20px 0 48px',
};
const titleStyle: React.CSSProperties = {
fontSize: '28px',
lineHeight: '1.25',
textAlign: 'center',
margin: '0 0 8px',
color: '#0f172a',
};
const description: React.CSSProperties = {
fontSize: '16px',
lineHeight: '1.5',
textAlign: 'center',
margin: '0 0 16px',
color: '#64748b',
};
const section: React.CSSProperties = {
padding: '20px',
margin: '16px 0',
border: '1px solid #e5e7eb',
borderRadius: '10px',
textAlign: 'left',
};
const card: React.CSSProperties = {
padding: '16px 18px',
marginBottom: '16px',
borderRadius: '12px',
border: '1px solid #e5e7eb',
};
const cardTitle: React.CSSProperties = {
fontSize: '12px',
lineHeight: '1.4',
fontWeight: 600,
textTransform: 'uppercase',
letterSpacing: '0.3px',
margin: '0 0 6px',
color: '#475569',
};
const cardText: React.CSSProperties = {
fontSize: '24px',
lineHeight: '1.2',
fontWeight: 300,
margin: 0,
color: '#334155',
};
export default DaySummary;
Copy
day: 1
date: 2025-08-15
ocf:
clips:
- clip: A001C001
size: 7572467904
copies:
- volume: Raid
hash: 4607f64fcae33728
- volume: Master_01
hash: 4607f64fcae33728
- volume: Backup_01
hash: 4607f64fcae33728
tc_start: 10:13:25:08
tc_end: 10:14:01:13
duration: 00:00:36:05
camera_model: CinemaCamera
reel: A001
fps: 25
sensor_fps: 25
lens: 40 mm
shutter: 180
resolution: 4608x3164
codec: ProRes 4444
gamma: LOG-C
ei: 800
wb: 5300
tint: "+0.0"
lut: commercial.cube
- clip: A001C002
size: 8642912484
copies:
- volume: Raid
hash: b90261cadf8aab43
- volume: Master_01
hash: b90261cadf8aab43
- volume: Backup_01
hash: b90261cadf8aab43
tc_start: 10:15:18:07
tc_end: 10:15:59:04
duration: 00:00:40:22
camera_model: CinemaCamera
reel: A001
fps: 25
sensor_fps: 25
lens: 40 mm
shutter: 180
resolution: 4608x3164
codec: ProRes 4444
gamma: LOG-C
ei: 800
wb: 5300
tint: "+0.0"
lut: commercial.cube
- clip: A001C003
size: 13965590828
copies:
- volume: Raid
hash: d21f12407d0ca819
- volume: Master_01
hash: d21f12407d0ca819
- volume: Backup_01
hash: d21f12407d0ca819
tc_start: 10:16:28:14
tc_end: 10:17:35:14
duration: 00:01:07:00
camera_model: CinemaCamera
reel: A001
fps: 25
sensor_fps: 25
lens: 40 mm
shutter: 180
resolution: 4608x3164
codec: ProRes 4444
gamma: LOG-C
ei: 800
wb: 5300
tint: "+0.0"
lut: commercial.cube
sound:
clips:
- clip: Clip001
size: 43926156
copies:
- volume: Raid
hash: b69d17d38b5fcb32
- volume: Master_01
hash: b69d17d38b5fcb32
- volume: Backup_01
hash: b69d17d38b5fcb32
tc_start: 10:13:07:00
tc_end: 10:14:08:00
- clip: Clip002
size: 38886174
copies:
- volume: Raid
hash: 2157d011ed699744
- volume: Master_01
hash: 2157d011ed699744
- volume: Backup_01
hash: 2157d011ed699744
tc_start: 10:15:09:00
tc_end: 10:16:03:00
- clip: Clip003
size: 57606144
copies:
- volume: Raid
hash: 8f520e1bed7eec41
- volume: Master_01
hash: 8f520e1bed7eec41
- volume: Backup_01
hash: 8f520e1bed7eec41
tc_start: 10:16:18:00
tc_end: 10:17:38:00
proxy:
clips:
- clip: A001C001
size: 159900258
format: MOV
codec: prores
resolution: 1920x1080
- clip: A001C002
size: 186713854
format: MOV
codec: prores
resolution: 1920x1080
- clip: A001C003
size: 305947102
format: MOV
codec: prores
resolution: 1920x1080
version: 1