diff --git a/README.md b/README.md index 9483570172..1911367b5f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ - Dub – an open-source link shortener SaaS with built-in analytics + free custom domains. + Dub – an open-source link management tool for modern marketing teams to create, share, and track short links.

Dub

- An open-source link shortener SaaS with built-in analytics + free custom domains. + An open-source link management tool for modern marketing teams to create, share, and track short links.

@@ -28,7 +28,7 @@ ## Introduction -Dub is an open-source link shortener with built-in analytics + free custom domains. Built with [Vercel Edge Functions](http://vercel.com/edge), [Upstash Redis](https://docs.upstash.com/redis), and [Planetscale MySQL](https://planetscale.com/). +Dub is an open-source link management tool for modern marketing teams to create, share, and track short links. Built with [Vercel Edge Functions](http://vercel.com/edge), [Upstash Redis](https://docs.upstash.com/redis), and [Planetscale MySQL](https://planetscale.com/). Here are some of the features that Dub provides out-of-the-box: diff --git a/components/app/links/link-card.tsx b/components/app/links/link-card.tsx index 9df88d5c5e..bebca70d14 100644 --- a/components/app/links/link-card.tsx +++ b/components/app/links/link-card.tsx @@ -14,7 +14,6 @@ import { Chart, Delete, Edit, - Eye, LoadingDots, QR, ThreeDots, @@ -147,18 +146,6 @@ export default function LinkCard({ props }: { props: LinkProps }) { clicks

- {title && description && image && ( - - - - )}

{url} diff --git a/components/app/modals/add-edit-link-modal/advanced-settings.tsx b/components/app/modals/add-edit-link-modal/advanced-settings.tsx index 6014ade819..f876ce0173 100644 --- a/components/app/modals/add-edit-link-modal/advanced-settings.tsx +++ b/components/app/modals/add-edit-link-modal/advanced-settings.tsx @@ -23,8 +23,6 @@ export default function AdvancedSettings({ data: LinkProps; setData: Dispatch>; }) { - const [expanded, setExpanded] = useState(false); - const { url, title, description, image, password, expiresAt } = data; const { utm_source, utm_medium, utm_campaign } = useMemo(() => { @@ -33,128 +31,27 @@ export default function AdvancedSettings({ return (
-
- +
+
+
+ Optional +
- {expanded && ( - - - {/* UTM Builder Section */} - - - -
- - - UTM Builder - -
- {utm_source && utm_medium && utm_campaign && ( - - )} -
-
- - - -
+
+ - {/* OG Tags Section */} - - - -
- - - Custom Social Previews - -
- {title && description && image && ( - - )} -
-
- - - -
+ - {/* Password Protection */} - - - -
- - - Password Protection - -
- {password && ( - - )} -
-
- - - -
+ - {/* Expiration Date */} - - - -
- - - Expiration Date - - {expiresAt && - new Date().getTime() > new Date(expiresAt).getTime() && ( - - Expired - - )} -
- {expiresAt && ( - - )} -
-
- - - -
- - - )} + +
); } diff --git a/components/app/modals/add-edit-link-modal/index.tsx b/components/app/modals/add-edit-link-modal/index.tsx index e9155e9956..5b4948394f 100644 --- a/components/app/modals/add-edit-link-modal/index.tsx +++ b/components/app/modals/add-edit-link-modal/index.tsx @@ -140,28 +140,51 @@ function AddEditLinkModal({ setShowModal={setShowAddEditLinkModal} closeWithX={true} > -
- {!hideXButton && ( +
+ {/* {!hideXButton && ( - )} + )} */} -
- -

{heroProps.copy}

-
+
+ {/*
+
+ + { + setKeyExistsError(false); + setData({ ...data, url: e.target.value }); + }} + required + className="peer block w-full rounded-md border border-gray-100 bg-gray-50 p-2 pl-10 text-sm placeholder:text-gray-400 focus:border-black focus:bg-white focus:outline-none focus:ring-0" + /> +
+
*/} +
+ +

{heroProps.copy}

+
- {id && ( + {/* {id && (
{expired ? ( Expired @@ -170,172 +193,175 @@ function AddEditLinkModal({ )} {archived && Archived}
- )} - -
{ - e.preventDefault(); - setSaving(true); - fetch(endpoint.url, { - method: endpoint.method, - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(data), - }).then((res) => { - setSaving(false); - if (res.status === 200) { - mutate( - domain - ? `/api/projects/${slug}/domains/${domain}/links${getQueryString( - router, - )}` - : `/api/links${getQueryString(router)}`, - ); - if (router.asPath === "/welcome") { - router.push("/links").then(() => { + )} */} + { + e.preventDefault(); + setSaving(true); + fetch(endpoint.url, { + method: endpoint.method, + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data), + }).then((res) => { + setSaving(false); + if (res.status === 200) { + mutate( + domain + ? `/api/projects/${slug}/domains/${domain}/links${getQueryString( + router, + )}` + : `/api/links${getQueryString(router)}`, + ); + if (router.asPath === "/welcome") { + router.push("/links").then(() => { + setShowAddEditLinkModal(false); + }); + } else { setShowAddEditLinkModal(false); - }); + } + } else if (res.status === 403) { + setKeyExistsError(true); + } else if (res.status === 400) { + setUrlError(true); } else { - setShowAddEditLinkModal(false); + alert("Something went wrong"); } - } else if (res.status === 403) { - setKeyExistsError(true); - } else if (res.status === 400) { - setUrlError(true); - } else { - alert("Something went wrong"); - } - }); - }} - className="grid gap-6 bg-gray-50 py-8" - > -
-
-
+ }); + }} + className="grid gap-6 bg-gray-50 py-8" + > +
+
+
+ + +
+
+ + {domain || "dub.sh"} + + { + setKeyExistsError(false); + setData({ ...data, key: e.target.value }); + }} + aria-invalid="true" + aria-describedby="key-error" + /> + {keyExistsError && ( +
+
+ )} +
+ {keyExistsError && ( +

+ Short link is already in use. +

+ )} +
+ +
- -
-
- - {domain || "dub.sh"} - - { - setKeyExistsError(false); - setData({ ...data, key: e.target.value }); - }} - aria-invalid="true" - aria-describedby="key-error" - /> - {keyExistsError && ( -
-
+
+ {urlError && ( +

+ Invalid url. +

)}
- {keyExistsError && ( -

- Short link is already in use. -

- )}
-
-
- - - -
- -
- + +
+
preview
); diff --git a/components/app/modals/add-edit-link-modal/og-section.tsx b/components/app/modals/add-edit-link-modal/og-section.tsx index fe3f15298d..605f5bca0e 100644 --- a/components/app/modals/add-edit-link-modal/og-section.tsx +++ b/components/app/modals/add-edit-link-modal/og-section.tsx @@ -135,7 +135,7 @@ export default function OGSection({ id="description" minRows={3} className="block w-full rounded-md border-gray-300 pr-10 text-gray-900 placeholder-gray-300 focus:border-gray-500 focus:outline-none focus:ring-gray-500 sm:text-sm" - placeholder="Dub is an open-source link shortener SaaS with built-in analytics + free custom domains." + placeholder="Dub is open-source link management tool for modern marketing teams to create, share, and track short links." value={description || ""} onChange={(e) => { setData({ diff --git a/components/home/features.tsx b/components/home/features.tsx index 9773d7970a..69b2841e6d 100644 --- a/components/home/features.tsx +++ b/components/home/features.tsx @@ -5,6 +5,7 @@ import { QR, Users, Link as LinkIcon, + Photo, } from "@/components/shared/icons"; import MaxWidthWrapper from "@/components/shared/max-width-wrapper"; import { useState } from "react"; @@ -31,6 +32,7 @@ const featureList = [ ), demo: "https://d2vwwcvoksz7ty.cloudfront.net/analytics.mp4", + thumbnail: "/_static/features/analytics.png", }, { key: "domains", @@ -51,11 +53,29 @@ const featureList = [ demo: "https://d2vwwcvoksz7ty.cloudfront.net/custom-domain.mp4", }, { - key: "links", - title: "Links with superpowers", + key: "social", + title: "Custom social media cards", + icon: , + description: + "Overlay custom OG images on your links to make them stand out on social media.", + cta: ( + + Customize your links + + ), + demo: "https://d2vwwcvoksz7ty.cloudfront.net/og.mp4", + }, + { + key: "builder", + title: "Powerful link builder", icon: , description: - "Create links with custom social previews, UTM parameters, password protection, and expiration dates.", + "Build your links with UTM parameters, password protection, and even expiration dates.", cta: ( - Create your project + Build your link - ), //custom cta + ), demo: "https://d2vwwcvoksz7ty.cloudfront.net/og.mp4", }, { @@ -186,9 +206,16 @@ export default function Features() { stiffness: 300, damping: 30, }} - className="min-h-[600px] w-full overflow-hidden whitespace-nowrap rounded-2xl bg-white shadow-2xl lg:mt-10 lg:w-[800px]" + className="relative min-h-[600px] w-full overflow-hidden whitespace-nowrap rounded-2xl bg-white shadow-2xl lg:mt-10 lg:w-[800px]" > -