Astro app

This commit is contained in:
Alicia Sykes 2024-05-20 22:44:09 +01:00
parent 34ca09fc20
commit b090dcadb1
23 changed files with 513 additions and 48 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

84
src/components/Nav.astro Normal file
View File

@ -0,0 +1,84 @@
---
---
<nav class="navbar">
<div class="nav-left">
<a href="/" class="logo-link" aria-label="Home">
<img width="64" src="/web-check.png" alt="Site Logo" />
<span class="site-title">Web Check</span>
</a>
</div>
<div class="nav-right">
<a href="/check" class="nav-link">Try Live</a>
<a href="/check/about" class="nav-link">About</a>
<a href="/account" class="nav-link">Join</a>
</div>
</nav>
<style lang="scss">
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.5rem 1rem;
flex-wrap: wrap;
background-color: var(--background);
color: var(--text-color);
width: 80vw;
margin: 0 auto;
border-radius: 2rem;
border: 1px solid var(--primary-transparent);
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
.nav-left {
display: flex;
align-items: center;
.logo-link {
display: flex;
align-items: center;
text-decoration: none;
color: var(--text-color);
img {
width: 2rem;
max-width: 64px;
margin-right: 0.5rem;
}
.site-title {
font-weight: bold;
color: var(--primary);
font-size: 1.8rem;
}
}
}
.nav-right {
display: flex;
.nav-link {
text-decoration: none;
color: var(--text-color);
margin-left: 1rem;
padding: 0.5rem;
transition: background-color 0.3s;
&:hover {
background-color: var(--primary-light);
}
&:focus {
outline: none;
background-color: var(--primary-dark);
box-shadow: 0 0 0 3px var(--primary);
}
}
}
}
</style>

View File

@ -5,6 +5,11 @@ import MetaTags from '@layouts/MetaTags.astro';
// import Footer from '@components/scafold/Footer.astro';
// import config from '../site-config';
import '@styles/typography.scss';
import '@styles/global.scss';
import '@styles/colors.scss';
import '@styles/media-queries.scss';
interface Props {
title?: string;
description?: string;
@ -37,7 +42,7 @@ interface Props {
<style is:global>
@import '@styles/global.scss';
html {
::selection {
background: var(--accent);

View File

@ -14,7 +14,8 @@ interface Props {
// Default meta tag values
const siteInfo = {
title: 'Web Check',
description: '',
titleLong: 'Web Check - X-Ray Vision for any Website',
description: 'Web Check is the all-in-one OSINT and security tool, for revealing the inner workings of any website',
keywords: '',
author: 'Alicia Sykes',
twitter: '@Lissy_Sykes',
@ -36,7 +37,7 @@ const {
} = Astro.props;
// Set non-customizable values for meta tags, from the siteInfo
const { site, author, twitter, analytics } = siteInfo;
const { site, author, twitter, analytics, titleLong } = siteInfo;
// Given a map of breadcrumbs, return the JSON-LD for the BreadcrumbList schema
const makeBreadcrumbs = () => {
@ -68,20 +69,21 @@ const makeBreadcrumbs = () => {
<meta name="robots" content="index, follow">
<!-- Icons and colors -->
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/png" sizes="64x64" href="/favicon.png">
<!-- <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> -->
<link rel="icon" type="image/png" sizes="512x512" href="/web-check.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<!-- Social media meta tags (Open Graphh + Twitter) -->
<meta property="og:site_name" content={title}>
<meta property="og:type" content="website">
<meta property="og:url" content={site}>
<meta property="og:title" content={title}>
<meta property="og:title" content={titleLong}>
<meta property="og:description" content={description}>
<meta property="og:image" content={`${site}/banner.png`}>
<meta name="twitter:card" content="summary">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:url" content={site}>
<meta name="twitter:title" content={title}>
<meta name="twitter:title" content={titleLong}>
<meta name="twitter:description" content={description}>
<meta name="twitter:image" content=`${site}/banner.png`}>
<link rel="twitter:image" sizes="180x180" href={`${site}/apple-touch-icon.png`}>

View File

@ -1,4 +1,5 @@
---
import BaseLayout from '@layouts/Base.astro';
import Main from '../../web-check-live/main.tsx';
import '../../web-check-live/styles/index.css';
@ -14,21 +15,28 @@ if (searchUrl) {
---
<html>
<head>
<title>Results</title>
<meta charset="UTF-8">
</head>
<body>
<Main {pathname} client:load />
</body>
</html>
<BaseLayout>
<Main {pathname} client:load />
</BaseLayout>
<script>
// Fallback, if Astro hasn't initialized the RC comp yet, use JS to redirect
// Fallback, if Astro hasn't initialized the RC comp yet, then check the url
// And if form has been submitted with ?url=, redirect to the results page
const searchParams = new URL(window.location.href).searchParams;
if (searchParams.has('url')) {
window.location.href = `/check/${searchParams.get('url')}`;
}
// And add a manual no-react form submit handler
const form = document.querySelector<HTMLFormElement>('form');
if (form) {
form.addEventListener('submit', function(event: Event) {
event.preventDefault();
const input = (this as HTMLFormElement).querySelector<HTMLInputElement>('input[name="url"]');
if (input && input.value) {
window.location.href = `/check/${encodeURIComponent(input.value)}`;
}
});
}
</script>

View File

@ -2,7 +2,10 @@
import BaseLayout from '@layouts/Base.astro';
---
<BaseLayout title="API Docs | Web Check">
<BaseLayout
title="API Docs | Web Check"
description="API documentation for the Web Check backend REST endpoints"
>
<Fragment slot="head">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.1.3/swagger-ui.css">
<link rel="stylesheet" href="https://rawcdn.githack.com/Amoenus/SwaggerDark/2064ccd45b571865a64c731fa6bfddfbf2a01fe1/SwaggerDark.css">
@ -23,20 +26,21 @@ import BaseLayout from '@layouts/Base.astro';
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
]
});
}
</script>
<style lang="scss">
@import '@styles/global.scss';
main {
padding: 0 2rem;
margin: 0 auto;
height: 100vh;
width: 100vw;
max-width: 1600px;
@include mobile-down {
padding: 0;
}
}
</style>

File diff suppressed because one or more lines are too long

33
src/styles/colors.scss Normal file
View File

@ -0,0 +1,33 @@
:root {
--primary: #9fef00;
--primary-lighter: #cff97a;
--text-color: #ffffff;
--text-color-secondary: #a4b1cd;
--background: #141d2b;
--background-darker: #111927;
--background-lighter: #1a2332;
--bg-shadow-color: #0f1620;
--fg-shadow-color: #456602;
--primary-transparent: #9fef0030;
// Action Colors
--info: #04e4f4;
--success: #20e253;
--warning: #f6f000;
--error: #fca016;
--danger: #f80363;
--neutral: #272f4d;
}
html[data-theme="light"] {
--primary: #4a7700;
--primary-lighter: #a4cf50;
--text-color: #333333;
--text-color-secondary: #57667e;
--background: #ffffff;
--background-darker: #f0f0f0;
--background-lighter: #fafafa;
--bg-shadow-color: #e0e0e0;
--fg-shadow-color: #678800;
--primary-transparent: #4a770033;
}

123
src/styles/global.scss Normal file
View File

@ -0,0 +1,123 @@
/* Global Stylesheet */
@import './media-queries.scss';
/* CSS Reset - Normalize dimensions and spacing across browsers */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* HTML and body basic setup */
html {
font-size: 16px; // Default text size; consider accessibility and user preferences
scroll-behavior: smooth; // Smooth scrolling on click to hash links
}
body {
font-family: 'Inter', 'Helvetica Neue', Arial, sans-serif;
line-height: 1;
color: var(--text-color);
background: var(--background);
overflow-x: hidden;
font-weight: 400;
}
/* Links */
a {
color: inherit;
text-decoration: none;
&:hover,
&:focus {
text-decoration: underline;
}
}
/* Images */
img {
max-width: 100%;
height: auto;
}
/* Typography */
h1, h2, h3, h4, h5, h6 {
color: inherit;
margin-top: 0;
margin-bottom: 0.5em;
font-weight: normal;
}
p {
margin-top: 0;
margin-bottom: 1em;
}
ul, ol {
margin-top: 0;
margin-bottom: 1em;
padding-left: 20px;
}
/* Forms */
input, button, textarea, select {
font: inherit;
&:focus {
outline: 1px solid var(--primary);
}
}
/* Utility Classes */
.text-center {
text-align: center;
}
.hidden {
display: none;
}
/* Responsive Design - Example of a simple breakpoint */
@media (max-width: 768px) {
html {
font-size: 14px; // Smaller font size on smaller screens
}
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5em;
font-weight: 600;
color: var(--text-color);
}
h1 { font-size: 2.25rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.5rem; }
h4 { font-size: 1.2rem; }
h5 { font-size: 1rem; }
h6 { font-size: 0.85rem; }
p {
margin-top: 0;
margin-bottom: 1em;
}
a {
color: var(--primary);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
// Responsive font sizes
@media (max-width: 768px) {
h1 { font-size: 2rem; }
h2 { font-size: 1.6rem; }
h3 { font-size: 1.4rem; }
// Adjust more as necessary
}

View File

@ -0,0 +1,79 @@
// Breakpoints
$breakpoint-xs: 599px; // Max width for mobile only
$breakpoint-sm: 600px; // Min width for tablet portrait
$breakpoint-md: 768px; // Min width for tablet landscape
$breakpoint-lg: 1024px; // Min width for desktop
$breakpoint-xl: 1440px; // Min width for large desktop
// Mixins for specific breakpoints
@mixin for-mobile-only {
@media (max-width: $breakpoint-xs) {
@content;
}
}
@mixin mobile-up {
@media (min-width: calc($breakpoint-xs + 1px)) {
@content;
}
}
@mixin for-tablet-portrait {
@media (min-width: $breakpoint-sm) and (max-width: calc($breakpoint-md - 1px)) {
@content;
}
}
@mixin tablet-portrait-down {
@media (max-width: calc($breakpoint-md - 1px)) {
@content;
}
}
@mixin tablet-up {
@media (min-width: $breakpoint-sm) {
@content;
}
}
@mixin for-tablet-landscape {
@media (min-width: $breakpoint-md) and (max-width: calc($breakpoint-lg - 1px)) {
@content;
}
}
@mixin tablet-landscape-down {
@media (max-width: calc($breakpoint-lg - 1px)) {
@content;
}
}
@mixin for-desktop {
@media (min-width: $breakpoint-lg) and (max-width: calc($breakpoint-xl - 1px)) {
@content;
}
}
@mixin desktop-down {
@media (max-width: calc($breakpoint-xl - 1px)) {
@content;
}
}
@mixin for-large-desktop {
@media (min-width: $breakpoint-xl) {
@content;
}
}
@mixin large-desktop-up {
@media (min-width: $breakpoint-xl) {
@content;
}
}
@mixin mobile-down {
@media (max-width: $breakpoint-xs) {
@content;
}
}

View File

@ -0,0 +1,62 @@
@font-face {
font-family: 'Inter';
src: url('../assets/fonts/Inter-Thin.ttf') format('truetype');
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'Inter';
src: url('../assets/fonts/Inter-ExtraLight.ttf') format('truetype');
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'Inter';
src: url('../assets/fonts/Inter-Light.ttf') format('truetype');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Inter';
src: url('../assets/fonts/Inter-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Inter';
src: url('../assets/fonts/Inter-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Inter';
src: url('../assets/fonts/Inter-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Inter';
src: url('../assets/fonts/Inter-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Inter';
src: url('../assets/fonts/Inter-ExtraBold.ttf') format('truetype');
font-weight: 800;
font-style: normal;
}
@font-face {
font-family: 'Inter';
src: url('../assets/fonts/Inter-Black.ttf') format('truetype');
font-weight: 900;
font-style: normal;
}

View File

@ -1,24 +1,34 @@
import { Routes, Route, Outlet } from "react-router-dom";
import { Routes, Route, Outlet } from 'react-router-dom';
import Home from 'web-check-live/views/Home.tsx';
import Results from 'web-check-live/views/Results.tsx';
import About from 'web-check-live/views/About.tsx';
import NotFound from 'web-check-live/views/NotFound.tsx';
import ErrorBoundary from 'web-check-live/components/boundaries/PageError.tsx';
import GlobalStyles from './styles/globals.tsx';
export default function App() {
return (
<Routes>
<Route path="/check" element={<Layout />}>
<Route index element={<Home />} />
<Route path="home" element={<Home />} />
<Route path="about" element={<About />} />
<Route path=":urlToScan" element={<Results />} />
<Route path="*" element={<NotFound />} />
</Route>
</Routes>
<ErrorBoundary>
<Routes>
<Route path="/check" element={<Layout />}>
<Route index element={<Home />} />
<Route path="home" element={<Home />} />
<Route path="about" element={<About />} />
<Route path=":urlToScan" element={<Results />} />
<Route path="*" element={<NotFound />} />
</Route>
</Routes>
</ErrorBoundary>
);
}
function Layout() {
return (<Outlet />);
return (
<>
<GlobalStyles />
<Outlet />
</>
);
}

View File

@ -1,7 +1,6 @@
import { BrowserRouter } from "react-router-dom";
import { StaticRouter } from "react-router-dom/server";
import App from "./App.tsx";
// import "./App.css";
export default ({ pathname }: { pathname: string }) => (
import.meta.env.SSR

View File

@ -9,7 +9,10 @@ const GlobalStyles = () => (
font-weight: 400;
src: url('/fonts/PTMono.ttf') format('ttf');
}
body { font-family: PTMono; }
body, div, a, p, span, ul, li, small, h1, h2, h3, h4, button, section {
font-family: PTMono;
color: #fff;
}
`}
/>
);