Skip to content

Templates

Full page examples composed entirely from existing Jetpack UI components — no one-off markup, no new components. Each template below is a realistic starting point you can copy into a project and adapt.

Login

A centered authentication card with email/password fields and a primary sign-in action.

Tailwind v4
vue
<script setup>
import { ref } from 'vue'
const email = ref('')
const password = ref('')
</script>

<template>
  <div class="flex justify-center">
    <Card style="width:360px" :shadow="true">
      <div style="text-align:center">
        <div>Jetpack Labs</div>
        <div>Sign in to your account</div>
      </div>

      <div class="flex flex-col gap-4">
        <FormGroup label="Email address" for="email">
          <Input id="email" v-model="email" type="email" placeholder="you@example.com" />
        </FormGroup>

        <FormGroup label="Password" for="password">
          <Input id="password" v-model="password" type="password" placeholder="••••••••" />
        </FormGroup>

        <Button class="w-full">Sign in</Button>

        <Link href="#" variant="subtle">Forgot password?</Link>
      </div>
    </Card>
  </div>
</template>

Settings

A settings form combining Input, Toggle, and Select for profile and preference fields, with a save action.

Tailwind v4
vue
<script setup>
import { ref } from 'vue'
const name = ref('Jamie Rivera')
const email = ref('jamie@jetpacklabs.com')
const notifications = ref(true)
const marketing = ref(false)
const timezone = ref('America/Denver')
</script>

<template>
  <Card>
    <template #header>Account settings</template>

    <div class="flex flex-col gap-4">
      <FormGroup label="Full name" for="name">
        <Input id="name" v-model="name" />
      </FormGroup>

      <FormGroup label="Email address" for="email">
        <Input id="email" v-model="email" type="email" />
      </FormGroup>

      <FormGroup label="Timezone" for="tz">
        <Select v-model="timezone" :options="timezoneOptions" />
      </FormGroup>

      <Toggle v-model="notifications" label="Email notifications" />
      <Toggle v-model="marketing" label="Product updates & marketing" />
    </div>

    <template #footer>
      <Button variant="secondary">Cancel</Button>
      <Button>Save changes</Button>
    </template>
  </Card>
</template>

Dashboard

A row of stat cards summarizing key metrics, followed by a DataTable of underlying records.

<Card>
  <template #header>
    <span style="font-size:15px;font-weight:600;color:#111827">Equipment status</span>
  </template>
  <DataTable
    :columns="dashColumns"
    :rows="dashRows"
    :total="dashRows.length"
    :page="dashPage"
    :per-page="DASH_PER_PAGE"
    @update:page="dashPage = $event"
  >
    <template #cell-status="{ value }">
      <Badge :variant="dashStatusVariant(value)"></Badge>
    </template>
  </DataTable>
</Card>
Tailwind v4
vue
<script setup>
import { ref } from 'vue'

const columns = [
  { key: 'name',     label: 'Name' },
  { key: 'status',   label: 'Status' },
  { key: 'location', label: 'Location' },
  { key: 'updated',  label: 'Last Updated', align: 'right' },
]
const rows = ref([...])
const page = ref(1)
const statusVariant = (s) =>
  s === 'Running' ? 'success' : s === 'Down' ? 'danger' : 'neutral'
</script>

<template>
  <div class="flex flex-col gap-6">
    <div class="flex flex-wrap gap-4">
      <StatCard label="Total Production" value="4,820 t" />
      <StatCard label="Throughput" value="312 t/h" :trend="8.5" trend-label="vs last week" />
      <StatCard label="Active Equipment" value="18 / 22" />
      <StatCard label="Downtime" value="2.1 hrs" :trend="-4.2" trend-label="vs last week" />
    </div>

    <Card>
      <template #header>Equipment status</template>
      <DataTable
        :columns="columns"
        :rows="rows"
        :total="rows.length"
        :page="page"
        :per-page="4"
        @update:page="page = $event"
      >
        <template #cell-status="{ value }">
          <Badge :variant="statusVariant(value)">{{ value }}</Badge>
        </template>
      </DataTable>
    </Card>
  </div>
</template>

Empty State

EmptyState inside a Card, paired with a call-to-action button to create the first record.

Tailwind v4
vue
<template>
  <Card>
    <EmptyState
      icon="🏗️"
      title="No equipment records"
      description="Add your first piece of equipment to start tracking status and production."
    >
      <template #action>
        <Button>Add equipment</Button>
      </template>
    </EmptyState>
  </Card>
</template>

Private — Jetpack Labs internal use only