Compare commits

...

36 Commits

Author SHA1 Message Date
Daniel 501e9e59e0 Merge pull request #104 from linkwarden/dev
Updated the dependencies
2023-08-01 22:23:57 -04:00
Daniel ffb1098a15 Merge pull request #71 from linkwarden/dependabot/npm_and_yarn/dev/next-13.4.12
Bump next from 13.1.6 to 13.4.12
2023-08-01 22:16:14 -04:00
Daniel 808ed9b15b Merge pull request #87 from linkwarden/dependabot/npm_and_yarn/dev/react-select-5.7.4
Bump react-select from 5.7.3 to 5.7.4
2023-08-01 22:13:35 -04:00
dependabot[bot] 232c95937d Bump next from 13.1.6 to 13.4.12
Bumps [next](https://github.com/vercel/next.js) from 13.1.6 to 13.4.12.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v13.1.6...v13.4.12)

---
updated-dependencies:
- dependency-name: next
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-02 02:08:13 +00:00
Daniel 857117dc0f Merge pull request #88 from linkwarden/dependabot/npm_and_yarn/dev/eslint-8.46.0
Bump eslint from 8.44.0 to 8.46.0
2023-08-01 22:08:13 -04:00
dependabot[bot] 2f0c2f2999 Bump eslint from 8.44.0 to 8.46.0
Bumps [eslint](https://github.com/eslint/eslint) from 8.44.0 to 8.46.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.44.0...v8.46.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-02 02:05:19 +00:00
Daniel 1fc0804cbf error handling missing avatar 2023-08-01 22:03:49 -04:00
Daniel 4c28e211ec Merge pull request #103 from linkwarden/dependabot/npm_and_yarn/dev/prisma-5.1.0
Bump prisma from 4.16.2 to 5.1.0
2023-08-01 19:44:52 -04:00
dependabot[bot] c29219c492 Bump prisma from 4.16.2 to 5.1.0
Bumps [prisma](https://github.com/prisma/prisma/tree/HEAD/packages/cli) from 4.16.2 to 5.1.0.
- [Release notes](https://github.com/prisma/prisma/releases)
- [Commits](https://github.com/prisma/prisma/commits/5.1.0/packages/cli)

---
updated-dependencies:
- dependency-name: prisma
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-01 23:36:44 +00:00
Daniel e22362808e Merge pull request #89 from linkwarden/dependabot/npm_and_yarn/dev/aws-sdk/client-s3-3.379.1
Bump @aws-sdk/client-s3 from 3.363.0 to 3.379.1
2023-08-01 19:32:44 -04:00
Daniel 94a6212caa Merge pull request #102 from linkwarden/dev
eslint fix
2023-08-01 16:32:11 -04:00
Daniel 46c897545f eslint fix 2023-08-01 16:31:30 -04:00
Daniel 86c839e7fe Merge pull request #101 from linkwarden/dev
better layout + improvements
2023-08-01 16:21:55 -04:00
Daniel 8c49b33154 better layout + improvements 2023-08-01 16:20:05 -04:00
Daniel cacbd7b400 Merge pull request #96 from linkwarden/dev
Update README.md
2023-08-01 00:51:14 -04:00
Daniel dc86c5487a Update README.md 2023-08-01 00:50:28 -04:00
Daniel a3dd3660b4 Merge pull request #95 from linkwarden/dev
Dev
2023-08-01 00:35:17 -04:00
Daniel d81ecf039b Delete CONTRIBUTING.md 2023-08-01 00:33:10 -04:00
Daniel 00c4a01f53 Merge pull request #93 from linkwarden/main
Main
2023-07-31 12:10:19 -04:00
Daniel 7d388e50f6 Merge pull request #92 from linkwarden/daniel31x13-patch-1
Update README.md
2023-07-31 12:09:34 -04:00
Daniel cbbc30f8b9 Update README.md 2023-07-31 12:09:24 -04:00
Daniel 80c11abb7f Merge pull request #91 from linkwarden/dev
Update README.md
2023-07-31 10:44:09 -04:00
Daniel e8709d8f23 Update README.md 2023-07-31 10:43:55 -04:00
Daniel 9ae3322224 Merge pull request #90 from linkwarden/dev
Dev
2023-07-31 09:38:23 -04:00
Daniel 880577f524 updated README screenshots 2023-07-31 08:44:13 -04:00
Daniel 94e4b58341 improved README.md 2023-07-31 08:08:52 -04:00
Daniel 1911571219 Update README.md 2023-07-31 06:52:27 -04:00
Daniel c46de09bb5 small change in README.md file 2023-07-31 02:22:47 -04:00
Daniel a3c2c78bc5 minor change in README.md file 2023-07-31 02:19:49 -04:00
Daniel d87715e759 minor improvement 2023-07-31 02:17:48 -04:00
Daniel deeaa6884a fixed minor typo 2023-07-31 02:12:25 -04:00
Daniel 0940396b2e fixed typos + changes to the readme file 2023-07-31 02:07:48 -04:00
Daniel 923750a6f7 minor fix 2023-07-31 01:56:33 -04:00
Daniel 4de6db7720 updated README.md 2023-07-31 01:54:53 -04:00
dependabot[bot] 657147a9bd Bump @aws-sdk/client-s3 from 3.363.0 to 3.379.1
Bumps [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) from 3.363.0 to 3.379.1.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.379.1/clients/client-s3)

---
updated-dependencies:
- dependency-name: "@aws-sdk/client-s3"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-31 04:34:20 +00:00
dependabot[bot] 14e9e9ef1c Bump react-select from 5.7.3 to 5.7.4
Bumps [react-select](https://github.com/JedWatson/react-select) from 5.7.3 to 5.7.4.
- [Release notes](https://github.com/JedWatson/react-select/releases)
- [Changelog](https://github.com/JedWatson/react-select/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/JedWatson/react-select/compare/react-select@5.7.3...react-select@5.7.4)

---
updated-dependencies:
- dependency-name: react-select
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-31 04:28:27 +00:00
19 changed files with 1077 additions and 996 deletions
-17
View File
@@ -1,17 +0,0 @@
# How to contribute
> **For questions/help, feature requests and bug reports please create an [issue](https://github.com/Daniel31x13/link-warden/issues) (please use the right lable).**
First off, I'm really glad you're reading this and thank you for taking the time to contribute!
1. Confirm your planned implementation fit into our project [features](https://github.com/Daniel31x13/link-warden#features) and [project roadmap](https://github.com/Daniel31x13/link-warden/wiki#project-roadmap) (wether it's adding a new feature or improving our existing code).
2. Open an [issue](https://github.com/Daniel31x13/link-warden/issues/new?assignees=&labels=contribution&template=contribution.md&title=Contribution) with your planned implementation to discuss.
3. Check in with me before starting development to make sure your work wont conflict with or duplicate existing work (by doing step 2).
4. Commit, push, and submit a PR and wait for review feedback.
5. Have patience, don't abandon your PR! We love contributors but we don't always have time to respond to notifications instantly. If you want a faster response, DM me on [Twitter](https://twitter.com/daniel31x13).
Thanks again! <3
+90 -8
View File
@@ -1,13 +1,95 @@
<div align="center">
<h1>
Linkwarden
</h1>
<h3>Collect, Organize, and Preserve Links with Seamless Collaboration!</h3>
<img src="./assets/icon.png" width="100px" />
<h1>Linkwarden</h1>
Rebuilding things from ground up (Almost ready).
<a href="https://discord.com/invite/CtuYV47nuJ"><img src="https://img.shields.io/discord/1117993124669702164?logo=discord&style=flat-square" alt="Discord"></a>
<img src="https://img.shields.io/github/commit-activity/m/linkwarden/linkwarden?style=flat-square" alt="Github Activity">
<img src="https://img.shields.io/github/languages/top/linkwarden/linkwarden?style=flat-square" alt="Top Language">
<img src="https://img.shields.io/github/stars/linkwarden/linkwarden?style=flat-square" alt="Github Stars">
To get a better sense at what this repository is all about, you can check out the old version *[here](https://github.com/linkwarden/linkwarden-old)*.
<h3>Thanks for your patience!</h3>
</div>
<div align='center'>
[Homepage](https://linkwarden.app) | [Getting Started](https://docs.linkwarden.app/getting-started) | [Features](https://github.com/linkwarden/linkwarden#features) | [Roadmap](https://github.com/linkwarden/linkwarden#roadmap) | [Screenshots](https://github.com/linkwarden/linkwarden#screenshots) | [Support ❤](https://github.com/linkwarden/linkwarden#support-)
</div>
## Intro & motivation
**Linkwarden is a self-hosted, open-source collaborative bookmark manager to collect, organize and archive webpages.** The objective is to organize useful webpages and articles you find across the web in one place, and since useful webpages can go away (see the inevitability of [Link Rot](https://www.howtogeek.com/786227/what-is-link-rot-and-how-does-it-threaten-the-web/)), Linkwarden also saves a copy of each webpage as a Screenshot and PDF, ensuring accessibility even if the original content is no longer available.
Additionally, Linkwarden is designed with collaboration in mind, sharing links with the public and/or allowing multiple users to work together seamlessly.
<img src="./assets/showcase_image.png" />
<details>
<summary><b>A bit of a "history"</b></summary>
Linkwarden has been completely rebuilt and redesigned from ground up, so pretty much the only thing it has in common with its predecessor is the idea behind it - bookmark management.
**What happened to the old version?**
We highly recommend you **not** to use the old version as it is no longer maintained and has much less features. But anyway if you really wanna check it out, here it is in [this repo](https://github.com/linkwarden/linkwarden-old).
</details>
## Main Tech Stack
- NextJS
- TypeScript
- Tailwind
- Prisma
- Zustand
## Features
- ✅ Auto capture a screenshot and a PDF of each link.
- ✅ Organize links by collection, name, description and multiple tags.
- ✅ Collaborate on gathering links in a collection.
- ✅ Customize the permissions of each member.
- ✅ Share your collected links with the world.
- ✅ Search, filter and sort by link details.
- ✅ Responsive design and supports most browsers.
## Roadmap
There are _many_ upcoming features, below are only _some_ of the 100% planned ones:
- 🐳 Docker version.
- 🌒 Dark mode.
- 📦 Import/Export your data.
- 🧩 Browser extention.
Also make sure to check out our [public roadmap](https://github.com/orgs/linkwarden/projects/1).
## Docs
Currently, the Documentation is a bit targeted towards a more tech-savvy audience and has so much room to improve, you can find it [here](https://docs.linkwarden.app).
## Development
If you want to contribute, Thanks! Start by checking our [public roadmap](https://github.com/orgs/linkwarden/projects/1), there you'll see a [readme item for contributers](https://github.com/orgs/linkwarden/projects/1?pane=issue&itemId=34708277) for the rest of the info on how to contribute to this repo.
## Security
If you found a security vulnerability, please do **not** create a public issue, instead send an email to [security@linkwarden.app](mailto:security@linkwarden.app) stating the vulnerability. Thanks!
## Screenshots
<img src="./assets/collections.png" />
<img src="./assets/collaborators.png" />
<img src="./assets/link_details.png" />
## Support ❤
Any [donations](https://opencollective.com/linkwarden) are highly appreciated. <3
Here are the other ways to support/cheer this project:
- Starring this repo.
- Joining us on [Discord](https://discord.com/invite/CtuYV47nuJ).
- Following @daniel31x13 on [Mastodon](https://mastodon.social/@daniel31x13), [Twitter](https://twitter.com/daniel31x13) and [GitHub](https://github.com/daniel31x13).
- Referring Linkwarden to a friend.
If you did any of the above, Thanksss! Otherwise thanks.
Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

+2 -2
View File
@@ -11,10 +11,10 @@ type Props = {
export default function Modal({ toggleModal, className, children }: Props) {
return (
<div className="overflow-y-auto py-2 fixed top-0 bottom-0 right-0 left-0 bg-gray-500 bg-opacity-10 backdrop-blur-sm flex items-center fade-in z-30">
<div className="overflow-y-auto py-2 fixed top-0 bottom-0 right-0 left-0 bg-gray-500 bg-opacity-10 backdrop-blur-sm flex justify-center items-center fade-in z-30">
<ClickAwayHandler
onClickOutside={toggleModal}
className={`w-fit m-auto mt-10 sm:mt-20 ${className}`}
className={`m-auto ${className}`}
>
<div className="slide-up relative border-sky-100 rounded-2xl border-solid border shadow-lg p-5 bg-white">
<div
+1 -1
View File
@@ -13,7 +13,7 @@ export default function useInitialData() {
const { setAccount } = useAccountStore();
useEffect(() => {
if (status === "authenticated") {
if (status === "authenticated" && data.user.isSubscriber) {
setCollections();
setTags();
// setLinks();
+32
View File
@@ -0,0 +1,32 @@
import Image from "next/image";
import React, { ReactNode } from "react";
interface Props {
text?: string;
children: ReactNode;
}
export default function CenteredForm({ text, children }: Props) {
return (
<div className="absolute top-0 bottom-0 left-0 right-0 flex justify-center items-center p-2">
<div className="m-auto flex flex-col gap-2">
<Image
src="/linkwarden.png"
width={518}
height={145}
alt="Linkwarden"
className="h-12 w-fit mx-auto"
/>
{text ? (
<p className="text-lg sm:w-[30rem] w-80 mx-auto font-semibold text-black px-2 text-center">
{text}
</p>
) : undefined}
{children}
<p className="text-center text-xs text-gray-500">
© {new Date().getFullYear()} Linkwarden. All rights reserved.
</p>
</div>
</div>
);
}
+52 -19
View File
@@ -1,14 +1,21 @@
import { GetObjectCommand, GetObjectCommandInput } from "@aws-sdk/client-s3";
import {
GetObjectCommand,
GetObjectCommandInput,
S3,
} from "@aws-sdk/client-s3";
import fs from "fs";
import path from "path";
import s3Client from "./s3Client";
import util from "util";
type ReturnContentTypes =
| "text/plain"
| "image/jpeg"
| "image/png"
| "application/pdf";
export default async function readFile({ filePath }: { filePath: string }) {
let contentType:
| "text/plain"
| "image/jpeg"
| "image/png"
| "application/pdf";
let contentType: ReturnContentTypes;
if (s3Client) {
const bucketParams: GetObjectCommandInput = {
@@ -17,26 +24,52 @@ export default async function readFile({ filePath }: { filePath: string }) {
};
try {
const response = await s3Client.send(new GetObjectCommand(bucketParams));
const data = await streamToBuffer(response.Body);
let returnObject:
| {
file: Buffer | string;
contentType: ReturnContentTypes;
}
| undefined;
if (filePath.endsWith(".pdf")) {
contentType = "application/pdf";
} else if (filePath.endsWith(".png")) {
contentType = "image/png";
} else {
// if (filePath.endsWith(".jpg"))
contentType = "image/jpeg";
const headObjectAsync = util.promisify(
s3Client.headObject.bind(s3Client)
);
try {
await headObjectAsync(bucketParams);
} catch (err) {
contentType = "text/plain";
returnObject = {
file: "File not found, it's possible that the file you're looking for either doesn't exist or hasn't been created yet.",
contentType,
};
}
return { file: data, contentType };
if (!returnObject) {
const response = await (s3Client as S3).send(
new GetObjectCommand(bucketParams)
);
const data = await streamToBuffer(response.Body);
if (filePath.endsWith(".pdf")) {
contentType = "application/pdf";
} else if (filePath.endsWith(".png")) {
contentType = "image/png";
} else {
// if (filePath.endsWith(".jpg"))
contentType = "image/jpeg";
}
returnObject = { file: data as Buffer, contentType };
}
return returnObject;
} catch (err) {
console.log("Error", err);
console.log("Error:", err);
contentType = "text/plain";
return {
file: "File not found, it's possible that the file you're looking for either doesn't exist or hasn't been created yet.",
file: "An internal occurred, please contact support.",
contentType,
};
}
+6 -5
View File
@@ -14,7 +14,7 @@
},
"dependencies": {
"@auth/prisma-adapter": "^1.0.1",
"@aws-sdk/client-s3": "^3.363.0",
"@aws-sdk/client-s3": "^3.379.1",
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-regular-svg-icons": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
@@ -31,9 +31,10 @@
"bcrypt": "^5.1.0",
"colorthief": "^2.4.0",
"crypto-js": "^4.1.1",
"eslint": "8.44.0",
"csstype": "^3.1.2",
"eslint": "8.46.0",
"eslint-config-next": "13.4.9",
"next": "13.1.6",
"next": "13.4.12",
"next-auth": "^4.22.1",
"nodemailer": "^6.9.3",
"playwright": "^1.35.1",
@@ -42,7 +43,7 @@
"react-dom": "18.2.0",
"react-hot-toast": "^2.4.1",
"react-image-file-resizer": "^0.4.8",
"react-select": "^5.7.3",
"react-select": "^5.7.4",
"sharp": "^0.32.1",
"stripe": "^12.13.0",
"typescript": "4.9.4",
@@ -53,7 +54,7 @@
"@types/bcrypt": "^5.0.0",
"autoprefixer": "^10.4.14",
"postcss": "^8.4.26",
"prisma": "^4.16.2",
"prisma": "^5.1.0",
"tailwindcss": "^3.3.3"
}
}
+5 -18
View File
@@ -6,6 +6,7 @@ import { toast } from "react-hot-toast";
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import useAccountStore from "@/store/account";
import CenteredForm from "@/layouts/CenteredForm";
export default function Subscribe() {
const [submitLoader, setSubmitLoader] = useState(false);
@@ -15,10 +16,6 @@ export default function Subscribe() {
const { updateAccount, account } = useAccountStore();
useEffect(() => {
console.log(data?.user);
}, [status]);
async function submitUsername() {
setSubmitLoader(true);
@@ -41,16 +38,9 @@ export default function Subscribe() {
}
return (
<>
<Image
src="/linkwarden.png"
width={518}
height={145}
alt="Linkwarden"
className="h-12 w-fit mx-auto mt-10"
/>
<div className="p-2 mt-10 mx-auto flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-md border border-sky-100">
<p className="text-xl text-sky-700 w-fit font-bold">
<CenteredForm>
<div className="p-2 mx-auto flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-2xl shadow-md border border-sky-100">
<p className="text-2xl text-center text-black font-bold">
Choose a Username (Last step)
</p>
@@ -91,9 +81,6 @@ export default function Subscribe() {
Sign Out
</div>
</div>
<p className="text-center text-xs text-gray-500 my-10">
© {new Date().getFullYear()} Linkwarden. All rights reserved.{" "}
</p>
</>
</CenteredForm>
);
}
+18 -16
View File
@@ -1,25 +1,27 @@
import { signIn } from "next-auth/react";
import CenteredForm from "@/layouts/CenteredForm";
import Link from "next/link";
import React from "react";
export default function EmailConfirmaion() {
return (
<div className="overflow-y-auto py-2 fixed top-0 bottom-0 right-0 left-0 bg-gray-500 bg-opacity-10 backdrop-blur-sm flex items-center fade-in z-30">
<div className="mx-auto p-3 text-center rounded-xl border border-sky-100 shadow-lg bg-gray-100 text-sky-800">
<p className="text-center text-2xl mb-2">Please check your email</p>
<CenteredForm>
<div className="p-2 sm:w-[30rem] w-80 rounded-2xl shadow-md m-auto border border-sky-100 bg-slate-50 text-sky-800">
<p className="text-center text-xl font-bold mb-2 text-black">
Please check your Email
</p>
<p>A sign in link has been sent to your email address.</p>
<p>You can safely close this page.</p>
{/* <div
onClick={() =>
signIn("email", {
email: email,
redirect: false,
})
}
className="mx-auto font-semibold mt-2 cursor-pointer w-fit"
>
Resend?
</div> */}
<hr className="my-5" />
<p className="text-sm text-gray-500 ">
If you didn&apos;t recieve anything, go to the{" "}
<Link href="/forgot" className="font-bold">
Password Recovery
</Link>{" "}
page and enter your Email to resend the sign in link.
</p>
</div>
</div>
</CenteredForm>
);
}
+15 -20
View File
@@ -1,4 +1,5 @@
import SubmitButton from "@/components/SubmitButton";
import CenteredForm from "@/layouts/CenteredForm";
import { signIn } from "next-auth/react";
import Image from "next/image";
import Link from "next/link";
@@ -38,22 +39,19 @@ export default function Forgot() {
}
return (
<>
<Image
src="/linkwarden.png"
width={518}
height={145}
alt="Linkwarden"
className="h-12 w-fit mx-auto mt-10"
/>
<div className="p-2 mt-10 mx-auto flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-md border border-sky-100">
<p className="text-xl text-sky-700 w-fit font-bold">Fogot Password?</p>
<p className="text-md text-gray-500 mt-1">
Enter your Email so we can send you a link to recover your account.
</p>
<p className="text-md text-gray-500 mt-1">
Make sure to change your password in the profile settings afterwards.
</p>
<CenteredForm>
<div className="p-2 flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-2xl shadow-md border border-sky-100">
<p className="text-2xl text-black font-bold">Password Recovery</p>
<div>
<p className="text-md text-black">
Enter your Email so we can send you a link to recover your account.
Make sure to change your password in the profile settings
afterwards.
</p>
<p className="text-sm text-gray-500">
You wont get logged in if you haven&apos;t created an account yet.
</p>
</div>
<div>
<p className="text-sm text-sky-700 w-fit font-semibold mb-1">Email</p>
@@ -78,9 +76,6 @@ export default function Forgot() {
</Link>
</div>
</div>
<p className="text-center text-xs text-gray-500 my-10">
© {new Date().getFullYear()} Linkwarden. All rights reserved.{" "}
</p>
</>
</CenteredForm>
);
}
+7 -18
View File
@@ -1,4 +1,5 @@
import SubmitButton from "@/components/SubmitButton";
import CenteredForm from "@/layouts/CenteredForm";
import { signIn } from "next-auth/react";
import Image from "next/image";
import Link from "next/link";
@@ -45,21 +46,12 @@ export default function Login() {
}
return (
<>
<Image
src="/linkwarden.png"
width={518}
height={145}
alt="Linkwarden"
className="h-12 w-fit mx-auto mt-10"
/>
<p className="text-xl font-semibold text-sky-700 px-2 text-center">
Sign in to your account
</p>
<div className="p-2 my-10 mx-auto flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-md border border-sky-100">
<p className="text-xl text-sky-700 w-fit font-bold">
<CenteredForm text="Sign in to your account">
<div className="p-2 flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-2xl shadow-md border border-sky-100">
<p className="text-2xl text-black text-center font-bold">
Enter your credentials
</p>
<div>
<p className="text-sm text-sky-700 w-fit font-semibold mb-1">
Username
@@ -99,7 +91,7 @@ export default function Login() {
<SubmitButton
onClick={loginUser}
label="Login"
className="mt-2 w-full text-center"
className=" w-full text-center"
loading={submitLoader}
/>
<div className="flex items-baseline gap-1 justify-center">
@@ -109,9 +101,6 @@ export default function Login() {
</Link>
</div>
</div>
<p className="text-center text-xs text-gray-500 mb-10">
© {new Date().getFullYear()} Linkwarden. All rights reserved.{" "}
</p>
</>
</CenteredForm>
);
}
+38 -48
View File
@@ -4,6 +4,7 @@ import { toast } from "react-hot-toast";
import SubmitButton from "@/components/SubmitButton";
import { signIn } from "next-auth/react";
import Image from "next/image";
import CenteredForm from "@/layouts/CenteredForm";
const emailEnabled = process.env.NEXT_PUBLIC_EMAIL_PROVIDER;
@@ -89,23 +90,17 @@ export default function Register() {
}
return (
<>
<Image
src="/linkwarden.png"
width={518}
height={145}
alt="Linkwarden"
className="h-12 w-fit mx-auto mt-10"
/>
<p className="text-center px-2 text-xl font-semibold text-sky-700">
{process.env.NEXT_PUBLIC_STRIPE_IS_ACTIVE
? `Start using our premium services with a ${
<CenteredForm
text={
process.env.NEXT_PUBLIC_STRIPE_IS_ACTIVE
? `Start using our Premium Services with a ${
process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14
}-day free trial!`
: "Create a new account"}
</p>
<div className="p-2 mx-auto my-10 flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-md border border-sky-100">
<p className="text-xl text-sky-700 w-fit font-bold">
: "Create a new account"
}
>
<div className="p-2 flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-2xl shadow-md border border-sky-100">
<p className="text-2xl text-black text-center font-bold">
Enter your details
</p>
<div>
@@ -154,40 +149,38 @@ export default function Register() {
</div>
) : undefined}
<div className="flex item-center gap-2">
<div className="w-full">
<p className="text-sm text-sky-700 w-fit font-semibold mb-1">
Password
</p>
<div className="w-full">
<p className="text-sm text-sky-700 w-fit font-semibold mb-1">
Password
</p>
<input
type="password"
placeholder="••••••••••••••"
value={form.password}
onChange={(e) => setForm({ ...form, password: e.target.value })}
className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 duration-100"
/>
</div>
<input
type="password"
placeholder="••••••••••••••"
value={form.password}
onChange={(e) => setForm({ ...form, password: e.target.value })}
className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 duration-100"
/>
</div>
<div className="w-full">
<p className="text-sm text-sky-700 w-fit font-semibold mb-1">
Confirm Password
</p>
<div className="w-full">
<p className="text-sm text-sky-700 w-fit font-semibold mb-1">
Confirm Password
</p>
<input
type="password"
placeholder="••••••••••••••"
value={form.passwordConfirmation}
onChange={(e) =>
setForm({ ...form, passwordConfirmation: e.target.value })
}
className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 duration-100"
/>
</div>
<input
type="password"
placeholder="••••••••••••••"
value={form.passwordConfirmation}
onChange={(e) =>
setForm({ ...form, passwordConfirmation: e.target.value })
}
className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 duration-100"
/>
</div>
{process.env.NEXT_PUBLIC_STRIPE_IS_ACTIVE ? (
<>
<div>
<p className="text-xs text-gray-500">
By signing up, you agree to our{" "}
<Link href="https://linkwarden.app/tos" className="font-semibold">
@@ -212,7 +205,7 @@ export default function Register() {
</Link>
.
</p>
</>
</div>
) : undefined}
<SubmitButton
@@ -228,9 +221,6 @@ export default function Register() {
</Link>
</div>
</div>
<p className="text-center text-xs text-gray-500 mb-10">
© {new Date().getFullYear()} Linkwarden. All rights reserved.{" "}
</p>
</>
</CenteredForm>
);
}
+15 -22
View File
@@ -5,6 +5,7 @@ import { useEffect, useState } from "react";
import { toast } from "react-hot-toast";
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import CenteredForm from "@/layouts/CenteredForm";
export default function Subscribe() {
const [submitLoader, setSubmitLoader] = useState(false);
@@ -20,29 +21,24 @@ export default function Subscribe() {
const res = await fetch("/api/payment");
const data = await res.json();
console.log(data);
router.push(data.response);
}
return (
<>
<Image
src="/linkwarden.png"
width={518}
height={145}
alt="Linkwarden"
className="h-12 w-fit mx-auto mt-10"
/>
<p className="text-xl font-semibold text-sky-700 text-center px-2">
{process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14} days free trial, then
${process.env.NEXT_PUBLIC_PRICING}/month afterwards
</p>
<div className="p-2 mt-10 mx-auto flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-md border border-sky-100">
<CenteredForm
text={`${
process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14
}-Day free trial, then $
${process.env.NEXT_PUBLIC_PRICING}/month afterwards`}
>
<div className="p-2 mx-auto flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-2xl shadow-md border border-sky-100">
<p className="text-2xl text-center font-bold">
Subscribe to Linkwarden!
</p>
<div>
<p className="text-md text-gray-500 mt-1">
You will be redirected to Stripe.
</p>
<p className="text-md text-gray-500 mt-1">
<p>You will be redirected to Stripe.</p>
<p>
Feel free to reach out to us at{" "}
<a className="font-semibold" href="mailto:support@linkwarden.app">
support@linkwarden.app
@@ -65,9 +61,6 @@ export default function Subscribe() {
Sign Out
</div>
</div>
<p className="text-center text-xs text-gray-500 my-10">
© {new Date().getFullYear()} Linkwarden. All rights reserved.{" "}
</p>
</>
</CenteredForm>
);
}
+796 -802
View File
File diff suppressed because it is too large Load Diff