Skip to content

Commit 4426d62

Browse files
committed
seo
1 parent cd7f8d0 commit 4426d62

16 files changed

+225
-61
lines changed

components/Navbar.js

+5-10
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,14 @@ function Navbar() {
2727
{auth?.user ? (
2828
<ul className="max-w-full h-full flex items-center justify-center">
2929
<li>
30-
<button
31-
className="px-4 py-2 mx-4"
32-
onClick={(e) => auth.signout()}
33-
>
34-
Log out
35-
</button>
36-
</li>
37-
<li className="mx-4 hidden sm:block">
38-
<div>{auth.user ? auth.user.email : "None"}</div>
30+
<Link className="cursor-pointer px-4 py-2 mx-4" href={"/account"}>
31+
{auth.user ? auth.user.email : "None"}
32+
</Link>
3933
</li>
34+
4035
<li>
4136
<img
42-
className="rounded-full mx-4 w-12 border-black border-2 dark:border-white"
37+
className=" rounded-full mx-4 w-12 border-black border-2 dark:border-white"
4338
src={auth.user.photoUrl}
4439
></img>
4540
</li>

components/Page.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from "react";
2+
import { NextSeo } from "next-seo";
3+
4+
const Page = ({ name, path, children }) => {
5+
const title = `Feedback na web – ${name}`;
6+
const url = `https://website-review.vercel.app/${path}`;
7+
console.log(title);
8+
9+
return (
10+
<>
11+
<NextSeo
12+
title={title}
13+
canonical={url}
14+
openGraph={{
15+
url,
16+
title,
17+
}}
18+
/>
19+
{children}
20+
</>
21+
);
22+
};
23+
24+
export default Page;

components/skeletons/FreePlanEmptyState.js

-17
This file was deleted.
+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import Box from "@/components/Box";
2+
import { useAuth } from "@/lib/auth";
3+
import { createCheckoutSession } from "@/lib/db";
4+
import React, { useState } from "react";
5+
6+
import DashboardShell from "@/components/DashboardShell";
7+
8+
const UpgradeEmptyState = () => {
9+
const { user } = useAuth();
10+
const [isCheckoutLoading, setCheckoutLoading] = useState(false);
11+
12+
return (
13+
<DashboardShell>
14+
<Box className="w-full bg-white p-4 justify-items-center align-center ">
15+
<h2>Jste ve free tieru</h2>
16+
<p>Pojďme na to!</p>
17+
<button
18+
className="bg-white text-black active:bg-pink-600 border-2 border-black dark:border-white dark:bg-black dark:text-white px-6 py-3 outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
19+
onClick={() => {
20+
setCheckoutLoading(true);
21+
createCheckoutSession(user.uid);
22+
}}
23+
>
24+
{isCheckoutLoading ? (
25+
<div className="flex items-center">
26+
<svg
27+
xmlns="http://www.w3.org/2000/svg"
28+
width="24"
29+
height="24"
30+
viewBox="0 0 24 24"
31+
className="animate-spin h-5 w-5 mr-3 fill-current"
32+
>
33+
<path d="M2 11H7V13H2zM17 11H22V13H17zM11 17H13V22H11zM11 2H13V7H11z"></path>
34+
<path
35+
transform="rotate(-45.001 6.697 6.697)"
36+
d="M5.697 4.197H7.697V9.197H5.697z"
37+
></path>
38+
<path
39+
transform="rotate(134.999 17.303 17.303)"
40+
d="M16.303 14.803H18.303V19.803H16.303z"
41+
></path>
42+
<path
43+
transform="rotate(45.001 6.697 17.303)"
44+
d="M5.697 14.803H7.697V19.803H5.697z"
45+
></path>
46+
<path
47+
transform="rotate(-44.992 17.303 6.697)"
48+
d="M14.803 5.697H19.803V7.697H14.803z"
49+
></path>
50+
</svg>
51+
<p>Načíta se</p>
52+
</div>
53+
) : (
54+
<div className="flex items-center">
55+
<p>Uprgadovat na startovač</p>
56+
</div>
57+
)}
58+
</button>
59+
</Box>
60+
</DashboardShell>
61+
);
62+
};
63+
export default UpgradeEmptyState;

lib/auth.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,16 @@ function useProvideAuth() {
2121
const handleUser = async (rawUser) => {
2222
if (rawUser) {
2323
const user = await formatUser(rawUser);
24+
2425
const { token, ...userWithoutToken } = user;
26+
2527
createUser(user.uid, userWithoutToken);
28+
2629
setUser(user);
2730
cookie.set("weback-web-feedback-auth", true, {
2831
expires: 1,
2932
});
33+
3034
return user;
3135
} else {
3236
setUser(false);
@@ -75,7 +79,7 @@ function useProvideAuth() {
7579
};
7680
}
7781
const formatUser = async (user) => {
78-
const token = await user.getIdToken();
82+
const { token, claims } = await user.getIdTokenResult();
7983

8084
return {
8185
uid: user.uid,
@@ -84,5 +88,6 @@ const formatUser = async (user) => {
8488
provider: user.providerData[0].providerId,
8589
photoUrl: user.photoURL,
8690
token,
91+
stripeRole: claims.stripeRole || "free",
8792
};
8893
};

lib/db.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ export async function goToBillingPortal() {
4848
.app()
4949
.functions("europe-west3")
5050
.httpsCallable("ext-firestore-stripe-subscriptions-createPortalLink");
51-
const { data } = await functionRef({ returnUrl: window.location.origin });
51+
const { data } = await functionRef({
52+
returnUrl: `${window.location.origin}/account`,
53+
});
5254

5355
window.location.assign(data.url);
5456
}

lib/rollbar.js

Whitespace-only changes.

next-seo.config.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const title = "Feedback na web – Nejednduší cesta, jak získat rychle feedback.";
2+
const description =
3+
"Feedback na web je aplikace vytvořena Adamem Treterou jako JAM stack";
4+
5+
const SEO = {
6+
title,
7+
description,
8+
canonical: "https://website-review.vercel.app/",
9+
openGraph: {
10+
type: "website",
11+
locale: "cs-CZ",
12+
url: "https://website-review.vercel.app/",
13+
title,
14+
description,
15+
images: [
16+
{
17+
url: "https://website-review.vercel.app/",
18+
alt: title,
19+
width: 1280,
20+
height: 720,
21+
},
22+
],
23+
},
24+
};
25+
26+
export default SEO;

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"firebase-admin": "^9.6.0",
1515
"js-cookie": "^2.2.1",
1616
"next": "^10.1.3",
17+
"next-seo": "^4.23.0",
1718
"next-themes": "0.0.14",
1819
"pino": "^6.11.2",
1920
"pino-logflare": "^0.3.8",

pages/_app.js

+5
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ import { AuthProvider } from "@/lib/auth";
44
import { ThemeProvider } from "next-themes";
55
import { Toaster } from "react-hot-toast";
66

7+
import SEO from "../next-seo.config";
8+
import { DefaultSeo } from "next-seo";
9+
710
function MyApp({ Component, pageProps }) {
811
return (
912
<AuthProvider>
13+
<DefaultSeo {...SEO} />
14+
1015
<ThemeProvider
1116
forcedTheme={Component.theme || undefined}
1217
attribute="class"

pages/account.js

+58-24
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
11
import { useState } from "react";
2+
import Page from "@/components/Page";
23

34
import { useAuth } from "@/lib/auth";
4-
import { createCheckoutSession, goToBillingPortal } from "@/lib/db";
5+
import { goToBillingPortal } from "@/lib/db";
56
import DashboardShell from "@/components/DashboardShell";
67
import Box from "@/components/Box";
8+
const SettingsTable = ({ stripeRole, children }) => (
9+
<div className="mt-5">
10+
<div className="flex justify-between">
11+
<h4 className="text-lg">Nastavení</h4>
12+
<span className="text-lg font-bold">Předplatné: {stripeRole}</span>
13+
</div>
14+
<div className="flex p-4 pt-0">{children}</div>
15+
</div>
16+
);
17+
const FeedbackUsage = () => (
18+
<section className="grid grid-cols-2 text-left gap-6">
19+
<div className="w-full col-span-2 sm:col-span-1 p-6 border-2 border-black dark:border-white">
20+
<h4 className="font-bold text-lg">Feedback</h4>
21+
<p className="text-lg"></p>
22+
<p className="text-lg ">10,000 limit</p>
23+
</div>
24+
<div className="w-full col-span-2 sm:col-span-1 p-6 border-2 border-black dark:border-white">
25+
<h4 className="font-bold text-lg">Feedback</h4>
26+
<p className="text-lg"></p>
27+
<p className="text-lg">10,000 limit</p>
28+
</div>
29+
</section>
30+
);
731

832
const Account = () => {
933
const { user, signout } = useAuth();
@@ -13,16 +37,34 @@ const Account = () => {
1337
return (
1438
<DashboardShell>
1539
<Box>
40+
<div className="block m-auto text-center">
41+
<img
42+
className="w-32 rounded-full border-2 border-black dark:border-white m-auto"
43+
src={user ? user.photoUrl : "null"}
44+
/>
45+
<h1 className="font-bold text-2xl mt-2">
46+
{user ? user.name : "None"}
47+
</h1>
48+
<h3> {user ? user.email : "None"}</h3>
49+
<SettingsTable stripeRole={user?.stripeRole} />
50+
<FeedbackUsage />
51+
<p className="text-md text-left pt-6">
52+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
53+
Pellentesque pretium lectus id turpis. Duis risus. Aliquam erat
54+
volutpat. Nullam feugiat, turpis at pulvinar vulputate, erat libero
55+
tristique tellus, nec bibendum odio risus sit amet ante.
56+
</p>
57+
</div>
58+
</Box>
59+
<div className="flex justify-end mt-4">
1660
<button
1761
className=" bg-white text-black active:bg-pink-600 border-2 border-black dark:border-white dark:bg-black dark:text-white px-6 py-3 outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
18-
type="button"
1962
onClick={() => {
20-
setCheckoutLoading(true);
21-
createCheckoutSession(user.uid);
63+
setBillingLoading(true);
64+
goToBillingPortal();
2265
}}
2366
>
24-
{" "}
25-
{isCheckoutLoading ? (
67+
{isBillingLoading ? (
2668
<div className="flex items-center">
2769
<svg
2870
xmlns="http://www.w3.org/2000/svg"
@@ -53,32 +95,24 @@ const Account = () => {
5395
</div>
5496
) : (
5597
<div className="flex items-center">
56-
<svg
57-
xmlns="http://www.w3.org/2000/svg"
58-
width="24"
59-
height="24"
60-
viewBox="0 0 24 24"
61-
className="h-5 w-5 mr-3 fill-current"
62-
>
63-
<path d="M3.414,13.778L2,15.192l4.949,2.121l2.122,4.95l1.414-1.414l-0.707-3.536l3.313-3.313l3.61,7.704l1.339-1.339l-1.19-10.123 l2.828-2.829c0.781-0.781,0.781-2.047,0-2.828c-0.781-0.781-2.048-0.781-2.828,0l-2.903,2.903L3.824,6.297L2.559,7.563l7.644,3.67 l-3.253,3.253L3.414,13.778z"></path>
64-
</svg>
65-
<p>Upgradovat plán na startovač</p>
98+
<p>Nastavení platby</p>
6699
</div>
67100
)}
68101
</button>
69102
<button
70103
className=" bg-white text-black active:bg-pink-600 border-2 border-black dark:border-white dark:bg-black dark:text-white px-6 py-3 outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
71-
onClick={() => {
72-
setBillingLoading(true);
73-
goToBillingPortal();
74-
}}
104+
onClick={() => signout()}
75105
>
76-
View Billing Portal
106+
Odhlásit
77107
</button>
78-
<button onClick={() => signout()}>Log Out</button>
79-
</Box>
108+
</div>
80109
</DashboardShell>
81110
);
82111
};
112+
const AccountPage = () => (
113+
<Page name="Účet" path="/account">
114+
<Account />
115+
</Page>
116+
);
83117

84-
export default Account;
118+
export default AccountPage;

pages/api/sites.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default async (req, res) => {
66
const { uid } = await auth.verifyIdToken(req.headers.token);
77
const { sites } = await getUserSites(uid);
88

9-
res.status(200).json({ sites });
9+
res.status(200).json({ sites: [] });
1010
} catch (error) {
1111
logger.error(
1212
{

0 commit comments

Comments
 (0)