Yassaaa
Yassaaa
Explore posts from servers
NNuxt
Created by Yassaaa on 8/13/2024 in #❓・help
Need help with creating mail templates with dynamic data and sending it
I did use Claude and Github Copilot for help.
6 replies
NNuxt
Created by Yassaaa on 8/13/2024 in #❓・help
Need help with creating mail templates with dynamic data and sending it
Issues Encountered: 1. When trying to display the email HTML in the page's body, I get warnings like "missing required prop". 2. In the server console, I get the following error:
WARN [plugin inject] emails/Order_Confirmation.vue: rollup-plugin-inject: [...]. Consider restricting the plugin to particular files via options.include

ERROR RollupError: emails/Order_Confirmation.vue (1:0): Expression expected (Note that you need plugins to import files that are not JavaScript) nitro 10:56:21


1: <script setup lang="ts">
^
2: import {
3: Html,
WARN [plugin inject] emails/Order_Confirmation.vue: rollup-plugin-inject: [...]. Consider restricting the plugin to particular files via options.include

ERROR RollupError: emails/Order_Confirmation.vue (1:0): Expression expected (Note that you need plugins to import files that are not JavaScript) nitro 10:56:21


1: <script setup lang="ts">
^
2: import {
3: Html,
I am using Pinia for state management and want to pass the data from the Pinia states to the email template and send it with Nodemailer. The checkout store has a formData state that contains all the relevant data about the customer like name, email, phone, address, etc. I would appreciate any guidance or suggestions on how to resolve these issues and successfully combine sending emails with Nodemailer and creating email templates with Vue-Mail.
6 replies
NNuxt
Created by Yassaaa on 8/13/2024 in #❓・help
Need help with creating mail templates with dynamic data and sending it
3. Combining Both: I tried to combine both functionalities by creating an API endpoint that generates the email HTML and sends the email. Here is the code:
import { defineEventHandler } from 'h3'
import { useShoppingCartStore } from '~/stores/shoppingCartStore'
import { useCheckoutStore } from '~/stores/checkoutStore'
import OrderConfirmationEmail from '~/emails/Order_Confirmation.vue'
import { renderToString } from '@vue/server-renderer'
import { createSSRApp, h } from 'vue'

export default defineEventHandler(async () => {
const shoppingCartStore = useShoppingCartStore()
const checkoutStore = useCheckoutStore()

const emailData = {
items: shoppingCartStore.items.map(item => ({
id: item._uid,
name: item.product_title.length > 32 ? item.product_title.slice(0, 31) + '...' : item.product_title,
quantity: item.item_count,
price: item.price,
image: item.product_image[0].filename || '/icon.svg'
})),
subtotal: shoppingCartStore.subtotal,
discount: shoppingCartStore.discount,
totalItems: shoppingCartStore.totalItems,
orderTotal: shoppingCartStore.total,
orderDate: new Date().toLocaleDateString(),
savings: shoppingCartStore.discount.toFixed(2),
shippingName: checkoutStore.formData.name,
shippingEmail: checkoutStore.formData.email,
shippingPhone: checkoutStore.formData.phone,
shippingAddress: checkoutStore.formData.address,
shippingCity: checkoutStore.formData.city,
shippingState: checkoutStore.formData.country
}

const app = createSSRApp({
render: () => h(OrderConfirmationEmail, { ...emailData })
})

const emailHtml = await renderToString(app)

return {
html: emailHtml
}
})
import { defineEventHandler } from 'h3'
import { useShoppingCartStore } from '~/stores/shoppingCartStore'
import { useCheckoutStore } from '~/stores/checkoutStore'
import OrderConfirmationEmail from '~/emails/Order_Confirmation.vue'
import { renderToString } from '@vue/server-renderer'
import { createSSRApp, h } from 'vue'

export default defineEventHandler(async () => {
const shoppingCartStore = useShoppingCartStore()
const checkoutStore = useCheckoutStore()

const emailData = {
items: shoppingCartStore.items.map(item => ({
id: item._uid,
name: item.product_title.length > 32 ? item.product_title.slice(0, 31) + '...' : item.product_title,
quantity: item.item_count,
price: item.price,
image: item.product_image[0].filename || '/icon.svg'
})),
subtotal: shoppingCartStore.subtotal,
discount: shoppingCartStore.discount,
totalItems: shoppingCartStore.totalItems,
orderTotal: shoppingCartStore.total,
orderDate: new Date().toLocaleDateString(),
savings: shoppingCartStore.discount.toFixed(2),
shippingName: checkoutStore.formData.name,
shippingEmail: checkoutStore.formData.email,
shippingPhone: checkoutStore.formData.phone,
shippingAddress: checkoutStore.formData.address,
shippingCity: checkoutStore.formData.city,
shippingState: checkoutStore.formData.country
}

const app = createSSRApp({
render: () => h(OrderConfirmationEmail, { ...emailData })
})

const emailHtml = await renderToString(app)

return {
html: emailHtml
}
})
6 replies
NNuxt
Created by Yassaaa on 8/13/2024 in #❓・help
Need help with creating mail templates with dynamic data and sending it
2. Creating Email Templates with Vue: I have created a template using Vue components and props. Here is the template:
6 replies
NNuxt
Created by Yassaaa on 8/13/2024 in #❓・help
Need help with creating mail templates with dynamic data and sending it
What I have tried: 1. Sending Emails with Nodemailer: I have a working implementation that sends emails using Nodemailer. Here is the relevant code:
<template>
<button @click="placeOrder" class="btn btn-circle">
Send Mail
</button>
</template>

<script setup lang="ts">
async function placeOrder() {
const orderDetails = {
senderEmail: '[email protected]',
recepient: '[email protected]',
subject: 'New Order Received',
name: 'TEST ORDER NOT REAL', // Replace with actual data
address: '123 Main St', // Replace with actual data
items: ['item1', 'item2'], // Replace with actual data
coupon: 'SAVE20' // Replace with actual data
};

try {
const response = await $fetch('/api/send-email', {
method: 'POST',
body: orderDetails,
});
alert('Email sent successfully!');
} catch (error) {
alert('An error occurred while sending the email. Please try again later.');
}
}

</script>
<template>
<button @click="placeOrder" class="btn btn-circle">
Send Mail
</button>
</template>

<script setup lang="ts">
async function placeOrder() {
const orderDetails = {
senderEmail: '[email protected]',
recepient: '[email protected]',
subject: 'New Order Received',
name: 'TEST ORDER NOT REAL', // Replace with actual data
address: '123 Main St', // Replace with actual data
items: ['item1', 'item2'], // Replace with actual data
coupon: 'SAVE20' // Replace with actual data
};

try {
const response = await $fetch('/api/send-email', {
method: 'POST',
body: orderDetails,
});
alert('Email sent successfully!');
} catch (error) {
alert('An error occurred while sending the email. Please try again later.');
}
}

</script>
6 replies
NNuxt
Created by Yassaaa on 7/8/2024 in #❓・help
Nuxt DevTools Modules page is bugged
Any dev or mod online and can help with this please? bumping post
6 replies
NNuxt
Created by Yassaaa on 7/8/2024 in #❓・help
Nuxt DevTools Modules page is bugged
I also tried deleting .nuxt and modules directories and reinstalled everything but nothing changed.
6 replies
NNuxt
Created by Yassaaa on 6/1/2024 in #❓・help
Tailwind CSS: Unhandled exception: require() of ES Module
anyone?
4 replies
NNuxt
Created by Yassaaa on 5/31/2024 in #❓・help
Need help with brevo integration
anyone pls help
2 replies
NNuxt
Created by Yassaaa on 6/1/2024 in #❓・help
Tailwind CSS: Unhandled exception: require() of ES Module
PLEASE PING ME IF YOU REPLY
4 replies
NNuxt
Created by Yassaaa on 6/1/2024 in #❓・help
Tailwind CSS: Unhandled exception: require() of ES Module
here is my nuxt.config.ts:
// https://nuxt.com/docs/api/configuration/nuxt-config
import fs from "node:fs";
import path from "node:path";

export default defineNuxtConfig({
devtools: { enabled: true },
devServer: {
https: {
key: fs.readFileSync(path.resolve(__dirname, './certs/localhost+2-key.pem')).toString(),
cert: fs.readFileSync(path.resolve(__dirname, './certs/localhost+2.pem')).toString(),
},
port: 3000 // Ensure the server runs on port 3000
},
modules: [
"@nuxtjs/tailwindcss",
"@nuxtjs/device",
"nuxt-viewport",
"nuxt-icon",
"@storyblok/nuxt",
"@nuxt/image",
"nuxt-twemoji",
],
vue: {
compilerOptions: {
isCustomElement: (tag) => tag === 'formester-popup'
},
},
storyblok: {
accessToken: process.env.NUXT_STORYBLOK_API_KEY
},
runtimeConfig: {
StoryblokApiKey: process.env.NUXT_STORYBLOK_API_KEY,
public: {
NodeEnv: process.env.NUXT_NODE_ENV,
}
},
router: {
options: {
scrollBehaviorType: "smooth",
},
},
app: {
pageTransition: {
name: "page",
mode: "out-in",
},
},
viewport: {
breakpoints: {
desktop: 1024,
desktopMedium: 1280,
desktopBetween: 1296,
desktopWide: 1600,

mobile: 320,
mobileMedium: 375,
mobileWide: 425,
mobileWideButSmaller: 480,
mobileOther: 532,

tabletLandscape: 1035,
tablet: 768,
},
},
})
// https://nuxt.com/docs/api/configuration/nuxt-config
import fs from "node:fs";
import path from "node:path";

export default defineNuxtConfig({
devtools: { enabled: true },
devServer: {
https: {
key: fs.readFileSync(path.resolve(__dirname, './certs/localhost+2-key.pem')).toString(),
cert: fs.readFileSync(path.resolve(__dirname, './certs/localhost+2.pem')).toString(),
},
port: 3000 // Ensure the server runs on port 3000
},
modules: [
"@nuxtjs/tailwindcss",
"@nuxtjs/device",
"nuxt-viewport",
"nuxt-icon",
"@storyblok/nuxt",
"@nuxt/image",
"nuxt-twemoji",
],
vue: {
compilerOptions: {
isCustomElement: (tag) => tag === 'formester-popup'
},
},
storyblok: {
accessToken: process.env.NUXT_STORYBLOK_API_KEY
},
runtimeConfig: {
StoryblokApiKey: process.env.NUXT_STORYBLOK_API_KEY,
public: {
NodeEnv: process.env.NUXT_NODE_ENV,
}
},
router: {
options: {
scrollBehaviorType: "smooth",
},
},
app: {
pageTransition: {
name: "page",
mode: "out-in",
},
},
viewport: {
breakpoints: {
desktop: 1024,
desktopMedium: 1280,
desktopBetween: 1296,
desktopWide: 1600,

mobile: 320,
mobileMedium: 375,
mobileWide: 425,
mobileWideButSmaller: 480,
mobileOther: 532,

tabletLandscape: 1035,
tablet: 768,
},
},
})
4 replies
NNuxt
Created by Yassaaa on 4/9/2024 in #❓・help
nuxt-swiper how to use hash navigation?
<template>
<div>
<div>
<p class="font-semibold text-3xl text-center my-4">Random Map:</p>
<swiper
:slides-per-view="4"
:space-between="30"
:centered-slides="true"
:grabCursor="true"
:loop="true"
:hash-navigation="{
watchState: true,
}"
class="mySwiper"
>
<swiper-slide v-for="(map, index) in mapNamesArray" :key="index" :data-hash="index">
<h1 class="text-center text-3xl font-bold text-white absolute z-1">{{ map }}</h1>
<img :src="mapImagesArray[index]" alt="map image">
</swiper-slide>
</swiper>

</div>


</div>
</template>

<script setup lang="ts">
let url = "https://valorant-api.com/v1/maps"

let { data: mapsRef, error } = useFetch(url)
watch(error, async (newVal) => {
if (newVal) {
console.error("Error fetching maps:", newVal.message)
}
})
let parsedMaps = computed(() => {
return mapsRef.value?.data.filter((m) => !!m.narrativeDescription)
})

let mapNamesArray = computed(() => {
return parsedMaps.value?.map((m) => m.displayName)
})

let mapImagesArray = computed(() => {
return parsedMaps.value?.map((m) => m.splash)
})
</script>

<style scoped lang="scss">

.swiper {
width: 100%;
height: 100%;
}

.swiper-slide {
text-align: center;
font-size: 18px;
background: #fff;

/* Center slide text vertically */
display: flex;
justify-content: center;
align-items: center;
}

//make img cover the whole swiper-slide
//.swiper-slide img {
// width: 100%;
// height: 100%;
// object-fit: cover;
// border-radius: 18px;
//}
.swiper-slide img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}

</style>
<template>
<div>
<div>
<p class="font-semibold text-3xl text-center my-4">Random Map:</p>
<swiper
:slides-per-view="4"
:space-between="30"
:centered-slides="true"
:grabCursor="true"
:loop="true"
:hash-navigation="{
watchState: true,
}"
class="mySwiper"
>
<swiper-slide v-for="(map, index) in mapNamesArray" :key="index" :data-hash="index">
<h1 class="text-center text-3xl font-bold text-white absolute z-1">{{ map }}</h1>
<img :src="mapImagesArray[index]" alt="map image">
</swiper-slide>
</swiper>

</div>


</div>
</template>

<script setup lang="ts">
let url = "https://valorant-api.com/v1/maps"

let { data: mapsRef, error } = useFetch(url)
watch(error, async (newVal) => {
if (newVal) {
console.error("Error fetching maps:", newVal.message)
}
})
let parsedMaps = computed(() => {
return mapsRef.value?.data.filter((m) => !!m.narrativeDescription)
})

let mapNamesArray = computed(() => {
return parsedMaps.value?.map((m) => m.displayName)
})

let mapImagesArray = computed(() => {
return parsedMaps.value?.map((m) => m.splash)
})
</script>

<style scoped lang="scss">

.swiper {
width: 100%;
height: 100%;
}

.swiper-slide {
text-align: center;
font-size: 18px;
background: #fff;

/* Center slide text vertically */
display: flex;
justify-content: center;
align-items: center;
}

//make img cover the whole swiper-slide
//.swiper-slide img {
// width: 100%;
// height: 100%;
// object-fit: cover;
// border-radius: 18px;
//}
.swiper-slide img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}

</style>
2 replies
NNuxt
Created by Yassaaa on 3/14/2024 in #❓・help
useFetch help - not working/fetching data
well I found out that the data I get from the api is already a JS object (i think?) and when I specify the uuid of the map or the agent and then requst the displayName or splash etc... then it works but there seems to be a problem for when I want it to fetch all the data from the api (all the maps or agents) and not only 1 map or agent. When I useFetch all tha agents/maps instead of one it does not show me anything. When I try to parse it I get 500 "[object Object]" is not valid JSON now I am confused why its not working when I want to get the whole list of agents/maps
10 replies
NNuxt
Created by Yassaaa on 3/14/2024 in #❓・help
useFetch help - not working/fetching data
I see thanks! I will try this when I get home
10 replies
NNuxt
Created by Yassaaa on 3/14/2024 in #❓・help
useFetch help - not working/fetching data
I tried reading it but it did not really help. But I did find out that the useFetch is actually working but I believe its returning the data as a string because when I outputed agents i got everything as a string. but when I try to access values within the data i cant because its undefined. soo yea I got it working with the regular fetch for now
10 replies