style: general tweaking

This commit is contained in:
Riccardo
2023-12-18 18:17:50 +01:00
parent 37ffb951a9
commit 5407e2cf79
10 changed files with 99 additions and 115 deletions

View File

@@ -29,3 +29,5 @@ RESEND_FROM=""
SECRET_HASH=""
HOME_URL=""
MAINTENANCE_MODE=0
BRAND_NAME=""
BRAND_EMAIL=""

View File

@@ -1,5 +1,11 @@
# Hackernews newsletter
## Next up
- Batch email (Resend: ETA early 2024)
- Custom url shortener for links in the newsletter
- Cron every 10 minutes: people are more likely to open the newsletter if delivered around the time when they subscribed (if cron becomes not enough, then the cost of sending all the emails might be a bigger issue)
## Vercel basics
Install vercel cli

View File

@@ -6,10 +6,10 @@ export async function GET() {
orderBy: {
createdAt: 'desc'
},
take: 50
take: 100
});
if (news && news.length === 50) {
if (news && news.length === 100) {
return ApiResponse(200, JSON.stringify(news));
}

View File

@@ -1,5 +1,6 @@
import { useState } from 'react';
import { z } from 'zod';
import { getRandomColor } from '../../../../utils/getRandomColor';
import { NewsSchema } from '../../../../utils/schemas';
type CardContentProps = {
@@ -7,15 +8,6 @@ type CardContentProps = {
side: boolean;
};
function getRandomColor() {
const letters = '456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 12)];
}
return color;
}
export function TileContent({ story, side }: CardContentProps) {
const [firstColor, setFirstColor] = useState(getRandomColor());
const [secondColor, setSecondColor] = useState(getRandomColor());
@@ -32,14 +24,15 @@ export function TileContent({ story, side }: CardContentProps) {
return (
<div
className={`h-40 w-40 overflow-hidden p-6 shadow-sm`}
className={`h-40 w-40 overflow-hidden rounded-lg p-6 shadow-sm`}
style={{
backgroundColor: `${color}`
}}
>
<h1 className='overflow-auto font-semibold'>{story.title}</h1>
<p className='overflow-auto italic'>{story.by}</p>
<p className='overflow-auto italic'>by {story.by}</p>
<div
className='rounded-lg'
style={{
position: 'absolute',
left: 0,

View File

@@ -1,14 +1,22 @@
import { getRandomColor } from '../../../utils/getRandomColor';
export function Footer() {
const background = getRandomColor();
return (
<footer className='mt-8 border-t border-gray-200 pt-6'>
<div className='mb-4 ml-8 flex items-center justify-between'>
<footer
className='mt-8 bg-blue-200 pt-6 text-black'
style={{ backgroundColor: `${background}` }}
>
<div className='ml-8 flex items-center justify-between pb-4'>
<div>
<h4 className='text-lg font-semibold text-gray-700'>Contact Us</h4>
<p className='text-gray-600'>FromPixels</p>
<p className='text-gray-600'>Email: info@frompixels.com</p>
<h4 className='text-lg font-semibold'>Contact Us</h4>
<p>{process.env.BRAND_NAME}</p>
<a href={`mailto:${process.env.BRAND_EMAIL}`}>
Email: {process.env.BRAND_EMAIL}
</a>
</div>
</div>
<p className='text-sm text-gray-500'></p>
</footer>
);
}

View File

@@ -9,15 +9,13 @@ export default function ConfirmationTemplate(code: string) {
<Email
title={'Welcome!'}
body={
<div className='mt-8'>
<p className='text-base text-gray-700 dark:text-gray-400'>
Dear subscriber,
</p>
<p className='mt-2 text-base text-gray-700 dark:text-gray-400'>
<div className='text-base text-gray-700 dark:text-gray-400'>
<p>Dear subscriber,</p>
<p className='mt-2 '>
thank you for subscribing to our newsletter! Please click the
button below to confirm your subscription.
</p>
<div className='mt-8 flex justify-center'>
<div className='my-8 flex justify-center'>
<Link
path={`${process.env.HOME_URL}/confirmation?code=${code}`}
text='Confirm Subscription'

View File

@@ -1,10 +1,7 @@
import { Container } from '@react-email/container';
import { Html } from '@react-email/html';
import { Section } from '@react-email/section';
import { Text } from '@react-email/text';
import { z } from 'zod';
import { getRandomColor } from '../../utils/getRandomColor';
import { NewsSchema } from '../../utils/schemas';
import { Footer } from './components/footer';
import Email from './template';
export default function NewsletterTemplate(
stories: z.infer<typeof NewsSchema>[]
@@ -26,36 +23,27 @@ export default function NewsletterTemplate(
return {
subject: `What's new from Hackernews?`,
template: (
<Html>
<Section className='bg-white'>
<div className='mx-auto w-full max-w-2xl overflow-hidden rounded-lg bg-white shadow-lg'>
<div className='text-center '>
<h1 className='my-4 text-3xl font-bold'>Good day!</h1>
<p>
<Email
title='Good day!'
body={
<div className='text-base text-gray-700 dark:text-gray-400'>
<p className='flex justify-center'>
Here is something{' '}
{sayings[Math.floor(Math.random() * sayings.length)]}:
</p>
</div>
<Container
style={{
margin: '0 auto',
padding: '20px 0 48px',
width: '580px'
}}
>
<Text>
{stories.map(story => {
const background = getRandomColor();
return (
<div
key={story.id}
className='mt-8 rounded-lg border bg-card text-card-foreground shadow-sm'
data-v0-t='card'
style={{ backgroundColor: `${background}` }}
>
<div className='flex flex-col space-y-1.5 p-6'>
<h2 className='text-2xl font-semibold'>
{story.title}
</h2>
<p>{story.by}</p>
<div className='flex flex-col space-y-1.5 px-6 pb-2 pt-6'>
<h2 className='text-2xl font-semibold'>{story.title}</h2>
<p className='italic'>by {story.by}</p>
</div>
{story.text && (
<div className='px-6'>
@@ -71,26 +59,16 @@ export default function NewsletterTemplate(
</div>
)}
{story.url && (
<div className='p-4 text-right'>
<p>
<a
href={story.url}
className='inline-flex h-10 items-center justify-center rounded-md bg-blue-500 px-4 py-2 text-sm font-medium text-primary-foreground ring-offset-background transition-colors hover:bg-blue-700/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50'
>
Read more
</a>
</p>
<div className='p-6 text-right font-bold'>
<a href={story.url}>Read more</a>
</div>
)}
</div>
);
})}
</Text>
</Container>
<Footer />
</div>
</Section>
</Html>
}
/>
)
};
}

View File

@@ -1,7 +1,6 @@
import { Container } from '@react-email/container';
import { Html } from '@react-email/html';
import { Section } from '@react-email/section';
import { Text } from '@react-email/text';
import { getRandomColor } from '../../utils/getRandomColor';
import { Footer } from './components/footer';
type EmailProps = {
@@ -10,26 +9,18 @@ type EmailProps = {
};
export default function Email({ title, body }: EmailProps) {
const titleBackground = getRandomColor();
return (
<Html>
<Section className='mx-auto w-full max-w-2xl overflow-hidden rounded-lg bg-white shadow-lg'>
<Container
style={{
margin: '0 auto',
padding: '20px 0 48px',
width: '580px'
}}
<Section className='max-w-2xl overflow-hidden rounded-lg bg-white shadow-lg'>
<h1
className='p-8 text-center text-3xl font-bold text-black'
style={{ backgroundColor: `${titleBackground}` }}
>
<h1 className='mt-4 text-center text-3xl font-bold'>{title}</h1>
<Text
style={{
fontSize: '16px',
marginBottom: '16px'
}}
>
{body}
</Text>
</Container>
{title}
</h1>
<div className='m-8 p-8'>{body}</div>
<Footer />
</Section>
</Html>

View File

@@ -9,8 +9,8 @@ export default function UnsubscribeTemplate() {
<Email
title="We're sad you're leaving :("
body={
<div className='mt-8'>
<p className='mt-2 text-base text-gray-700 dark:text-gray-400'>
<div className='text-base text-gray-700 dark:text-gray-400'>
<p className='mt-2 '>
You have been successfully unsubscribed from our newsletter. You
won&apos;t receive any further communications from us unless you
explicitly opt-in again.

8
utils/getRandomColor.ts Normal file
View File

@@ -0,0 +1,8 @@
export function getRandomColor() {
const letters = '6789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 10)];
}
return color;
}