Compare commits
10 commits
44bd7f49d8
...
fb9d9dc193
| Author | SHA1 | Date | |
|---|---|---|---|
| fb9d9dc193 | |||
| 0c571c68bd | |||
| b5254425a1 | |||
| 0a706d7032 | |||
| 3c21f680e0 | |||
| 0705772ef6 | |||
| 8b468d2bb6 | |||
| 5be0ee02d3 | |||
| fc14384ba5 | |||
| 52af1cde2e |
18 changed files with 251 additions and 774 deletions
19
LICENSE
Normal file
19
LICENSE
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
99
README.md
99
README.md
|
|
@ -1,36 +1,89 @@
|
|||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Getting Started
|
||||
# hangerthem.com
|
||||
|
||||
First, run the development server:
|
||||
Welcome to my personal portfolio repository, **hangerthem.com**. This webpage is a showcase of my skills and projects, providing a glimpse into who I am and what I do.
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
## Project Overview
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
**hangerthem.com** is a fully custom-designed and coded personal portfolio website. It highlights my skills, projects, and personal information in a clean, responsive layout. The site is built with Next.js and styled-components, and it includes a reCaptcha implementation for secure email communication.
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
## Features
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||
- Fully custom design and code
|
||||
- Built with Next.js and styled-components
|
||||
- reCaptcha implemented for secure email sending
|
||||
- Responsive design for all device sizes
|
||||
- Easy navigation with a fixed navbar
|
||||
|
||||
## Learn More
|
||||
## Installation Instructions
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
To run this project locally, you will need Node.js (or Bun) installed on your machine. Follow these steps:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
1. **Clone the repository:**
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
```bash
|
||||
git clone https://github.com/HangerThem/hangerthem.com.git
|
||||
cd hangerthem.com
|
||||
```
|
||||
|
||||
## Deploy on Vercel
|
||||
2. **Install dependencies:**
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
```bash
|
||||
npm install
|
||||
# or
|
||||
yarn install
|
||||
# or
|
||||
pnpm install
|
||||
# or
|
||||
bun install
|
||||
```
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
3. **Set up environment variables:**
|
||||
Create a `.env` file in the root directory and add the required environment variables. (Contact me if you need specific details about these variables.)
|
||||
|
||||
4. **Run the development server:**
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
||||
|
||||
## Usage
|
||||
|
||||
The portfolio is a single-page application with a navbar for easy navigation between sections. It is fully responsive and works well on all device sizes.
|
||||
|
||||
### Lighthouse Report
|
||||
|
||||

|
||||
|
||||
## Contributing
|
||||
|
||||
This is a personal portfolio, so contributions are not expected. However, if you find any issues or have suggestions, feel free to open an issue or contact me directly.
|
||||
|
||||
## License
|
||||
|
||||
This project is open source and available under the [MIT License](LICENSE).
|
||||
|
||||
## Contact Information
|
||||
|
||||
You can contact me through the contact form on the website or directly via email at [f.borisjuk@hangerthem.com](mailto:f.borisjuk@hangerthem.com).
|
||||
|
||||
## Additional Information
|
||||
|
||||
For any other information or inquiries, please feel free to reach out through the provided contact methods.
|
||||
|
|
|
|||
|
|
@ -2,31 +2,12 @@ import {
|
|||
successResponse,
|
||||
optionsResponse,
|
||||
badRequestResponse,
|
||||
tooManyRequestsResponse,
|
||||
internalServerErrorResponse,
|
||||
} from "@/helpers/apiHelper"
|
||||
import { NextRequest, NextResponse } from "next/server"
|
||||
import { sendEmail } from "@/utils/emailUtils"
|
||||
import rateLimit from "express-rate-limit"
|
||||
|
||||
const limiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000,
|
||||
max: 100,
|
||||
message: "Too many requests, please try again later.",
|
||||
})
|
||||
|
||||
export async function POST(req: NextRequest, res: NextResponse) {
|
||||
if (process.env.NODE_ENV !== "development") {
|
||||
await new Promise((resolve, reject) => {
|
||||
limiter(req, res, (result: any) => {
|
||||
if (result instanceof Error) {
|
||||
return tooManyRequestsResponse()
|
||||
}
|
||||
resolve(result)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
const { email, name, message, recaptchaToken } = await req.json()
|
||||
|
||||
|
|
@ -56,7 +37,7 @@ export async function POST(req: NextRequest, res: NextResponse) {
|
|||
text: message,
|
||||
})
|
||||
|
||||
return successResponse("Email sent successfully")
|
||||
return successResponse({ message: "Email sent successfully" })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return internalServerErrorResponse()
|
||||
|
|
|
|||
|
|
@ -33,12 +33,12 @@ export const metadata: Metadata = {
|
|||
alternateLocale: ["cs_CZ"],
|
||||
countryName: "Czechia",
|
||||
emails: ["f.borisjuk@hangerthem.com"],
|
||||
images: ["https://hangerthem.com/hangerthem.png"],
|
||||
url: "https://hangerthem.com",
|
||||
determiner: "auto",
|
||||
ttl: 604800,
|
||||
audio: [],
|
||||
faxNumbers: [],
|
||||
images: [],
|
||||
phoneNumbers: [],
|
||||
videos: [],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ export default function About() {
|
|||
I've built{" "}
|
||||
<Link
|
||||
href="https://github.com/HangerThem/linkboard"
|
||||
aria-label="Linkboard a cool alternative to Linktree"
|
||||
referrerPolicy="no-referrer"
|
||||
target="_blank"
|
||||
>
|
||||
|
|
@ -98,6 +99,7 @@ export default function About() {
|
|||
, a cool alternative to Linktree, and I'm currently developing{" "}
|
||||
<Link
|
||||
href="https://github.com/HangerThem/ephemr"
|
||||
aria-label="Ephemr a simple social network"
|
||||
referrerPolicy="no-referrer"
|
||||
target="_blank"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ export default function Contact() {
|
|||
<button
|
||||
type="submit"
|
||||
disabled={!data.name || !data.email || !data.message || loading}
|
||||
aria-label="Send email"
|
||||
>
|
||||
{loading ? "Sending..." : "Send"}
|
||||
</button>
|
||||
|
|
@ -123,6 +124,7 @@ export default function Contact() {
|
|||
<SocialMedia>
|
||||
<Link
|
||||
href="https://www.instagram.com/ferda_borisjuk/"
|
||||
arial-label="Contact Frank Borisjuk on Instagram"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
|
|
@ -130,6 +132,7 @@ export default function Contact() {
|
|||
</Link>
|
||||
<Link
|
||||
href="https://github.com/HangerThem"
|
||||
arial-label="Contact Frank Borisjuk on GitHub"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
|
|
@ -137,6 +140,7 @@ export default function Contact() {
|
|||
</Link>
|
||||
<Link
|
||||
href="https://discord.com/users/495134242825699328"
|
||||
arial-label="Contact Frank Borisjuk on Discord"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
|
|
@ -144,6 +148,7 @@ export default function Contact() {
|
|||
</Link>
|
||||
<Link
|
||||
href="https://www.linkedin.com/in/franti%C5%A1ek-borisjuk-022686225/"
|
||||
arial-label="Contact Frank Borisjuk on LinkedIn"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -41,12 +41,20 @@ export default function Footer() {
|
|||
<FooterContent>
|
||||
<p>
|
||||
Made with ❤️ by{" "}
|
||||
<Link href="https://github.com/HangerThem">Frank Borisjuk</Link>
|
||||
<Link
|
||||
href="https://github.com/HangerThem"
|
||||
aria-label="Frank Borisjuk's GitHub"
|
||||
>
|
||||
Frank Borisjuk
|
||||
</Link>
|
||||
</p>
|
||||
<p>© 2024 - All rights reserved</p>
|
||||
<p>
|
||||
Sources available on{" "}
|
||||
<Link href="https://github.com/HangerThem/hangerthem.com">
|
||||
<Link
|
||||
href="https://github.com/HangerThem/hangerthem.com"
|
||||
aria-label="This site's repository on GitHub"
|
||||
>
|
||||
GitHub
|
||||
</Link>
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -348,7 +348,9 @@ const Navbar = () => {
|
|||
<NavbarContainer>
|
||||
<Topbar>
|
||||
<Title>
|
||||
<Link href="/">HangerThem</Link>
|
||||
<Link href="/" aria-label="HangerThem's Home Page">
|
||||
HangerThem
|
||||
</Link>
|
||||
</Title>
|
||||
<HamburgerWrapper
|
||||
ref={hanburgerRef}
|
||||
|
|
@ -364,6 +366,7 @@ const Navbar = () => {
|
|||
<li key={link.id}>
|
||||
<Link
|
||||
href={link.href}
|
||||
arial-label={link.text}
|
||||
className={navState.activeTag === link.id ? "active" : ""}
|
||||
onClick={() =>
|
||||
setNavState((prev) => ({ ...prev, activeTag: link.id }))
|
||||
|
|
@ -376,7 +379,11 @@ const Navbar = () => {
|
|||
</LinksContainer>
|
||||
<SocialLinksContainer>
|
||||
{socialLinks.map((socialLink) => (
|
||||
<Link key={socialLink.id} href={socialLink.href}>
|
||||
<Link
|
||||
key={socialLink.id}
|
||||
href={socialLink.href}
|
||||
aria-label={socialLink.text}
|
||||
>
|
||||
{socialLink.icon}
|
||||
{socialLink.text}
|
||||
</Link>
|
||||
|
|
|
|||
|
|
@ -11,10 +11,12 @@ import { Container, Content } from "@/styles/pageStyles"
|
|||
const CarouselWrapper = styled.div`
|
||||
display: flex;
|
||||
transition: transform 0.5s ease-in-out;
|
||||
gap: 2rem;
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: 1rem;
|
||||
|
||||
@media (min-width: 1250px) {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
`
|
||||
|
|
@ -25,9 +27,9 @@ const CarouselContainer = styled.div`
|
|||
`
|
||||
|
||||
const ProjectCard = styled.div`
|
||||
padding: 2rem;
|
||||
width: 400px;
|
||||
height: 600px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
|
|
@ -40,7 +42,7 @@ const ProjectCard = styled.div`
|
|||
font-size: 2rem;
|
||||
font-weight: 600;
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@media (min-width: 1250px) {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
|
@ -49,20 +51,18 @@ const ProjectCard = styled.div`
|
|||
font-size: 1.2rem;
|
||||
font-weight: 400;
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@media (min-width: 1250px) {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
height: auto;
|
||||
min-height: 150px;
|
||||
max-height: 200px;
|
||||
object-fit: contain;
|
||||
border-radius: 1rem;
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
height: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.active) {
|
||||
|
|
@ -70,15 +70,16 @@ const ProjectCard = styled.div`
|
|||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding: 1rem;
|
||||
@media (min-width: 1250px) {
|
||||
padding: 2rem;
|
||||
width: 400px;
|
||||
height: 550px;
|
||||
}
|
||||
`
|
||||
|
||||
const NavigationButton = styled.button`
|
||||
position: absolute;
|
||||
display: none;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
border: none;
|
||||
|
|
@ -93,17 +94,17 @@ const NavigationButton = styled.button`
|
|||
color: rgb(var(--white));
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
display: none;
|
||||
@media (min-width: 1250px) {
|
||||
display: block;
|
||||
}
|
||||
`
|
||||
|
||||
const PrevButton = styled(NavigationButton)`
|
||||
left: 0;
|
||||
left: -0.25rem;
|
||||
`
|
||||
|
||||
const NextButton = styled(NavigationButton)`
|
||||
right: 0;
|
||||
right: -0.25rem;
|
||||
`
|
||||
|
||||
const CarouselIndicator = styled.div`
|
||||
|
|
@ -112,7 +113,7 @@ const CarouselIndicator = styled.div`
|
|||
gap: 0.5rem;
|
||||
margin-top: 1rem;
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@media (min-width: 1250px) {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
`
|
||||
|
|
@ -128,7 +129,7 @@ const IndicatorDot = styled.div`
|
|||
background-color: rgb(var(--white));
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@media (min-width: 1250px) {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
|
@ -146,7 +147,7 @@ const TechStack = styled.div`
|
|||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@media (min-width: 1250px) {
|
||||
font-size: 0.7rem;
|
||||
padding: 0.2rem 0.4rem;
|
||||
}
|
||||
|
|
@ -173,9 +174,10 @@ const ViewLink = styled(Link)`
|
|||
|
||||
&:hover {
|
||||
background-color: rgb(var(--primary));
|
||||
color: rgb(var(--white));
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@media (min-width: 1250px) {
|
||||
font-size: 1rem;
|
||||
padding: 0.4rem 0.8rem;
|
||||
}
|
||||
|
|
@ -191,7 +193,7 @@ const SourceLink = styled(Link)`
|
|||
color: rgb(var(--white));
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@media (min-width: 1250px) {
|
||||
svg {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
|
|
@ -269,6 +271,7 @@ const Projects = () => {
|
|||
href={project.href}
|
||||
target="_blank"
|
||||
title="View Project"
|
||||
arial-label="View Project"
|
||||
>
|
||||
View Project
|
||||
</ViewLink>
|
||||
|
|
@ -277,6 +280,7 @@ const Projects = () => {
|
|||
href={project.source}
|
||||
target="_blank"
|
||||
title="View Source"
|
||||
arial-label="View Source"
|
||||
>
|
||||
<Git size={30} />
|
||||
</SourceLink>
|
||||
|
|
@ -284,10 +288,10 @@ const Projects = () => {
|
|||
</ProjectCard>
|
||||
))}
|
||||
</CarouselWrapper>
|
||||
<PrevButton onClick={handlePrev}>
|
||||
<PrevButton onClick={handlePrev} aria-label="Previous Project">
|
||||
<CaretLeftFill size={50} />
|
||||
</PrevButton>
|
||||
<NextButton onClick={handleNext}>
|
||||
<NextButton onClick={handleNext} aria-label="Next Project">
|
||||
<CaretRightFill size={50} />
|
||||
</NextButton>
|
||||
<CarouselIndicator>
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ export default function Skills() {
|
|||
<Categories>
|
||||
{skills.languages && (
|
||||
<SkillCategory>
|
||||
<h4>Languages</h4>
|
||||
<h3>Languages</h3>
|
||||
<ul>
|
||||
{skills.languages.map((language, index) => (
|
||||
<li key={index}>
|
||||
|
|
@ -115,7 +115,7 @@ export default function Skills() {
|
|||
)}
|
||||
{skills.programmingLanguages && (
|
||||
<SkillCategory>
|
||||
<h4>Programming Languages</h4>
|
||||
<h3>Programming Languages</h3>
|
||||
<ul>
|
||||
{skills.programmingLanguages.map(
|
||||
(programmingLanguage, index) => (
|
||||
|
|
@ -132,7 +132,7 @@ export default function Skills() {
|
|||
)}
|
||||
{skills.technologies && (
|
||||
<SkillCategory>
|
||||
<h4>Technologies</h4>
|
||||
<h3>Technologies</h3>
|
||||
<ul>
|
||||
{skills.technologies.map((technology, index) => (
|
||||
<li key={index}>
|
||||
|
|
@ -147,7 +147,7 @@ export default function Skills() {
|
|||
)}
|
||||
{skills.tools && (
|
||||
<SkillCategory>
|
||||
<h4>Tools</h4>
|
||||
<h3>Tools</h3>
|
||||
<ul>
|
||||
{skills.tools.map((tool, index) => (
|
||||
<li key={index}>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ const projects: Project[] = [
|
|||
{
|
||||
title: "HangerThem Portfolio",
|
||||
description: "This very website and my personal portfolio.",
|
||||
// image: "/hangerthem.png",
|
||||
image: "/hangerthem.png",
|
||||
techStack: ["Next.js", "TypeScript", "Styled Components"],
|
||||
href: "https://hangerthem.com",
|
||||
source: "https://github.com/HangerThem/hangerthem.com",
|
||||
|
|
@ -58,6 +58,16 @@ const projects: Project[] = [
|
|||
source: "https://github.com/HangerThem/ephemeris",
|
||||
state: "done",
|
||||
},
|
||||
{
|
||||
title: "Lighthouse SVG report",
|
||||
description: "A simple SVG report generator for Lighthouse reports.",
|
||||
image:
|
||||
"https://lighthouse-report-svg.vercel.app/?perf=100&acc=92&best=100&seo=100&pwa=0",
|
||||
techStack: ["TypeScript", "Node.js", "Express"],
|
||||
href: "https://lighthouse-report-svg.vercel.app",
|
||||
source: "https://github.com/HangerThem/lighthouse-report-svg",
|
||||
state: "done",
|
||||
},
|
||||
{
|
||||
title: "Evolution algorithm Flappy Bird",
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -36,10 +36,6 @@ export function badRequestResponse(errorMessage?: string | {}) {
|
|||
return jsonResponse(400, { error: errorMessage ?? "Bad request" })
|
||||
}
|
||||
|
||||
export function tooManyRequestsResponse() {
|
||||
return jsonResponse(429, { error: "Too many requests" })
|
||||
}
|
||||
|
||||
export function internalServerErrorResponse() {
|
||||
return jsonResponse(500, { error: "Internal server error" })
|
||||
}
|
||||
|
|
|
|||
5
next-sitemap.config.js
Normal file
5
next-sitemap.config.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
/** @type {import('next-sitemap').IConfig} */
|
||||
module.exports = {
|
||||
siteUrl: process.env.SITE_URL || "https://example.com",
|
||||
generateRobotsTxt: true,
|
||||
}
|
||||
|
|
@ -1,4 +1,14 @@
|
|||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {};
|
||||
const nextConfig = {
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
hostname: "lighthouse-report-svg.vercel.app",
|
||||
protocol: "https",
|
||||
},
|
||||
],
|
||||
dangerouslyAllowSVG: true,
|
||||
},
|
||||
}
|
||||
|
||||
export default nextConfig;
|
||||
export default nextConfig
|
||||
|
|
|
|||
738
package-lock.json
generated
738
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -5,15 +5,16 @@
|
|||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"postbuild": "next-sitemap",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/analytics": "^1.3.1",
|
||||
"canvas-confetti": "^1.9.3",
|
||||
"express-rate-limit": "^7.4.0",
|
||||
"next": "14.1.0",
|
||||
"next-recaptcha-v3": "^1.4.1",
|
||||
"next-sitemap": "^4.2.3",
|
||||
"nodemailer": "^6.9.14",
|
||||
"react": "^18",
|
||||
"react-bootstrap-icons": "^1.11.4",
|
||||
|
|
|
|||
BIN
public/hangerthem.png
Normal file
BIN
public/hangerthem.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 529 KiB |
|
|
@ -4,9 +4,9 @@ import { createGlobalStyle } from "styled-components"
|
|||
|
||||
export const GlobalStyle = createGlobalStyle`
|
||||
:root {
|
||||
--primary: 201, 14, 14;
|
||||
--primary: 239, 31, 31;
|
||||
--white: 255, 255, 255;
|
||||
--black: 0, 0, 0;
|
||||
--black: 5, 5, 5;
|
||||
--background: 217, 217, 217;
|
||||
--accent: 104, 104, 104;
|
||||
}
|
||||
|
|
@ -56,4 +56,8 @@ export const GlobalStyle = createGlobalStyle`
|
|||
color: rgb(var(--primary), 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
.grecaptcha-badge {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
`
|
||||
|
|
|
|||
Loading…
Reference in a new issue