only for login user access pages condition updated for homw page and crawl page and logout function updated
This commit is contained in:
parent
3cdab23587
commit
290dff0b4a
@ -1,6 +1,7 @@
|
|||||||
// app/(defaults)/crawl/page.tsx
|
// app/(defaults)/crawl/page.tsx
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,6 +30,18 @@ export default function CrawlPage() {
|
|||||||
|
|
||||||
const apiBase = 'https://api.crawlerx.co/crawl';
|
const apiBase = 'https://api.crawlerx.co/crawl';
|
||||||
|
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
if (!token) {
|
||||||
|
// If no token, redirect to login page
|
||||||
|
router.push("/login");
|
||||||
|
}
|
||||||
|
}, [router]);
|
||||||
|
|
||||||
|
|
||||||
/* ---------------- URL helpers ---------------- */
|
/* ---------------- URL helpers ---------------- */
|
||||||
const isValidUrl = useMemo(() => {
|
const isValidUrl = useMemo(() => {
|
||||||
try {
|
try {
|
||||||
@ -104,28 +117,28 @@ export default function CrawlPage() {
|
|||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function exportCSV() {
|
function exportCSV() {
|
||||||
const rows = filteredRows;
|
const rows = filteredRows;
|
||||||
if (!rows.length) return;
|
if (!rows.length) return;
|
||||||
const cols = visibleCols.length ? visibleCols : defaultCols;
|
const cols = visibleCols.length ? visibleCols : defaultCols;
|
||||||
|
|
||||||
const csvEscape = (v: any) => {
|
const csvEscape = (v: any) => {
|
||||||
if (v == null) return '';
|
if (v == null) return '';
|
||||||
const s = String(v);
|
const s = String(v);
|
||||||
// NOTE: keep this regex on one line!
|
// NOTE: keep this regex on one line!
|
||||||
return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
||||||
};
|
};
|
||||||
|
|
||||||
const header = cols.join(',');
|
const header = cols.join(',');
|
||||||
const lines = rows.map((r) => cols.map((c) => csvEscape(r[c])).join(','));
|
const lines = rows.map((r) => cols.map((c) => csvEscape(r[c])).join(','));
|
||||||
const csv = [header, ...lines].join('\n');
|
const csv = [header, ...lines].join('\n');
|
||||||
|
|
||||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' });
|
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' });
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
a.href = URL.createObjectURL(blob);
|
a.href = URL.createObjectURL(blob);
|
||||||
a.download = 'crawl-report.csv';
|
a.download = 'crawl-report.csv';
|
||||||
a.click();
|
a.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------- data shaping ---------------- */
|
/* ---------------- data shaping ---------------- */
|
||||||
const rows = useMemo(() => dataRows(report), [report]);
|
const rows = useMemo(() => dataRows(report), [report]);
|
||||||
@ -144,7 +157,7 @@ function exportCSV() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!rows.length) return;
|
if (!rows.length) return;
|
||||||
if (!visibleCols.length) setVisibleCols(PRESets[view]?.columns ?? defaultCols);
|
if (!visibleCols.length) setVisibleCols(PRESets[view]?.columns ?? defaultCols);
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [rows.length]);
|
}, [rows.length]);
|
||||||
|
|
||||||
// recompute on view change
|
// recompute on view change
|
||||||
@ -422,8 +435,8 @@ function dataRows(report: any): any[] {
|
|||||||
const data = Array.isArray(report)
|
const data = Array.isArray(report)
|
||||||
? report
|
? report
|
||||||
: Array.isArray(report?.results)
|
: Array.isArray(report?.results)
|
||||||
? report.results
|
? report.results
|
||||||
: null;
|
: null;
|
||||||
return Array.isArray(data) ? data : [];
|
return Array.isArray(data) ? data : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,25 @@
|
|||||||
import { Metadata } from 'next';
|
"use client";
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
// import { Metadata } from "next";
|
||||||
title: 'CrawlerX',
|
import React, { useEffect } from "react";
|
||||||
};
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
|
// export const metadata: Metadata = {
|
||||||
|
// title: "CrawlerX",
|
||||||
|
// };
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
return <div>starter page</div>;
|
const router = useRouter();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
if (!token) {
|
||||||
|
// If no token, redirect to login page
|
||||||
|
router.push("/login");
|
||||||
|
}
|
||||||
|
}, [router]);
|
||||||
|
|
||||||
|
return <div>starter page</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Dashboard;
|
export default Dashboard;
|
||||||
|
|||||||
@ -6,8 +6,8 @@ import { Nunito } from 'next/font/google';
|
|||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: {
|
title: {
|
||||||
template: '%s | VRISTO - Multipurpose Tailwind Dashboard Template',
|
template: 'CrawlerX',
|
||||||
default: 'VRISTO - Multipurpose Tailwind Dashboard Template',
|
default: 'Crawl Smarter. Rank Higher.',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const nunito = Nunito({
|
const nunito = Nunito({
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
const Footer = () => {
|
const Footer = () => {
|
||||||
return (
|
return (
|
||||||
<div className="p-6 pt-0 mt-auto text-center dark:text-white-dark ltr:sm:text-left rtl:sm:text-right">© {new Date().getFullYear()}. Vristo All rights reserved.</div>
|
<div className="p-6 pt-0 mt-auto text-center dark:text-white-dark ltr:sm:text-left rtl:sm:text-right">© {new Date().getFullYear()}. CrawlerX All rights reserved.</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -144,6 +144,17 @@ const Header = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const [search, setSearch] = useState(false);
|
const [search, setSearch] = useState(false);
|
||||||
|
const [token, setToken] = useState("")
|
||||||
|
useEffect(() => {
|
||||||
|
const Token: any = localStorage.getItem('token')
|
||||||
|
setToken(Token)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
|
||||||
|
const HandleLogout = () => {
|
||||||
|
localStorage.removeItem('token')
|
||||||
|
router.push('/login')
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className={`z-40 ${themeConfig.semidark && themeConfig.menu === 'horizontal' ? 'dark' : ''}`}>
|
<header className={`z-40 ${themeConfig.semidark && themeConfig.menu === 'horizontal' ? 'dark' : ''}`}>
|
||||||
@ -152,7 +163,7 @@ const Header = () => {
|
|||||||
<div className="horizontal-logo flex items-center justify-between ltr:mr-2 rtl:ml-2 lg:hidden">
|
<div className="horizontal-logo flex items-center justify-between ltr:mr-2 rtl:ml-2 lg:hidden">
|
||||||
<Link href="/" className="main-logo flex shrink-0 items-center">
|
<Link href="/" className="main-logo flex shrink-0 items-center">
|
||||||
<img className="inline w-8 ltr:-ml-1 rtl:-mr-1" src="/assets/images/logo.svg" alt="logo" />
|
<img className="inline w-8 ltr:-ml-1 rtl:-mr-1" src="/assets/images/logo.svg" alt="logo" />
|
||||||
<span className="hidden align-middle text-2xl font-semibold transition-all duration-300 ltr:ml-1.5 rtl:mr-1.5 dark:text-white-light md:inline">VRISTO</span>
|
<span className="hidden align-middle text-2xl font-semibold transition-all duration-300 ltr:ml-1.5 rtl:mr-1.5 dark:text-white-light md:inline">CrawlerX</span>
|
||||||
</Link>
|
</Link>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -213,10 +224,9 @@ const Header = () => {
|
|||||||
<div>
|
<div>
|
||||||
{themeConfig.theme === 'light' ? (
|
{themeConfig.theme === 'light' ? (
|
||||||
<button
|
<button
|
||||||
className={`${
|
className={`${themeConfig.theme === 'light' &&
|
||||||
themeConfig.theme === 'light' &&
|
|
||||||
'flex items-center rounded-full bg-white-light/40 p-2 hover:bg-white-light/90 hover:text-primary dark:bg-dark/40 dark:hover:bg-dark/60'
|
'flex items-center rounded-full bg-white-light/40 p-2 hover:bg-white-light/90 hover:text-primary dark:bg-dark/40 dark:hover:bg-dark/60'
|
||||||
}`}
|
}`}
|
||||||
onClick={() => dispatch(toggleTheme('dark'))}
|
onClick={() => dispatch(toggleTheme('dark'))}
|
||||||
>
|
>
|
||||||
<IconSun />
|
<IconSun />
|
||||||
@ -226,10 +236,9 @@ const Header = () => {
|
|||||||
)}
|
)}
|
||||||
{themeConfig.theme === 'dark' && (
|
{themeConfig.theme === 'dark' && (
|
||||||
<button
|
<button
|
||||||
className={`${
|
className={`${themeConfig.theme === 'dark' &&
|
||||||
themeConfig.theme === 'dark' &&
|
|
||||||
'flex items-center rounded-full bg-white-light/40 p-2 hover:bg-white-light/90 hover:text-primary dark:bg-dark/40 dark:hover:bg-dark/60'
|
'flex items-center rounded-full bg-white-light/40 p-2 hover:bg-white-light/90 hover:text-primary dark:bg-dark/40 dark:hover:bg-dark/60'
|
||||||
}`}
|
}`}
|
||||||
onClick={() => dispatch(toggleTheme('system'))}
|
onClick={() => dispatch(toggleTheme('system'))}
|
||||||
>
|
>
|
||||||
<IconMoon />
|
<IconMoon />
|
||||||
@ -237,10 +246,9 @@ const Header = () => {
|
|||||||
)}
|
)}
|
||||||
{themeConfig.theme === 'system' && (
|
{themeConfig.theme === 'system' && (
|
||||||
<button
|
<button
|
||||||
className={`${
|
className={`${themeConfig.theme === 'system' &&
|
||||||
themeConfig.theme === 'system' &&
|
|
||||||
'flex items-center rounded-full bg-white-light/40 p-2 hover:bg-white-light/90 hover:text-primary dark:bg-dark/40 dark:hover:bg-dark/60'
|
'flex items-center rounded-full bg-white-light/40 p-2 hover:bg-white-light/90 hover:text-primary dark:bg-dark/40 dark:hover:bg-dark/60'
|
||||||
}`}
|
}`}
|
||||||
onClick={() => dispatch(toggleTheme('light'))}
|
onClick={() => dispatch(toggleTheme('light'))}
|
||||||
>
|
>
|
||||||
<IconLaptop />
|
<IconLaptop />
|
||||||
@ -445,10 +453,24 @@ const Header = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li className="border-t border-white-light dark:border-white-light/10">
|
<li className="border-t border-white-light dark:border-white-light/10">
|
||||||
<Link href="/auth/boxed-signin" className="!py-3 text-danger">
|
<li className="border-t border-white-light dark:border-white-light/10">
|
||||||
<IconLogout className="h-4.5 w-4.5 shrink-0 rotate-90 ltr:mr-2 rtl:ml-2" />
|
{token ? (
|
||||||
Sign Out
|
<button
|
||||||
</Link>
|
type="button"
|
||||||
|
onClick={HandleLogout}
|
||||||
|
className="!py-3 text-danger flex items-center"
|
||||||
|
>
|
||||||
|
<IconLogout className="h-4.5 w-4.5 shrink-0 rotate-90 ltr:mr-2 rtl:ml-2" />
|
||||||
|
Sign Out
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<Link href="/login" className="!py-3 text-danger">
|
||||||
|
<IconLogout className="h-4.5 w-4.5 shrink-0 rotate-90 ltr:mr-2 rtl:ml-2" />
|
||||||
|
Login
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
|||||||
@ -91,7 +91,7 @@ const Sidebar = () => {
|
|||||||
<div className="flex items-center justify-between px-4 py-3">
|
<div className="flex items-center justify-between px-4 py-3">
|
||||||
<Link href="/" className="main-logo flex shrink-0 items-center">
|
<Link href="/" className="main-logo flex shrink-0 items-center">
|
||||||
<img className="ml-[5px] w-8 flex-none" src="/assets/images/logo.svg" alt="logo" />
|
<img className="ml-[5px] w-8 flex-none" src="/assets/images/logo.svg" alt="logo" />
|
||||||
<span className="align-middle text-2xl font-semibold ltr:ml-1.5 rtl:mr-1.5 dark:text-white-light lg:inline">VRISTO</span>
|
<span className="align-middle text-2xl font-semibold ltr:ml-1.5 rtl:mr-1.5 dark:text-white-light lg:inline">CrawlerX</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "vristo-next",
|
"name": "CrawlerX",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "vristo-next",
|
"name": "CrawlerX",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.10.6",
|
"@emotion/react": "^11.10.6",
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "vristo-next",
|
"name": "crawlerx",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user