diff --git a/app/(marketing)/page.tsx b/app/(marketing)/page.tsx index cdc6e01..7120805 100644 --- a/app/(marketing)/page.tsx +++ b/app/(marketing)/page.tsx @@ -1,3 +1,4 @@ +import { siteConfig } from "@/config/site"; import HeroLanding, { LandingImages } from "@/components/sections/hero-landing"; import { PricingSection } from "@/components/sections/pricing"; @@ -7,7 +8,6 @@ export default function IndexPage() { return ( <> - {/* */} > diff --git a/app/(protected)/dashboard/page.tsx b/app/(protected)/dashboard/page.tsx index 946fb4e..333ec99 100644 --- a/app/(protected)/dashboard/page.tsx +++ b/app/(protected)/dashboard/page.tsx @@ -1,4 +1,3 @@ -import Link from "next/link"; import { redirect } from "next/navigation"; import { siteConfig } from "@/config/site"; diff --git a/app/(protected)/dashboard/urls/url-list.tsx b/app/(protected)/dashboard/urls/url-list.tsx index 7e0cbb7..56718f7 100644 --- a/app/(protected)/dashboard/urls/url-list.tsx +++ b/app/(protected)/dashboard/urls/url-list.tsx @@ -353,7 +353,7 @@ export default function UserUrlsList({ user, action }: UrlListProps) { { setSelectedUrlId(short.id!); setShowQrcode(!isShowQrcode); - handleQrcode(`https://wr.do/s/${short.url}`); + handleQrcode( + `https://${short.prefix}/s/${short.url}`, + ); }} > diff --git a/app/api/url/add/route.ts b/app/api/url/add/route.ts index e000f0f..f558d0f 100644 --- a/app/api/url/add/route.ts +++ b/app/api/url/add/route.ts @@ -25,13 +25,14 @@ export async function POST(req: Request) { const { data } = await req.json(); - const { target, url, visible, active, expiration } = + const { target, url, prefix, visible, active, expiration } = createUrlSchema.parse(data); const res = await createUserShortUrl({ userId: user.id, userName: user.name || "Anonymous", target, url, + prefix, visible, active, expiration, diff --git a/app/api/url/admin/delete/route.ts b/app/api/url/admin/delete/route.ts index bf7f44a..9a9ae6d 100644 --- a/app/api/url/admin/delete/route.ts +++ b/app/api/url/admin/delete/route.ts @@ -1,5 +1,4 @@ import { env } from "@/env.mjs"; -import { getUserRecords } from "@/lib/dto/cloudflare-dns-record"; import { deleteUserShortUrl } from "@/lib/dto/short-urls"; import { checkUserStatus } from "@/lib/dto/user"; import { getCurrentUser } from "@/lib/session"; diff --git a/app/api/url/admin/update/route.ts b/app/api/url/admin/update/route.ts index ec44819..2593df8 100644 --- a/app/api/url/admin/update/route.ts +++ b/app/api/url/admin/update/route.ts @@ -24,7 +24,7 @@ export async function POST(req: Request) { }); } - const { target, url, visible, active, id, expiration } = + const { target, url, prefix, visible, active, id, expiration } = createUrlSchema.parse(data); const res = await updateUserShortUrl({ id, @@ -32,6 +32,7 @@ export async function POST(req: Request) { userName: "", target, url, + prefix, visible, active, expiration, diff --git a/app/api/url/update/active/route.ts b/app/api/url/update/active/route.ts index da15070..8aa2ef7 100644 --- a/app/api/url/update/active/route.ts +++ b/app/api/url/update/active/route.ts @@ -6,7 +6,6 @@ import { } from "@/lib/dto/short-urls"; import { checkUserStatus } from "@/lib/dto/user"; import { getCurrentUser } from "@/lib/session"; -import { createUrlSchema } from "@/lib/validations/url"; export async function POST(req: Request) { try { diff --git a/app/api/url/update/route.ts b/app/api/url/update/route.ts index 533dbfd..f7c4574 100644 --- a/app/api/url/update/route.ts +++ b/app/api/url/update/route.ts @@ -18,13 +18,14 @@ export async function POST(req: Request) { }); } - const { target, url, visible, active, id, expiration } = + const { target, url, prefix, visible, active, id, expiration } = createUrlSchema.parse(data); const res = await updateUserShortUrl({ id, userId: user.id, userName: user.name || "Anonymous", target, + prefix, url, visible, active, diff --git a/components/forms/url-form.tsx b/components/forms/url-form.tsx index cad7bf4..4214c3f 100644 --- a/components/forms/url-form.tsx +++ b/components/forms/url-form.tsx @@ -7,6 +7,7 @@ import { Sparkles } from "lucide-react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; +import { siteConfig } from "@/config/site"; import { ShortUrlFormData } from "@/lib/dto/short-urls"; import { EXPIRATION_ENUMS } from "@/lib/enums"; import { generateUrlSuffix } from "@/lib/utils"; @@ -63,6 +64,7 @@ export function UrlForm({ target: initData?.target || "", url: initData?.url || "", active: initData?.active || 1, + prefix: initData?.prefix || siteConfig.shortDomains[0], visible: initData?.visible || 0, expiration: initData?.expiration || "-1", }, @@ -148,7 +150,7 @@ export function UrlForm({ onSubmit={onSubmit} > - + Target @@ -172,19 +174,38 @@ export function UrlForm({ )} - + Url - - https://wr.do/s/ - + { + setValue("prefix", value); + }} + name="prefix" + defaultValue={initData?.prefix || siteConfig.shortDomains[0]} + disabled={type === "edit"} + > + + + + + {siteConfig.shortDomains.map((v) => ( + + {v} + + ))} + + + {/* + /s/ + */} ) : ( - A random url suffix. + A random url suffix. Final url like「wr.do/s/suffix」 )} @@ -241,7 +262,15 @@ export function UrlForm({ Expiration time, default for never. - + {/* + + Your Final URL: + + + {getValues("prefix")}/s/{getValues("url")} + + */} + {/* Visible @@ -257,7 +286,7 @@ export function UrlForm({ Public or private short url. - + */} {/* diff --git a/config/site.ts b/config/site.ts index 783871f..65277a1 100644 --- a/config/site.ts +++ b/config/site.ts @@ -5,6 +5,7 @@ const site_url = env.NEXT_PUBLIC_APP_URL; const free_recored_quota = env.NEXT_PUBLIC_FREE_RECORD_QUOTA; const free_url_quota = env.NEXT_PUBLIC_FREE_URL_QUOTA; const open_signup = env.NEXT_PUBLIC_OPEN_SIGNUP; +const short_domains = env.NEXT_PUBLIC_SHORT_DOMAINS || ""; export const siteConfig: SiteConfig = { name: "WR.DO", @@ -22,6 +23,7 @@ export const siteConfig: SiteConfig = { url: Number(free_url_quota), }, openSignup: open_signup === "1" ? true : false, + shortDomains: short_domains.split(","), }; export const footerLinks: SidebarNavItem[] = [ diff --git a/env.mjs b/env.mjs index 22dae06..ce96255 100644 --- a/env.mjs +++ b/env.mjs @@ -26,6 +26,7 @@ export const env = createEnv({ NEXT_PUBLIC_FREE_RECORD_QUOTA: z.string().min(1).default("3"), NEXT_PUBLIC_FREE_URL_QUOTA: z.string().min(1).default("100"), NEXT_PUBLIC_OPEN_SIGNUP: z.string().min(1).default("1"), + NEXT_PUBLIC_SHORT_DOMAINS: z.string().min(1).default(""), }, runtimeEnv: { NEXTAUTH_URL: process.env.NEXTAUTH_URL, @@ -40,6 +41,7 @@ export const env = createEnv({ NEXT_PUBLIC_FREE_RECORD_QUOTA: process.env.NEXT_PUBLIC_FREE_RECORD_QUOTA, NEXT_PUBLIC_FREE_URL_QUOTA: process.env.NEXT_PUBLIC_FREE_URL_QUOTA, NEXT_PUBLIC_OPEN_SIGNUP: process.env.NEXT_PUBLIC_OPEN_SIGNUP, + NEXT_PUBLIC_SHORT_DOMAINS: process.env.NEXT_PUBLIC_SHORT_DOMAINS, CLOUDFLARE_ZONE_ID: process.env.CLOUDFLARE_ZONE_ID, CLOUDFLARE_API_KEY: process.env.CLOUDFLARE_API_KEY, CLOUDFLARE_EMAIL: process.env.CLOUDFLARE_EMAIL, diff --git a/lib/dto/short-urls.ts b/lib/dto/short-urls.ts index a7ddbed..c0a7b3d 100644 --- a/lib/dto/short-urls.ts +++ b/lib/dto/short-urls.ts @@ -9,6 +9,7 @@ export interface ShortUrlFormData { userName: string; target: string; url: string; + prefix: string; visible: number; active: number; expiration: string; @@ -103,6 +104,7 @@ export async function createUserShortUrl(data: ShortUrlFormData) { userName: data.userName || "Anonymous", target: data.target, url: data.url, + prefix: data.prefix, visible: data.visible, active: data.active, expiration: data.expiration, @@ -127,6 +129,7 @@ export async function updateUserShortUrl(data: ShortUrlFormData) { target: data.target, url: data.url, visible: data.visible, + prefix: data.prefix, // active: data.active, expiration: data.expiration, updatedAt: new Date().toISOString(), @@ -206,6 +209,7 @@ export async function getUrlBySuffix(suffix: string) { id: true, target: true, active: true, + prefix: true, expiration: true, updatedAt: true, }, diff --git a/lib/validations/url.ts b/lib/validations/url.ts index 6437524..82a3d36 100644 --- a/lib/validations/url.ts +++ b/lib/validations/url.ts @@ -23,4 +23,5 @@ export const createUrlSchema = z.object({ expiration: z.string().default("-1"), visible: z.number().default(1), active: z.number().default(1), + prefix: z.string().default("wr.do"), }); diff --git a/prisma/migrations/20240705091917_init/migration.sql b/prisma/migrations/20240705091917_init/migration.sql index 5da496d..978b529 100644 --- a/prisma/migrations/20240705091917_init/migration.sql +++ b/prisma/migrations/20240705091917_init/migration.sql @@ -126,6 +126,7 @@ CREATE TABLE "user_urls" "userName" TEXT NOT NULL, "target" TEXT NOT NULL, "url" TEXT NOT NULL, + "prefix" TEXT NOT NULL, "visible" INTEGER NOT NULL DEFAULT 0, "active" INTEGER NOT NULL DEFAULT 1, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f1bb23f..212a05f 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -110,6 +110,7 @@ model UserUrl { userName String target String url String @unique + prefix String visible Int @default(0) active Int @default(1) expiration String @default("-1") diff --git a/public/sw.js.map b/public/sw.js.map index 772a845..37cc2e2 100644 --- a/public/sw.js.map +++ b/public/sw.js.map @@ -1 +1 @@ -{"version":3,"file":"sw.js","sources":["../../../../../private/var/folders/9b/3qmyp8zd2xvdspdrp149fyg00000gn/T/eeb8506ad954ff7d16a48dffbab4e6da/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-routing@6.6.0/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-core@6.6.0/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"sw.js","sources":["../../../../../private/var/folders/9b/3qmyp8zd2xvdspdrp149fyg00000gn/T/16fe6ea3dda159bcee09c25f9a0e35b4/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-routing@6.6.0/node_modules/workbox-routing/registerRoute.mjs';\nimport {NetworkFirst as workbox_strategies_NetworkFirst} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-strategies@6.6.0/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/songjunxi/Desktop/repos/wr.do/node_modules/.pnpm/workbox-core@6.6.0/node_modules/workbox-core/clientsClaim.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\nimportScripts(\n \n);\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n\nworkbox_routing_registerRoute(\"/\", new workbox_strategies_NetworkFirst({ \"cacheName\":\"start-url\", plugins: [{ cacheWillUpdate: async ({ request, response, event, state }) => { if (response && response.type === 'opaqueredirect') { return new Response(response.body, { status: 200, statusText: 'OK', headers: response.headers }) } return response } }] }), 'GET');\nworkbox_routing_registerRoute(/.*/i, new workbox_strategies_NetworkOnly({ \"cacheName\":\"dev\", plugins: [] }), 'GET');\n\n\n\n\n"],"names":["importScripts","self","skipWaiting","workbox_core_clientsClaim","workbox_routing_registerRoute","workbox_strategies_NetworkFirst","plugins","cacheWillUpdate","request","response","event","state","type","Response","body","status","statusText","headers","workbox_strategies_NetworkOnly"],"mappings":"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"} \ No newline at end of file diff --git a/types/index.d.ts b/types/index.d.ts index 58c6a93..6183700 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -19,6 +19,7 @@ export type SiteConfig = { url: number; }; openSignup: boolean; + shortDomains: string[]; }; export type NavItem = {
- A random url suffix. + A random url suffix. Final url like「wr.do/s/suffix」
+ Your Final URL: +
+ {getValues("prefix")}/s/{getValues("url")} +
Public or private short url.