> ## Documentation Index
> Fetch the complete documentation index at: https://docs.daytalog.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ClipsReport

> Example of a simple clips report

<Tabs>
  <Tab title="Preview">
    <Frame caption="Simple Clips Report with data from OCF, Proxy and Sound combined" className="mt-3">
      <iframe src="https://assets.daytalog.com/example/ClipReport.pdf" width="100%" height="400" min-height="100vh" />
    </Frame>
  </Tab>

  <Tab title="Code">
    ```Typescript theme={null}
    import { Page, Text, View, Document, StyleSheet, Image } from '@react-pdf/renderer';
    import { useDaytalog } from 'daytalog';
    import logo from './assets/obsidian.png';

    const ClipsReport: React.FC = () => {
    const { projectName, log } = useDaytalog();

    const rows: Array<Record<string, any>> = log.clips.map((clip) => ({
      clip: clip.clip,
      tc_start: clip.tc_start,
      tc_end: clip.tc_end,
      duration: clip.durationTC(),
      fps: clip.fps !== clip.sensor_fps ? clip.fps : `${clip.sensor_fps} / (TC: ${clip.fps})`,
      size: clip.size(),
      camera: clip.camera_model,
      lens: clip.lens,
      codec: clip.codec,
      resolution: clip.resolution,
      ei: clip.ei,
      wb: clip.wb,
      tint: clip.tint,
      lut: clip.lut,
      proxy_format: `${clip.proxy.codec} (.${clip.proxy.format})`,
      sound: clip.sound?.join(', '),
      copies: clip.copies?.length,
    }));
    const headers = Object.keys(rows[0] || {});

    const charCounts = headers.map((h) => {
      const all = rows.map((r) => String(r[h]).length).concat(h.length);
      return Math.max(...all);
    });
    const totalChars = charCounts.reduce((sum, x) => sum + x, 0);

    // 2) Convert to % widths:
    const colPercents = charCounts.map((c) => (c / totalChars) * 100);

    return (
      <Document title='Clips'>
        <Page size='A4' orientation='landscape' style={styles.page}>
          <View>
            <View style={styles.header}>
              <View>
                <Text style={styles.title}>{`Clips Report - Day ${log.day()} - ${log.date()}`}</Text>
                <Text>Project: {projectName}</Text>
              </View>
              <Image style={styles.logo} src={logo} />
            </View>
            <View style={styles.cardGroup}>
              <View style={styles.card}>
                <Text style={styles.cardTitle}>Duration</Text>
                <Text style={styles.cardText}>{log.ocf.duration()}</Text>
              </View>
              <View style={styles.card}>
                <Text style={styles.cardTitle}>Camera Files</Text>
                <Text style={styles.cardText}>{`${log.ocf.files()} clips, ${log.ocf.size()}`}</Text>
              </View>
              <View style={styles.card}>
                <Text style={styles.cardTitle}>Proxy Files</Text>
                <Text
                  style={styles.cardText}
                >{`${log.proxy.files()} clips, ${log.proxy.size()}`}</Text>
              </View>
              <View style={styles.card}>
                <Text style={styles.cardTitle}>Sound Files</Text>
                <Text
                  style={styles.cardText}
                >{`${log.sound.files()} clips, ${log.sound.size()}`}</Text>
              </View>
              <View style={styles.card}>
                <Text style={styles.cardTitle}>Camera Reels</Text>
                <Text style={styles.cardText}>{log.ocf.reels({ mergeRanges: true })}</Text>
              </View>
            </View>
            {!!log.clips.length ? (
              <View style={styles.table}>
                {/* Header Row */}
                <View style={styles.row} fixed>
                  {headers.map((header, i) => (
                    <Text
                      key={i}
                      style={[
                        styles.headerCell,
                        {
                          width: `${colPercents[i]}%`,
                          borderTopLeftRadius: i === 0 ? 2 : 0,
                          borderTopRightRadius: i === headers.length - 1 ? 2 : 0,
                        },
                      ]}
                    >
                      {(() => {
                        const label = header
                          .replace(/_/g, ' ')
                          .replace(/\b\w/g, (c) => c.toUpperCase());
                        return label.length <= 3 ? label.toUpperCase() : label;
                      })()}
                    </Text>
                  ))}
                </View>

                {/* Data Rows */}
                {rows.map((row, rowIndex) => (
                  <View
                    key={rowIndex}
                    style={[styles.row, rowIndex % 2 === 1 ? styles.zebra : {}]}
                    wrap={false}
                  >
                    {headers.map((header, colIndex) => (
                      <Text
                        key={colIndex}
                        style={[styles.cell, { width: `${colPercents[colIndex]}%` }]}
                      >
                        {row[header]}
                      </Text>
                    ))}
                  </View>
                ))}
              </View>
            ) : (
              <View>
                <Text>{`No clips :(`}</Text>
              </View>
            )}
          </View>
          <Text
            style={styles.pageNumber}
            render={({ pageNumber, totalPages }) => totalPages > 1 && pageNumber + ' / ' + totalPages}
            fixed
          />
        </Page>
      </Document>
    );
    };

    const styles = StyleSheet.create({
    page: { fontFamily: 'Helvetica', padding: 40, fontSize: 12, backgroundColor: '#fff' },
    title: { fontSize: 24, fontWeight: 'bold', marginBottom: 20, color: '#333' },
    projectInfo: { fontSize: 12 },
    table: { display: 'table', width: '100%', borderCollapse: 'collapse', marginTop: 10 },
    row: { flexDirection: 'row' },
    headerCell: {
      padding: 6,
      backgroundColor: '#09090b',
      color: '#fff',
      fontSize: 5,
      fontWeight: '500',
      textAlign: 'left',
    },
    cell: {
      padding: 6,
      fontSize: 4,
      color: '#333',
      textAlign: 'left',
      borderBottomWidth: 0.2,
      borderBottomColor: '#ddd',
    },
    zebra: { backgroundColor: '#f8f8f8' },
    pageNumber: { fontSize: 4, position: 'absolute', bottom: 20, right: 20 },
    logo: {
      width: 60,
      height: 60,
      marginBottom: 20,
    },
    header: {
      flex: 'auto',
      flexDirection: 'row',
      justifyContent: 'space-between',
      alignItems: 'center',
    },
    cardGroup: {
      flexDirection: 'row',
      gap: 8,
      marginTop: 8,
      marginBottom: 8,
    },
    card: {
      width: '25%',
      gap: 2,
      padding: 18,
      borderRadius: 8,
      borderWidth: 1,
      borderColor: '#dedede',
    },
    cardTitle: {
      fontSize: 8,
      fontWeight: 'bold',
    },
    cardText: {
      fontSize: 14,
      fontWeight: '200',
    },
    });

    export default ClipsReport;
    ```
  </Tab>

  <Tab title="Data (.dayta)">
    ```yaml theme={null}
    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

    ```
  </Tab>
</Tabs>
