chore
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
<div align="center">
|
||||
<h1>𝐖𝐑.𝐃𝐎</h1>
|
||||
<p><a href="https://discord.gg/d68kWCBDEs">Discord</a> · English | <a href="/README.md">简体中文</a></p>
|
||||
<p>Temporary email service build with email worker.</p>
|
||||
<!-- <img src="https://img.inke.app/file/beb0212f96c6cd37eaeb8.jpg"/> -->
|
||||
</div>
|
||||
|
||||
## Features
|
||||
|
||||
- 🎯 Privacy-friendly, no registration required, out-of-the-box
|
||||
- ✈️ Support email sending and receiving
|
||||
- ✨ Support saving passwords and retrieving email addresses
|
||||
- 😄 Support multiple domain name suffixes
|
||||
- 🚀 100% open source, quick deployment, no server required
|
||||
|
||||
Principles:
|
||||
|
||||
- Receiving emails (email worker)
|
||||
- Display email (remix)
|
||||
- Mail Storage (sqlite)
|
||||
- [Nodejs](https://nodejs.org) >= 18
|
||||
|
||||
> Worker receives email -> saves to database -> client queries email
|
||||
|
||||
## Self-hosted Tutorial
|
||||
|
||||
### Requirements
|
||||
|
||||
- [Cloudflare](https://dash.cloudflare.com/) account and a domain name hosted on Cloudflare
|
||||
- [turso](https://turso.tech) sqlite (a free plan available for personal use)
|
||||
- [Vercel](https://vercel.com) or [fly.io](https://fly.io) to deploy Remix app
|
||||
|
||||
### Receiving Emails steps
|
||||
|
||||
See [receive-tutorial-en.md](/docs//receive-tutorial-en.md)
|
||||
|
||||
### Sending Emails steps
|
||||
|
||||
See [send-tutorial-en.md](/docs/send-tutorial-en.md)
|
||||
|
||||
## Local development
|
||||
|
||||
copy `apps/remix/.env.example` to `apps/remix/.env` and fill in the necessary environment variables.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/oiov/vmail
|
||||
cd vmail
|
||||
pnpm install
|
||||
|
||||
# run on localhost:3000
|
||||
pnpm run remix:dev
|
||||
```
|
||||
|
||||
## Community Group
|
||||
|
||||
- Discord: https://discord.gg/d68kWCBDEs
|
||||
|
||||
## License
|
||||
|
||||
GNU General Public License v3.0
|
||||
|
||||
## Star History
|
||||
|
||||
[](https://star-history.com/#oiov/vmail&Date)
|
||||
|
||||
Inspired by smail.pw & email.ml
|
||||
@@ -19,7 +19,7 @@ export default async function DashboardPage() {
|
||||
return (
|
||||
<>
|
||||
<DashboardHeader
|
||||
heading="Manage DNS Records"
|
||||
heading="Manage DNS Records"
|
||||
text="List and manage records."
|
||||
link="/docs/dns-records"
|
||||
linkText="DNS Records."
|
||||
|
||||
@@ -19,7 +19,7 @@ export default async function DashboardPage() {
|
||||
return (
|
||||
<>
|
||||
<DashboardHeader
|
||||
heading="Manage Short URLs"
|
||||
heading="Manage Short URLs"
|
||||
text="List and manage short urls."
|
||||
link="/docs/short-urls"
|
||||
linkText="Short urls."
|
||||
|
||||
@@ -9,6 +9,7 @@ import useSWR, { useSWRConfig } from "swr";
|
||||
import { siteConfig } from "@/config/site";
|
||||
import { ShortUrlFormData } from "@/lib/dto/short-urls";
|
||||
import { cn, fetcher } from "@/lib/utils";
|
||||
import { useMediaQuery } from "@/hooks/use-media-query";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
@@ -38,12 +39,12 @@ export interface UrlListProps {
|
||||
|
||||
function TableColumnSekleton({ className }: { className?: string }) {
|
||||
return (
|
||||
<TableRow className="grid grid-cols-5 items-center sm:grid-cols-7">
|
||||
<TableCell className="col-span-2">
|
||||
<Skeleton className="h-5 w-24" />
|
||||
<TableRow className="grid grid-cols-3 items-center sm:grid-cols-7">
|
||||
<TableCell className="col-span-1 sm:col-span-2">
|
||||
<Skeleton className="h-5 w-20" />
|
||||
</TableCell>
|
||||
<TableCell className="col-span-2">
|
||||
<Skeleton className="h-5 w-24" />
|
||||
<TableCell className="col-span-1 sm:col-span-2">
|
||||
<Skeleton className="h-5 w-20" />
|
||||
</TableCell>
|
||||
<TableCell className="col-span-1 hidden justify-center sm:flex">
|
||||
<Skeleton className="h-5 w-16" />
|
||||
@@ -59,6 +60,7 @@ function TableColumnSekleton({ className }: { className?: string }) {
|
||||
}
|
||||
|
||||
export default function UserUrlsList({ user }: UrlListProps) {
|
||||
const { isMobile } = useMediaQuery();
|
||||
const [isShowForm, setShowForm] = useState(false);
|
||||
const [formType, setFormType] = useState<FormType>("add");
|
||||
const [currentEditUrl, setCurrentEditUrl] = useState<ShortUrlFormData | null>(
|
||||
@@ -127,11 +129,11 @@ export default function UserUrlsList({ user }: UrlListProps) {
|
||||
)}
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="grid grid-cols-5 items-center sm:grid-cols-7">
|
||||
<TableHead className="col-span-2 flex items-center font-bold">
|
||||
<TableRow className="grid grid-cols-3 items-center sm:grid-cols-7">
|
||||
<TableHead className="col-span-1 flex items-center font-bold sm:col-span-2">
|
||||
Target
|
||||
</TableHead>
|
||||
<TableHead className="col-span-2 flex items-center font-bold">
|
||||
<TableHead className="col-span-1 flex items-center font-bold sm:col-span-2">
|
||||
Url
|
||||
</TableHead>
|
||||
<TableHead className="col-span-1 hidden items-center justify-center font-bold sm:flex">
|
||||
@@ -154,17 +156,20 @@ export default function UserUrlsList({ user }: UrlListProps) {
|
||||
</>
|
||||
) : data && data.length > 0 ? (
|
||||
data.map((short) => (
|
||||
<TableRow className="grid animate-fade-in grid-cols-5 items-center animate-in sm:grid-cols-7">
|
||||
<TableCell className="col-span-2">
|
||||
<TableRow className="grid animate-fade-in grid-cols-3 items-center animate-in sm:grid-cols-7">
|
||||
<TableCell className="col-span-1 sm:col-span-2">
|
||||
<Link
|
||||
className="text-slate-600 hover:text-blue-400 hover:underline"
|
||||
href={short.target}
|
||||
target="_blank"
|
||||
>
|
||||
{short.target}
|
||||
{short.target.startsWith("http")
|
||||
? short.target.split("//")[1]
|
||||
: short.target}
|
||||
{/* {isMobile ? short.target.split("//")[1] :short.target} */}
|
||||
</Link>
|
||||
</TableCell>
|
||||
<TableCell className="col-span-2 flex items-center gap-1">
|
||||
<TableCell className="col-span-1 flex items-center gap-1 sm:col-span-2">
|
||||
<Link
|
||||
className="text-slate-600 hover:text-blue-400 hover:underline"
|
||||
href={`/s/${short.url}`}
|
||||
|
||||
@@ -58,7 +58,7 @@ export function NewsletterForm() {
|
||||
<Input
|
||||
type="email"
|
||||
className="rounded-lg px-4"
|
||||
placeholder="janedoe@example.com"
|
||||
placeholder="oiov@example.com"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
@@ -56,6 +56,15 @@ export function SiteFooter({ className }: React.HTMLAttributes<HTMLElement>) {
|
||||
className="font-medium text-primary underline underline-offset-2"
|
||||
>
|
||||
Nextjs
|
||||
</Link>{" "}
|
||||
&{" "}
|
||||
<Link
|
||||
href="https://www.cloudflare.com?ref=wrdo"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="font-medium text-primary underline underline-offset-2"
|
||||
>
|
||||
Cloudflare
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
|
||||
+23
-4
@@ -12,18 +12,37 @@ export const docsConfig: DocsConfig = {
|
||||
icon: "page",
|
||||
},
|
||||
{
|
||||
title: "Installation",
|
||||
href: "/docs/installation",
|
||||
title: "Quick Start",
|
||||
href: "/docs/quick-start",
|
||||
icon: "page",
|
||||
},
|
||||
{
|
||||
title: "DNS Records",
|
||||
href: "/docs/dns-records",
|
||||
icon: "page",
|
||||
},
|
||||
{
|
||||
title: "Short URLs",
|
||||
href: "/docs/short-urls",
|
||||
icon: "page",
|
||||
},
|
||||
{
|
||||
title: "Newsletter",
|
||||
href: "/docs/newsletter",
|
||||
icon: "page",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Configuration",
|
||||
title: "Developer",
|
||||
items: [
|
||||
{
|
||||
title: "Installation",
|
||||
href: "/docs/installation",
|
||||
icon: "page",
|
||||
},
|
||||
{
|
||||
title: "Authentification",
|
||||
// title: "Blog",
|
||||
href: "/docs/configuration/authentification",
|
||||
icon: "page",
|
||||
},
|
||||
|
||||
+2
-1
@@ -7,7 +7,7 @@ const free_url_quota = env.NEXT_PUBLIC_FREE_URL_QUOTA;
|
||||
const open_signup = env.NEXT_PUBLIC_OPEN_SIGNUP;
|
||||
|
||||
export const siteConfig: SiteConfig = {
|
||||
name: "WR.DO",
|
||||
name: "𝐖𝐑.𝐃𝐎",
|
||||
description: "A DNS record distribution system",
|
||||
url: site_url,
|
||||
ogImage: `${site_url}/_static/og.jpg`,
|
||||
@@ -46,6 +46,7 @@ export const footerLinks: SidebarNavItem[] = [
|
||||
items: [
|
||||
{ title: "Introduction", href: "/docs" },
|
||||
{ title: "Guide", href: "/docs/quick-start" },
|
||||
{ title: "Developer", href: "/docs/developer" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user