Skip to content

Commit c4c8bc5

Browse files
authored
Merge pull request #52 from meceware/dev
v1.2.1
2 parents 0bf10d5 + cbdd36a commit c4c8bc5

File tree

13 files changed

+75
-37
lines changed

13 files changed

+75
-37
lines changed

.github/workflows/docker-build.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,5 @@ jobs:
5757
tags: ${{ steps.meta.outputs.tags }}
5858
labels: ${{ steps.meta.outputs.labels }}
5959
cache-from: type=gha
60-
cache-to: type=gha,mode=max
60+
cache-to: type=gha,mode=max
61+
network: host

public/apple-icon.png

-9.66 KB
Binary file not shown.

public/images/og.png

95.1 KB
Loading

public/images/x.png

325 KB
Loading

src/app/contact/actions.js

+35-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { Resend } from 'resend';
44
import { z } from 'zod';
5+
import { siteConfig } from '@/components/config';
56

67
const resend = new Resend(process.env.RESEND_API_KEY);
78

@@ -41,11 +42,42 @@ export async function sendContactForm(formData) {
4142
await resend.emails.send({
4243
from: `Contact Form <${process.env.RESEND_FROM}>`,
4344
to: process.env.RESEND_CONTACT_EMAIL,
44-
subject: `Contact Form Submission from ${name}`,
45-
text: `
45+
replyTo: `${name} <${email_address}>`,
46+
subject: `Contact form submission from ${name}`,
47+
text: `New Contact Form Submission
48+
4649
Name: ${name}
4750
Email: ${email_address}
48-
Message: ${message}
51+
52+
Message:
53+
${message}
54+
55+
This is an automated message from ${siteConfig.name}.`,
56+
html: `
57+
<body style="margin: 0; padding: 0; background-color: #efefef;">
58+
<table role="presentation" style="width: 100%; border-collapse: collapse; border: 0;">
59+
<tr>
60+
<td align="center" style="padding: 1rem 2rem;">
61+
<div style="max-width: 400px; background-color: #ffffff; padding: 1rem; text-align: left;">
62+
<h2 style="margin: 1rem 0; color: #000000;">Contact Form Submission</h2>
63+
<p>This is an automated message from ${siteConfig.name}.</p>
64+
<div style="margin: 1rem 0;">
65+
<strong>Name:</strong> ${name}<br>
66+
<strong>Email:</strong> ${email_address}<br><br>
67+
<strong>Message:</strong><br>
68+
${message}
69+
</div>
70+
</div>
71+
<div style="max-width: 400px; color: #999999; text-align: center;">
72+
<p style="padding-bottom: 0.5rem;">Made with ♥ by <a href="${siteConfig.url}" target="_blank">${siteConfig.name}</a></p>
73+
<div style="text-align: center;">
74+
<img src="${siteConfig.url}/icon.png" alt="${siteConfig.from}" style="width: 96px;">
75+
</div>
76+
</div>
77+
</td>
78+
</tr>
79+
</table>
80+
</body>
4981
`,
5082
});
5183

src/app/layout.js

+21-17
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,31 @@ const inter = Inter({ subsets: ['latin'] });
2121

2222
// Metadata
2323
export const metadata = {
24-
metadataBase: new URL( siteConfig.url ),
24+
metadataBase: new URL(siteConfig.url),
2525
alternates: {
26-
canonical: '/',
26+
canonical: './',
2727
},
2828
title: {
2929
default: siteConfig.title,
30-
template: `%s | ${ siteConfig.name }`,
30+
template: `%s | ${siteConfig.name}`,
3131
},
3232
description: siteConfig.description,
3333
keywords: siteConfig.keywords,
34-
authors: [ siteConfig.author ],
34+
authors: [siteConfig.author],
3535
creator: siteConfig.author.name,
3636
publisher: siteConfig.author.name,
3737
referrer: 'origin-when-cross-origin',
3838
robots: {
3939
index: true,
4040
follow: true,
41-
nocache: true,
41+
nocache: false,
42+
noimageindex: false,
43+
'max-video-preview': -1,
44+
'max-image-preview': 'large',
45+
'max-snippet': -1,
4246
googleBot: {
4347
index: true,
4448
follow: true,
45-
noimageindex: true,
4649
'max-video-preview': -1,
4750
'max-image-preview': 'large',
4851
'max-snippet': -1,
@@ -55,35 +58,36 @@ export const metadata = {
5558
title: siteConfig.title,
5659
description: siteConfig.description,
5760
siteName: siteConfig.name,
58-
images: [ `/og.png` ],
61+
images: ['/images/og.png'],
5962
},
6063
twitter: {
6164
card: 'summary_large_image',
6265
title: siteConfig.title,
6366
description: siteConfig.description,
64-
images: [ `/og.png` ],
67+
images: ['/images/x.png'],
6568
},
6669
icons: {
6770
icon: [
71+
{ url: '/icons/icon-32.png', sizes: '32x32', type: 'image/png' },
6872
{ url: '/icons/icon-96.png', sizes: '96x96', type: 'image/png' },
69-
{ url: '/favicon.svg', type: 'image/svg+xml' },
73+
{ url: '/icons/icon-192.png', sizes: '192x192', type: 'image/png' },
74+
{ url: '/icons/icon-256.png', sizes: '256x256', type: 'image/png' },
75+
{ url: '/icons/icon-512.png', sizes: '512x512', type: 'image/png' },
7076
],
7177
shortcut: '/favicon.ico',
7278
apple: '/apple-touch-icon.png',
7379
},
7480
manifest: '/manifest.webmanifest',
75-
category: 'technology',
7681
};
7782

7883
// Viewport
7984
export const viewport = {
8085
themeColor: [
81-
{ media: '(prefers-color-scheme: light)', color: '#FFFFFF' }, // TODO: does this work?
86+
{ media: '(prefers-color-scheme: light)', color: '#FFFFFF' },
8287
{ media: '(prefers-color-scheme: dark)', color: '#09090B' },
8388
],
8489
width: 'device-width',
8590
initialScale: 1,
86-
maximumScale: 1,
8791
};
8892

8993
// Root Layout
@@ -93,7 +97,7 @@ export default async function RootLayout({ children }) {
9397
return (
9498
<html lang='en' suppressHydrationWarning>
9599
<body className={`${inter.className} antialiased`}>
96-
<SessionProvider session={ session }>
100+
<SessionProvider session={session}>
97101
<ThemeProvider attribute='class' defaultTheme='system' enableSystem disableTransitionOnChange>
98102
<PushNotificationProvider>
99103
<div className='flex min-h-screen flex-col'>
@@ -103,13 +107,13 @@ export default async function RootLayout({ children }) {
103107
/>
104108
<main className='flex flex-col h-full grow items-center p-8 md:p-12'>
105109
<div className='container flex flex-col items-center gap-6 text-center grow relative'>
106-
{ children }
110+
{children}
107111
</div>
108112
</main>
109-
<Footer author={ siteConfig.author } github={ siteConfig.links.github } />
113+
<Footer author={siteConfig.author} github={siteConfig.links.github} />
110114
</div>
111-
{ session && <PushNotificationToggle vapidPublicKey={process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY || ''} /> }
112-
{ session && <AddToHomeScreen /> }
115+
{session && <PushNotificationToggle vapidPublicKey={process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY || ''} />}
116+
{session && <AddToHomeScreen />}
113117
</PushNotificationProvider>
114118
<Toaster richColors closeButton />
115119
<CookieConsent />

src/app/terms-of-service/terms-of-service.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import Link from 'next/link';
44
import { Card, CardContent } from '@/components/ui/card';
5+
import { siteConfig } from '@/components/config';
56

67
export const TermsOfService = () => {
78
return (
@@ -17,14 +18,14 @@ export const TermsOfService = () => {
1718

1819
<section className='space-y-4'>
1920
<p>
20-
Welcome to the Wapy.dev website (the "Site"). By accessing or using the Site, you agree to comply with and be bound by the following terms and conditions ("Terms of Service").
21+
Welcome to the {siteConfig.name} website (the "Site"). By accessing or using the Site, you agree to comply with and be bound by the following terms and conditions ("Terms of Service").
2122
</p>
2223
</section>
2324

2425
<section className='space-y-4'>
2526
<h2 className='text-2xl font-semibold'>Overview</h2>
2627
<p>
27-
Wapy.dev offers this Site, including all information, tools, and services available from this Site to you, the user, conditioned upon your acceptance of all terms, conditions, policies, and notices stated here.
28+
{siteConfig.name} offers this Site, including all information, tools, and services available from this Site to you, the user, conditioned upon your acceptance of all terms, conditions, policies, and notices stated here.
2829
</p>
2930
<p>
3031
Please read these Terms of Service carefully before accessing or using the Site. By accessing or using any part of the Site, you agree to be bound by these Terms of Service. If you do not agree to all the terms and conditions of this agreement, then you may not access the Site or use any services. If these Terms of Service are considered an offer, acceptance is expressly limited to these Terms of Service.
@@ -89,7 +90,7 @@ export const TermsOfService = () => {
8990
<section className='space-y-4'>
9091
<h2 className='text-2xl font-semibold'>Limitation of Liability</h2>
9192
<p>
92-
Wapy.dev shall not be held responsible for any indirect, incidental, special, or consequential damages that may occur from your use of the Site, regardless of whether such damages arise from contract, tort, negligence, strict liability, or any other legal theory. The maximum amount Site may be liable for in any claim related to the Site is limited to the total subscription fees you have paid in the last 12 months.
93+
{siteConfig.name} shall not be held responsible for any indirect, incidental, special, or consequential damages that may occur from your use of the Site, regardless of whether such damages arise from contract, tort, negligence, strict liability, or any other legal theory. The maximum amount Site may be liable for in any claim related to the Site is limited to the total subscription fees you have paid in the last 12 months.
9394
</p>
9495
</section>
9596

@@ -103,7 +104,7 @@ export const TermsOfService = () => {
103104
<section className='space-y-4'>
104105
<h2 className='text-2xl font-semibold'>Indemnification</h2>
105106
<p>
106-
You agree to indemnify and hold harmless Wapy.dev, its affiliates, officers, directors, employees, agents, and licensors from and against any claims, liabilities, damages, losses, and expenses, including without limitation reasonable attorney&apos;s fees, arising out of or in connection with your use of the Site, your violation of these Terms of Service, or your violation of any rights of another party.
107+
You agree to indemnify and hold harmless {siteConfig.name}, its affiliates, officers, directors, employees, agents, and licensors from and against any claims, liabilities, damages, losses, and expenses, including without limitation reasonable attorney&apos;s fees, arising out of or in connection with your use of the Site, your violation of these Terms of Service, or your violation of any rights of another party.
107108
</p>
108109
</section>
109110

@@ -120,14 +121,14 @@ export const TermsOfService = () => {
120121
<section className='space-y-4'>
121122
<h2 className='text-2xl font-semibold'>Governing Law and Jurisdiction</h2>
122123
<p>
123-
These Terms of Service shall be governed by and construed in accordance with the laws of the jurisdiction where Wapy.dev is headquartered without giving effect to any principles of conflicts of law. You agree to submit to the exclusive jurisdiction of the courts in that jurisdiction for any disputes arising out of or in connection with these Terms of Service or your use of the Site.
124+
These Terms of Service shall be governed by and construed in accordance with the laws of the jurisdiction where {siteConfig.name} is headquartered without giving effect to any principles of conflicts of law. You agree to submit to the exclusive jurisdiction of the courts in that jurisdiction for any disputes arising out of or in connection with these Terms of Service or your use of the Site.
124125
</p>
125126
</section>
126127

127128
<section className='space-y-4'>
128129
<h2 className='text-2xl font-semibold'>Entire Agreement</h2>
129130
<p>
130-
These Terms of Service constitute the entire agreement between you and Wapy.dev regarding your use of the Site and supersede all prior and contemporaneous agreements and understandings, whether oral or written, relating to the same subject matter.
131+
These Terms of Service constitute the entire agreement between you and {siteConfig.name} regarding your use of the Site and supersede all prior and contemporaneous agreements and understandings, whether oral or written, relating to the same subject matter.
131132
</p>
132133
</section>
133134

@@ -141,7 +142,7 @@ export const TermsOfService = () => {
141142
<section className='space-y-4'>
142143
<h2 className='text-2xl font-semibold'>Waiver</h2>
143144
<p>
144-
The failure of Wapy.dev to enforce any right or provision of these Terms of Service shall not constitute a waiver of that right or provision.
145+
The failure of {siteConfig.name} to enforce any right or provision of these Terms of Service shall not constitute a waiver of that right or provision.
145146
</p>
146147
</section>
147148

src/components/config.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
export const siteConfig = {
22
name: 'Wapy.dev',
33
title: 'Wapy.dev - Subscription Manager',
4-
description: 'Track, manage, and optimize your subscriptions and recurring expenses in one powerful and human readable dashboard. Get notified and never miss a payment again.',
5-
keywords: 'subscription, expense, tracker, wapy, meceware',
4+
description: 'Effortlessly track and manage all your subscriptions and recurring expenses in a powerful, easy-to-read dashboard. Know exactly what you\'re spending and get timely notifications to ensure you never miss a payment.',
5+
keywords: 'subscription tracker, subscription management, recurring payments, expense tracker, manage subscriptions, budgeting tools, personal finance tracker, track my subscriptions, expense management, subscription monitoring, money-saving tools, wapy, meceware',
66
url: process.env.SITE_URL || 'http://localhost:3000',
77
links: {
88
github: 'https://github.com/meceware/wapy.dev',

src/components/footer.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
DropdownMenuItem,
1010
DropdownMenuTrigger,
1111
} from '@/components/ui/dropdown-menu';
12-
import { Button } from '@/components/ui/button';
1312

1413
export default function Footer( { author, github } ) {
1514
return (
@@ -39,7 +38,7 @@ export default function Footer( { author, github } ) {
3938
<Separator orientation='vertical' className='h-4' />
4039
<DropdownMenu>
4140
<DropdownMenuTrigger asChild>
42-
<button className='inline-flex items-center gap-1 text-sm text-center font-medium focus:outline-hidden'>
41+
<button className='inline-flex items-center gap-1 text-sm text-center font-medium focus:outline-hidden cursor-pointer'>
4342
<Icons.menu className='size-4' />
4443
Menu
4544
</button>

src/components/header-member.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const HeaderMemberIconNavigation = (
4141
<Icons.settings className='size-5' />
4242
</Link>
4343
</Button>
44-
<Button variant='ghost' size='icon' title='Sign out' onClick={() => signOut({ callbackUrl: '/' })} className='hidden md:flex'>
44+
<Button variant='ghost' size='icon' title='Sign out' onClick={() => signOut({ callbackUrl: '/' })} className='hidden md:flex cursor-pointer'>
4545
<Icons.signOut className='size-5' />
4646
</Button>
4747

@@ -75,7 +75,7 @@ export const HeaderMemberIconNavigation = (
7575
<DropdownMenuItem asChild>
7676
<Link href='/' className='flex items-center gap-2 cursor-pointer focus:outline-hidden'>
7777
<Icons.send className='size-5' />
78-
Contact
78+
Contact Us
7979
</Link>
8080
</DropdownMenuItem>
8181
<DropdownMenuItem onClick={() => signOut({ callbackUrl: '/' })} className='flex items-center gap-2 cursor-pointer'>

src/components/header-visitor.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export const HeaderVisitorIconNavigation = (
6363
<DropdownMenuItem asChild>
6464
<Link href='/' className='flex items-center gap-2 cursor-pointer focus:outline-hidden'>
6565
<Icons.send className='size-5' />
66-
Contact
66+
Contact Us
6767
</Link>
6868
</DropdownMenuItem>
6969
</DropdownMenuContent>

src/components/notifications/notification-bell.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export function NotificationBell() {
5757
return (
5858
<Popover open={open} onOpenChange={setOpen}>
5959
<PopoverTrigger asChild>
60-
<Button variant='ghost' size='icon' className='relative'>
60+
<Button variant='ghost' size='icon' className='relative cursor-pointer'>
6161
<Bell className='h-5 w-5' />
6262
{unreadCount > 0 && (
6363
<span

src/components/#-table.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
CardHeader,
1212
CardTitle,
1313
} from '@/components/ui/card';
14+
import { siteConfig } from '@/components/config';
1415

1516
export const #Table = () => {
1617
return (
@@ -81,7 +82,7 @@ export const #Table = () => {
8182
</CardContent>
8283
<CardFooter className='flex justify-center items-end'>
8384
<Button variant='outline' size='lg' className='w-full' asChild>
84-
<Link href='https://github.com/meceware/wapy.dev' target='_blank' rel='noopener noreferrer'>
85+
<Link href={siteConfig.links.github} target='_blank' rel='noopener noreferrer'>
8586
<Icons.github className='mr-2 h-4 w-4' />
8687
View on GitHub
8788
</Link>

0 commit comments

Comments
 (0)