diff --git a/app/app/(dashboard)/home/page.tsx b/app/app/(dashboard)/home/page.tsx index ea9ac6e..256c876 100644 --- a/app/app/(dashboard)/home/page.tsx +++ b/app/app/(dashboard)/home/page.tsx @@ -125,7 +125,7 @@ export default function HomePage() { className="checkbox checkbox-success checkbox-sm pointer-events-none" readOnly /> -

Make a short link or QR Code

+

Make a short link

@@ -134,16 +134,6 @@ export default function HomePage() {

Create a link

- - -
diff --git a/app/app/(dashboard)/links/[id]/page.tsx b/app/app/(dashboard)/links/[id]/page.tsx index 959c12a..11640bd 100644 --- a/app/app/(dashboard)/links/[id]/page.tsx +++ b/app/app/(dashboard)/links/[id]/page.tsx @@ -45,11 +45,16 @@ export default function Page(params : any) { Desktop: 720, Mobile: 420, Tablet: 60 + }, + refs:{ + google: 20, + direc: 210, + "dub.co": 60 } }; return ( -
+
+ +
- -
+ +
+ +
+ +
+
+
+
); diff --git a/app/app/(dashboard)/links/page.tsx b/app/app/(dashboard)/links/page.tsx index 1a536a7..dd904bb 100644 --- a/app/app/(dashboard)/links/page.tsx +++ b/app/app/(dashboard)/links/page.tsx @@ -18,8 +18,8 @@ export default function Page() { const [loading,setLoading] = useState(true) const current_date = new Date() const [date, setDate] = React.useState({ - from: new Date(current_date.getFullYear(), current_date.getMonth(), current_date.getDate()), - to: addDays(new Date(2024, 4, 24), 20), + to: new Date(current_date.getFullYear(), current_date.getMonth(), current_date.getDate()+1), + from: new Date(2024, 4, 18), }) useEffect(()=>{ diff --git a/components/CardComponents/LinkCard.tsx b/components/CardComponents/LinkCard.tsx index 35e02fb..857c4e2 100644 --- a/components/CardComponents/LinkCard.tsx +++ b/components/CardComponents/LinkCard.tsx @@ -53,7 +53,7 @@ export function LinkCard({ Share - + - + diff --git a/components/CardComponents/QRCodeCardComponent.tsx b/components/CardComponents/QRCodeCardComponent.tsx index d3e9b98..ca28830 100644 --- a/components/CardComponents/QRCodeCardComponent.tsx +++ b/components/CardComponents/QRCodeCardComponent.tsx @@ -54,7 +54,7 @@ export function QRCodeCardComponent({ qrcode }: { qrcode: any }) {
- +
@@ -69,15 +69,17 @@ export function QRCodeCardComponent({ qrcode }: { qrcode: any }) { -
-
@@ -97,7 +99,12 @@ export function QRCodeCardComponent({ qrcode }: { qrcode: any }) {
-

+

{ + window.open( + shortLink, + "_blank" + ) + }} className="text-sm ml-2 hover:underline cursor-pointer"> {shortLink}

@@ -108,9 +115,6 @@ export function QRCodeCardComponent({ qrcode }: { qrcode: any }) { - diff --git a/components/DialogComponents/LinkShareDialog.tsx b/components/DialogComponents/LinkShareDialog.tsx index 737af25..180decc 100644 --- a/components/DialogComponents/LinkShareDialog.tsx +++ b/components/DialogComponents/LinkShareDialog.tsx @@ -8,10 +8,16 @@ import { DialogTrigger, } from "@/components/ui/dialog" import { Input } from "@/components/ui/input" -import { Copy, Facebook, Instagram, MessageCircleCodeIcon } from "lucide-react" +import { Copy, Facebook, MessageCircleCodeIcon,LinkedinIcon } from "lucide-react" import React from "react" import { toast } from "../ui/use-toast" - +import { + FacebookShareButton, + LinkedinShareButton, + TwitterShareButton, + WhatsappShareButton +} from "react-share"; +import { TwitterLogoIcon } from "@radix-ui/react-icons" export function LinkShareDialog({children,link}:{ children : React.ReactNode, link:any @@ -49,15 +55,26 @@ export function LinkShareDialog({children,link}:{
+
+
+
- +
+
+
+
+ +
+ +
+
diff --git a/components/NavigationBars/SideNavBar.tsx b/components/NavigationBars/SideNavBar.tsx index a71e537..13bbcf6 100644 --- a/components/NavigationBars/SideNavBar.tsx +++ b/components/NavigationBars/SideNavBar.tsx @@ -33,9 +33,9 @@ export function SideNavBar() { ) : (
- - - + + +
{/* this is a seperator */}
diff --git a/interfaces/types.ts b/interfaces/types.ts index 57bc501..bced999 100644 --- a/interfaces/types.ts +++ b/interfaces/types.ts @@ -12,7 +12,6 @@ export interface locationsDetails { percentage: number; } -export type devicesDetails = Record; export interface LinkType { id: number; @@ -24,7 +23,8 @@ export interface LinkType { last7DaysEngage?: number; weeklyChange?: number; locations?: locationsDetails[]; - devices?: devicesDetails; + devices?: Record; + refs?: Record } diff --git a/lib/actions/createLinkAction.ts b/lib/actions/createLinkAction.ts index 9b81d52..f3f35fc 100644 --- a/lib/actions/createLinkAction.ts +++ b/lib/actions/createLinkAction.ts @@ -1,6 +1,5 @@ "use server" -import { HTTP_STATUS } from "../constants" import { createPrivateLink } from "../services/privateLinkManager" export async function createLinkAction (formdata:FormData){ diff --git a/lib/services/privateLinkManager.ts b/lib/services/privateLinkManager.ts index 2912eff..3db0022 100644 --- a/lib/services/privateLinkManager.ts +++ b/lib/services/privateLinkManager.ts @@ -1,5 +1,4 @@ import { base62_encode } from "@/lib/services/base62"; -import { NextRequest } from "next/server"; import incrementCounter from "@/lib/services/counter"; import { getServerSession } from "next-auth"; @@ -14,7 +13,7 @@ export async function createPrivateLink(formdata : FormData) { const posgresInstance = PrismaClientManager.getInstance(); const prisma = posgresInstance.getPrismaClient(); - const { title,long_url, status, msg } = validateURLCreateReq(formdata); + const { title,long_url, status } = await validateURLCreateReq(formdata); const session: ISessionType | null = await getServerSession(authOptions); if (!status) { diff --git a/lib/validations/url_create.ts b/lib/validations/url_create.ts index 6b02c67..632e84b 100644 --- a/lib/validations/url_create.ts +++ b/lib/validations/url_create.ts @@ -1,28 +1,36 @@ -import { NextRequest } from "next/server"; import { urlSchema } from "../zod/url"; +import cheerio from 'cheerio'; -import { IUrlCreateReq } from "@/interfaces/url"; +const validateURLCreateReq = async (formdata: FormData) => { + try { + const long_url = formdata.get("longUrl"); + let title:any = formdata.get("title"); -const validateURLCreateReq = (formdata: FormData) => { - try { - - const long_url = formdata.get("longUrl"); - const title = formdata.get("title"); - - // validation of title need to be done - const errors = urlSchema.safeParse({ - long_url, - }); - return { title,long_url, status: errors.success, msg: errors.error }; - } catch (e) { - return { - title: "", - long_url: "", - status: false, - msg : JSON.stringify(e) - }; + // validation of title need to be done + const errors = urlSchema.safeParse({ + long_url, + }); + + const urlHit: any = long_url; + + if (title?.toString().length == 0) { + const response = await fetch(urlHit); + const html = await response.text(); + const $ = cheerio.load(html); + const newTitle = $('title').text(); + title = newTitle; } - }; + return { title, long_url, status: errors.success, msg: errors.error }; + } catch (e) { + console.log(e) + return { + title: "", + long_url: "", + status: false, + msg: JSON.stringify(e), + }; + } +}; -export default validateURLCreateReq; \ No newline at end of file +export default validateURLCreateReq; diff --git a/lib/zod/url.ts b/lib/zod/url.ts index b55b815..89a30d5 100644 --- a/lib/zod/url.ts +++ b/lib/zod/url.ts @@ -1,7 +1,7 @@ import { z } from "zod"; const urlSchema = z.object({ - long_url: z.string().url(), + long_url: z.string().url() }); export { urlSchema }; diff --git a/package-lock.json b/package-lock.json index bd648d5..08bc93b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,7 @@ "bcrypt": "^5.1.1", "bcryptjs": "^2.4.3", "chart.js": "^4.4.2", + "cheerio": "^1.0.0-rc.12", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "date-fns": "^3.6.0", @@ -47,6 +48,7 @@ "react-day-picker": "^8.10.1", "react-dom": "^18", "react-resizable-panels": "^2.0.16", + "react-share": "^5.1.0", "tailwind-merge": "^2.2.2", "tailwindcss-animate": "^1.0.7", "ua-parser-js": "^1.0.37", @@ -2581,6 +2583,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2726,6 +2733,42 @@ "pnpm": ">=8" } }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -2787,6 +2830,11 @@ "node": ">=6" } }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -2876,6 +2924,32 @@ "node": ">= 8" } }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -3084,6 +3158,57 @@ "node": ">=6.0.0" } }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -3113,6 +3238,17 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/es-abstract": { "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", @@ -4249,6 +4385,24 @@ "react-is": "^16.7.0" } }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -4832,6 +4986,27 @@ "json5": "lib/cli.js" } }, + "node_modules/jsonp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/jsonp/-/jsonp-0.2.1.tgz", + "integrity": "sha512-pfog5gdDxPdV4eP7Kg87M8/bHgshlZ5pybl+yKxAnCZ5O7lCIn7Ixydj03wOlnDQesky2BPyA91SQ+5Y/mNwzw==", + "dependencies": { + "debug": "^2.1.3" + } + }, + "node_modules/jsonp/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/jsonp/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -5306,6 +5481,17 @@ "set-blocking": "^2.0.0" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/oauth": { "version": "0.9.15", "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", @@ -5551,6 +5737,29 @@ "node": ">=6" } }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6000,6 +6209,18 @@ "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-share": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/react-share/-/react-share-5.1.0.tgz", + "integrity": "sha512-OvyfMtj/0UzH1wi90OdHhZVJ6WUC/+IeWvBwppeZozwIGyAjQgyR0QXlHOrxVHVECqnGvcpBaFTXVrqouTieaw==", + "dependencies": { + "classnames": "^2.3.2", + "jsonp": "^0.2.1" + }, + "peerDependencies": { + "react": "^17 || ^18" + } + }, "node_modules/react-style-singleton": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", diff --git a/package.json b/package.json index aaf1336..5c5e550 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "bcrypt": "^5.1.1", "bcryptjs": "^2.4.3", "chart.js": "^4.4.2", + "cheerio": "^1.0.0-rc.12", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "date-fns": "^3.6.0", @@ -48,6 +49,7 @@ "react-day-picker": "^8.10.1", "react-dom": "^18", "react-resizable-panels": "^2.0.16", + "react-share": "^5.1.0", "tailwind-merge": "^2.2.2", "tailwindcss-animate": "^1.0.7", "ua-parser-js": "^1.0.37",