This is a workshop to learn Nuxt.js
Join our discord channel for two way comms!
If yes
On your fork, click on the "code" button(usually green), clone the repository on your machine
If no
On your fork, click on the "code" button(usually green), and select Codespaces.
Click on "create codespace on main" to get your own cloud ide
This is VS Code running in the cloud! 😎
This might take a moment, depending on your connection speed.
You can now start the project in dev mode by running the following command in the terminal
npm run dev
Note that if you cloned the project, you might need to run `npm install` first
Open port 3000 to view the running project in a new tab
If you see the green messsage, Congratulations! 🎉
If you don't see it, call an instructor to assist you
Create a 'components' folder
Add a new file `Container.vue`
Add the following code to the file
<template>
<div class="container mx-auto">
Hello from Container.vue
</div>
</template>
Let's create a simple layout using tailwind classes
Use the following classes to create a simple layout
<template>
<div class="container mx-auto">
<div class="grid grid-cols-2 gap-4">
<div class="bg-gray-200 p-4">
<h2>Hello from Container.vue</h2>
</div>
<div class="bg-gray-200 p-4">
<h2>Hello from Container.vue</h2>
</div>
</div>
</div>
</template>
Endpoint: https://github.com/MrSunshyne/mauritius-dataset-electricity/blob/main/data/power-outages.latest.json
const API_ENDPOINT = 'https://raw.githubusercontent.com/MrSunshyne/mauritius-dataset-electricity/main/data/power-outages.json'
async function fetchJson(url = API_ENDPOINT) {
try {
const response = await fetch(url)
return response.json()
}
catch (error) {
throw new Error(`Error fetching JSON: ${error}`)
}
}
Display all the outages for today on the page by accessing the correct key
// In the script tag
const outages = await fetchJson()
const { today } = outages
for (const outage of today) {
console.log(outage)
}
// In the template tag
<ul>
<li v-for="outage of today" :key="outage.id">
<pre>{{ outage }}</pre>
</li>
</ul>
Poste De Police, Loday Lane, Flic En Flac Road, Residence Des Peupliers Et Residence Gold Coast
Power will resume in 34m 6s
Le Village De Caroline Dans Le Périmètre De La Route Royale, Avenue Descombe, Avenue Gandhi, Avenue Allaman, Filling Engen Et Shell, Petit Bois, Chemin Balance, Morc. Caunhye
Power will resume in 34m 6s
Flic en Flacq
8 hours ago, From 08:30 to 15:30
Power will resume in 34m 6s
Le Village De Caroline Dans Le Périmètre De La Route Royale, Avenue Descombe, Avenue Gandhi, Avenue Allaman, Filling Engen Et Shell, Petit Bois, Chemin Balance, Morc. Caunhye, Residence EDC, Chemin La Pompe, Morc. Sohawon, Morc.
Flic en Flacq
8 hours ago, From 08:30 to 15:30
Power will resume in 34m 6s
Le Village De Caroline Dans Le Périmètre De La Route Royale, Avenue Descombe, Avenue Gandhi, Avenue Allaman, Filling Engen Et Shell, Petit Bois, Chemin Balance, Morc. Caunhye, Residence EDC, Chemin La Pompe, Morc. Sohawon, Morc.
Here we will learn about props and how to pass them
We will pass the `Street Name, District, Date From, Date To` into the card and customize the content to show our data
// index.vue In the template tag
<ul class="grid gap-y-12 max-w-screen-md mx-auto">
<li v-for="(outage, index) in today" :key="index">
<Outage :outage="outage" />
</li>
</ul>
// components/Outage.vue Create the script tag (setup lang="ts")
import { useTimeAgo } from "@vueuse/core"
// todo: move to types.ts (?)
enum District {
blackriver,
flacq,
grandport,
moka,
pamplemousses,
plainewilhems,
portlouis,
rivieredurempart,
savanne,
rodrigues,
}
// todo: move to types.ts (?)
interface Record {
date: string
locality: string
streets: string
district: District
from: Date
to: Date
id: string
}
type Props = {
outage: Record
}
const props = defineProps<Props>()
// components/Outage.vue Update the template
<div
class="flex flex-col justify-between bg-blue-950 text-white p-4 rounded-md w-full"
>
<div class="flex justify-between w-full">
<div class="text-xl font-bold">{{ props.outage.locality }}</div>
<div class="w-6">
<!-- todo: have the candle <IconCandle /> -->
🕯️
</div>
</div>
<div class="flex justify-between items-end">
<div class="space-y-2">
<p class="font-light max-w-3xl">
{{ props.outage.streets }}
</p>
<div class="text-sm">
{{ props.outage.date }}
</div>
</div>
</div>
</div>
// components/Outage.vue Apend to the script tag contents
...
const state = computed(() => {
let on = "upcoming"
const from = new Date(props.outage.from)
const to = new Date(props.outage.to)
const now = new Date()
if (now.getTime() > from.getTime()) {
on = "ongoing"
}
if (now.getTime() > to.getTime()) {
on = "past"
}
return on
})
const outageMessage = computed(() => {
if (state.value === "ongoing") {
return "will resume in"
} else if (state.value === "upcoming") {
return "will cut in"
} else {
return "has resumed"
}
})
// components/Outage.vue Apend to the template tag contents
// after <div class="text-sm"> {{ props.outage.date }} </div> </div>
<div class="inline md:block">Power {{ outageMessage }}</div>
<div
class="inline md:block"
v-if="!['ongoing', 'upcoming'].includes(state)"
>
{{ useTimeAgo(outage.from, { showSecond: true }) }}
</div>
<div class="inline md:block" v-else>
{{ useTimeAgo(outage.from) }}
</div>