upd: logos and layout
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
<div align="center">
|
||||
<h1>𝐖𝐑.𝐃𝐎</h1>
|
||||
<h1>WR.DO</h1>
|
||||
<p><a href="https://discord.gg/d68kWCBDEs">Discord</a> · English | <a href="/README-zh.md">简体中文</a></p>
|
||||
<p>创建 DNS 记录,生成短链接</p>
|
||||
<img src="https://f8dd841.webp.li/wrdo-og.png"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div align="center">
|
||||
<h1>𝐖𝐑.𝐃𝐎</h1>
|
||||
<h1>WR.DO</h1>
|
||||
<p><a href="https://discord.gg/d68kWCBDEs">Discord</a> · English | <a href="/README-zh.md">简体中文</a></p>
|
||||
<p>Craft DNS Records, Make Short Links</p>
|
||||
<img src="https://f8dd841.webp.li/wrdo-og.png"/>
|
||||
|
||||
@@ -11,7 +11,7 @@ import UserRecordsList from "./records/record-list";
|
||||
import UserUrlsList from "./urls/url-list";
|
||||
|
||||
export const metadata = constructMetadata({
|
||||
title: "Dashboard - WRDO",
|
||||
title: "Dashboard - WR.DO",
|
||||
description: "List and manage records.",
|
||||
});
|
||||
|
||||
@@ -24,7 +24,7 @@ export default async function DashboardPage() {
|
||||
<>
|
||||
<DashboardHeader
|
||||
heading="Dashboard"
|
||||
text="𝐖𝐑.𝐃𝐎 Beta Launching Now! 🎉"
|
||||
text="WR.DO Beta Launching Now! 🎉"
|
||||
/>
|
||||
<div className="flex flex-col gap-5">
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-3 xl:grid-cols-3">
|
||||
|
||||
@@ -7,7 +7,7 @@ import { DashboardHeader } from "@/components/dashboard/header";
|
||||
import UserRecordsList from "./record-list";
|
||||
|
||||
export const metadata = constructMetadata({
|
||||
title: "DNS Records - WRDO",
|
||||
title: "DNS Records - WR.DO",
|
||||
description: "List and manage records.",
|
||||
});
|
||||
|
||||
|
||||
@@ -169,7 +169,10 @@ export default function UserRecordsList({ user }: RecordListProps) {
|
||||
</>
|
||||
) : data && data.length > 0 ? (
|
||||
data.map((record) => (
|
||||
<TableRow className="grid animate-fade-in grid-cols-3 items-center animate-in sm:grid-cols-7">
|
||||
<TableRow
|
||||
key={record.id}
|
||||
className="grid animate-fade-in grid-cols-3 items-center animate-in sm:grid-cols-7"
|
||||
>
|
||||
<TableCell className="col-span-1">
|
||||
<Badge className="text-xs" variant="outline">
|
||||
{record.type}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { DashboardHeader } from "@/components/dashboard/header";
|
||||
import UserUrlsList from "./url-list";
|
||||
|
||||
export const metadata = constructMetadata({
|
||||
title: "Short URLs - WRDO",
|
||||
title: "Short URLs - WR.DO",
|
||||
description: "List and manage records.",
|
||||
});
|
||||
|
||||
|
||||
@@ -156,7 +156,10 @@ export default function UserUrlsList({ user }: UrlListProps) {
|
||||
</>
|
||||
) : data && data.length > 0 ? (
|
||||
data.map((short) => (
|
||||
<TableRow className="grid animate-fade-in grid-cols-3 items-center animate-in sm:grid-cols-7">
|
||||
<TableRow
|
||||
key={short.id}
|
||||
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"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { toast } from "sonner";
|
||||
import { z } from "zod";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -14,7 +15,6 @@ import {
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { toast } from "@/components/ui/use-toast";
|
||||
|
||||
const FormSchema = z.object({
|
||||
email: z.string().email({
|
||||
@@ -31,15 +31,16 @@ export function NewsletterForm() {
|
||||
});
|
||||
|
||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||
form.reset();
|
||||
toast({
|
||||
title: "You submitted the following values:",
|
||||
description: (
|
||||
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
||||
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
||||
</pre>
|
||||
),
|
||||
});
|
||||
// form.reset();
|
||||
toast.warning(`Work in progress...`);
|
||||
// toast({
|
||||
// title: "You submitted the following values:",
|
||||
// description: (
|
||||
// <pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
|
||||
// <code className="text-white">{JSON.stringify(data, null, 2)}</code>
|
||||
// </pre>
|
||||
// ),
|
||||
// });
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { Fragment, useEffect, useState } from "react";
|
||||
import Image from "next/image";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { NavItem, SidebarNavItem } from "@/types";
|
||||
import { Menu, PanelLeftClose, PanelRightClose } from "lucide-react";
|
||||
@@ -75,7 +76,11 @@ export function DashboardSidebar({ links }: DashboardSidebarProps) {
|
||||
{isSidebarExpanded && (
|
||||
<>
|
||||
<Icons.logo />
|
||||
<Link href="/" className="font-satoshi text-xl font-bold">
|
||||
<Link
|
||||
href="/"
|
||||
style={{ fontFamily: "Bahamas Bold" }}
|
||||
className="text-2xl"
|
||||
>
|
||||
{siteConfig.name}
|
||||
</Link>
|
||||
</>
|
||||
@@ -237,11 +242,15 @@ export function MobileSheetSidebar({ links }: DashboardSidebarProps) {
|
||||
<div className="flex h-screen flex-col">
|
||||
<nav className="flex flex-1 flex-col gap-y-8 p-6 text-lg font-medium">
|
||||
<Link
|
||||
href="#"
|
||||
href="/"
|
||||
className="flex items-center gap-2 text-lg font-semibold"
|
||||
>
|
||||
<Icons.logo className="size-6" />
|
||||
<span className="font-satoshi text-lg font-bold">
|
||||
{/* <Icons.logo /> */}
|
||||
<Image src="/favicon.ico" alt="logo" width={20} height={20} />
|
||||
<span
|
||||
style={{ fontFamily: "Bahamas Bold" }}
|
||||
className="pt-0.5 text-xl"
|
||||
>
|
||||
{siteConfig.name}
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { useContext } from "react";
|
||||
import Link from "next/link";
|
||||
import { useSelectedLayoutSegment } from "next/navigation";
|
||||
import { useSession } from "next-auth/react";
|
||||
@@ -13,11 +12,11 @@ import { useScroll } from "@/hooks/use-scroll";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { DocsSearch } from "@/components/docs/search";
|
||||
import { ModalContext } from "@/components/modals/providers";
|
||||
import { Icons } from "@/components/shared/icons";
|
||||
import MaxWidthWrapper from "@/components/shared/max-width-wrapper";
|
||||
|
||||
import { ModeToggle } from "./mode-toggle";
|
||||
import { UserAccountNav } from "./user-account-nav";
|
||||
|
||||
interface NavBarProps {
|
||||
scroll?: boolean;
|
||||
@@ -27,7 +26,6 @@ interface NavBarProps {
|
||||
export function NavBar({ scroll = false }: NavBarProps) {
|
||||
const scrolled = useScroll(50);
|
||||
const { data: session, status } = useSession();
|
||||
const { setShowSignInModal } = useContext(ModalContext);
|
||||
|
||||
const selectedLayout = useSelectedLayoutSegment();
|
||||
const documentation = selectedLayout === "docs";
|
||||
@@ -49,12 +47,16 @@ export function NavBar({ scroll = false }: NavBarProps) {
|
||||
className="flex h-14 items-center justify-between py-4"
|
||||
large={documentation}
|
||||
>
|
||||
<div className="flex gap-6 md:gap-10">
|
||||
<div className="flex items-center gap-6 md:gap-10">
|
||||
<Link href="/" className="flex items-center space-x-1.5">
|
||||
<Icons.logo />
|
||||
<span className="text-xl font-bold">{siteConfig.name}</span>
|
||||
<h1 style={{ fontFamily: "Bahamas Bold" }} className="text-2xl">
|
||||
{siteConfig.name}
|
||||
</h1>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-4">
|
||||
{links && links.length > 0 ? (
|
||||
<nav className="hidden gap-6 md:flex">
|
||||
{links.map((item, index) => (
|
||||
@@ -75,9 +77,7 @@ export function NavBar({ scroll = false }: NavBarProps) {
|
||||
))}
|
||||
</nav>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-3">
|
||||
{/* right header for docs */}
|
||||
{documentation ? (
|
||||
<div className="hidden flex-1 items-center space-x-4 sm:justify-end lg:flex">
|
||||
@@ -100,21 +100,17 @@ export function NavBar({ scroll = false }: NavBarProps) {
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<ModeToggle />
|
||||
{session ? (
|
||||
<Link
|
||||
href={session.user.role === "ADMIN" ? "/admin" : "/dashboard"}
|
||||
className="hidden md:block"
|
||||
>
|
||||
<Button
|
||||
className="gap-2 px-4"
|
||||
variant="default"
|
||||
size="sm"
|
||||
rounded="xl"
|
||||
<div className="hidden items-center gap-4 md:flex">
|
||||
<Link
|
||||
href="/dashboard"
|
||||
className="hidden text-sm font-medium text-foreground/60 transition-colors hover:text-foreground/80 md:block"
|
||||
>
|
||||
<span>Dashboard</span>
|
||||
</Button>
|
||||
</Link>
|
||||
Dashboard
|
||||
</Link>
|
||||
<ModeToggle />
|
||||
<UserAccountNav />
|
||||
</div>
|
||||
) : status === "unauthenticated" ? (
|
||||
<Link href="login">
|
||||
<Button
|
||||
|
||||
@@ -12,6 +12,20 @@ export function SiteFooter({ className }: React.HTMLAttributes<HTMLElement>) {
|
||||
return (
|
||||
<footer className={cn("border-t", className)}>
|
||||
<div className="container grid max-w-6xl grid-cols-2 gap-6 py-14 md:grid-cols-5">
|
||||
<div className="col-span-full ml-4 flex flex-col items-start sm:col-span-1 md:col-span-2">
|
||||
{/* <NewsletterForm /> */}
|
||||
<div className="flex items-center gap-6 md:gap-10">
|
||||
<Link href="/" className="flex items-center space-x-1.5">
|
||||
<Icons.logo />
|
||||
<h1 style={{ fontFamily: "Bahamas Bold" }} className="text-2xl">
|
||||
{siteConfig.name}
|
||||
</h1>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="mt-4 text-sm">
|
||||
Craft DNS Records, Make Short Links.
|
||||
</div>
|
||||
</div>
|
||||
{footerLinks.map((section) => (
|
||||
<div key={section.title}>
|
||||
<span className="text-sm font-medium text-foreground">
|
||||
@@ -31,9 +45,6 @@ export function SiteFooter({ className }: React.HTMLAttributes<HTMLElement>) {
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
<div className="col-span-full flex flex-col items-end sm:col-span-1 md:col-span-2">
|
||||
<NewsletterForm />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t py-4">
|
||||
|
||||
@@ -125,7 +125,7 @@ export function UserAccountNav() {
|
||||
<DropdownMenuTrigger>
|
||||
<UserAvatar
|
||||
user={{ name: user.name || null, image: user.image || null }}
|
||||
className="size-8 border"
|
||||
className="size-8 border border-gray-200 shadow-inner"
|
||||
/>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
|
||||
@@ -16,7 +16,9 @@ export default async function HeroLanding() {
|
||||
"px-4",
|
||||
)}
|
||||
>
|
||||
<span className="mr-3">🎉</span> 𝐖𝐑.𝐃𝐎 Beta Launching Now!
|
||||
<span className="mr-3">🎉</span>{" "}
|
||||
<span style={{ fontFamily: "Bahamas Bold" }}>WR.DO </span> Beta
|
||||
Launching Now!
|
||||
</Link>
|
||||
|
||||
<h1 className="text-balance font-satoshi text-[40px] font-black leading-[1.15] tracking-tight sm:text-5xl md:text-6xl md:leading-[1.15]">
|
||||
@@ -32,17 +34,6 @@ export default async function HeroLanding() {
|
||||
</p>
|
||||
|
||||
<div className="flex justify-center space-x-2">
|
||||
<Link
|
||||
href="/dashboard"
|
||||
prefetch={true}
|
||||
className={cn(
|
||||
buttonVariants({ rounded: "xl", size: "lg" }),
|
||||
"gap-2 px-5 text-[15px]",
|
||||
)}
|
||||
>
|
||||
<span>Dashboard</span>
|
||||
<Icons.arrowRight className="size-4" />
|
||||
</Link>
|
||||
<Link
|
||||
href={siteConfig.links.github}
|
||||
target="_blank"
|
||||
@@ -61,6 +52,17 @@ export default async function HeroLanding() {
|
||||
<span className="hidden sm:inline-block">Star on</span> GitHub
|
||||
</p>
|
||||
</Link>
|
||||
<Link
|
||||
href="/dashboard"
|
||||
prefetch={true}
|
||||
className={cn(
|
||||
buttonVariants({ rounded: "xl", size: "lg" }),
|
||||
"gap-2 px-5 text-[15px]",
|
||||
)}
|
||||
>
|
||||
<span>Dashboard</span>
|
||||
<Icons.arrowRight className="size-4" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
+3
-2
@@ -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: "𝐖𝐑.𝐃𝐎",
|
||||
name: "WR.DO",
|
||||
description: "A DNS record distribution system",
|
||||
url: site_url,
|
||||
ogImage: `${site_url}/_static/og.jpg`,
|
||||
@@ -30,10 +30,11 @@ export const footerLinks: SidebarNavItem[] = [
|
||||
{ title: "About", href: "/docs" },
|
||||
{ title: "Terms", href: "/terms" },
|
||||
{ title: "Privacy", href: "/privacy" },
|
||||
{ title: "Blog", href: "https://www.oiov.dev" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Product",
|
||||
title: "Products",
|
||||
items: [
|
||||
{ title: "Vmail", href: "https://vmail.dev" },
|
||||
{ title: "Moise", href: "https://moise.oiov.dev" },
|
||||
|
||||
@@ -125,3 +125,16 @@ export async function getUserUrlMetaInfo(userId: string, urlId: string) {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function getUrlBySuffix(suffix: string) {
|
||||
return await prisma.userUrl.findFirst({
|
||||
where: {
|
||||
url: suffix,
|
||||
active: 1,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
target: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 8.4 KiB |
@@ -117,3 +117,21 @@
|
||||
background-position: 50%;
|
||||
background-size: 20px 20px;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Bahamas Normal";
|
||||
/* font-style: normal;
|
||||
font-weight: normal; */
|
||||
src:
|
||||
local("Bahamas Normal"),
|
||||
url("/_static/fonts/BAHAMASN.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Bahamas Bold";
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src:
|
||||
local("Bahamas Bold"),
|
||||
url("/_static/fonts/BAHAMASB.woff") format("woff");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user