diff --git a/src/app/components/footer/copyright.tsx b/src/app/components/footer/copyright.tsx
index bf92e0b6..edbd5ca7 100644
--- a/src/app/components/footer/copyright.tsx
+++ b/src/app/components/footer/copyright.tsx
@@ -1,7 +1,24 @@
+import Link from 'next/link';
export default function CopyRight() {
return (
-
- © 2024 Ashref Gwader. All rights reserved
-
+ <>
+
+ © 2024 Ashref Gwader. All rights reserved
+
+
+
+ Terms
+
+
+ Privacy
+
+
+ >
);
}
diff --git a/src/app/components/mdx/styled-mdx.tsx b/src/app/components/mdx/styled-mdx.tsx
index 9e6e2520..2e23ba14 100644
--- a/src/app/components/mdx/styled-mdx.tsx
+++ b/src/app/components/mdx/styled-mdx.tsx
@@ -3,6 +3,7 @@ import { Link } from '@/app/components/reusables/link';
import { Image, Skeleton } from '@nextui-org/react';
import { cn } from '@/lib/utils';
import NextImage from 'next/image';
+import { Divider as _Divider } from '@nextui-org/react';
import CodeBlock from '@/app/components/reusables/code-block';
import {
Heading2,
@@ -27,6 +28,7 @@ export default function StyledMDX({ source }: { source: string }) {
S3: Spacer3,
C: TextContent,
L: Link,
+ D: Divider,
}}
>
);
@@ -34,7 +36,9 @@ export default function StyledMDX({ source }: { source: string }) {
function _StyledMDX({ components, ...props }: MDXRemoteProps) {
return ;
}
-
+export function Divider() {
+ return <_Divider orientation="horizontal" />;
+}
type MDXImageProps = {
alt: string;
width: string;
@@ -44,7 +48,7 @@ type MDXImageProps = {
};
export function MDXImage(props: MDXImageProps) {
return (
-
+
+
{
)}
>
-
+
Home
Blog
About
@@ -35,7 +38,7 @@ const Nav = () => {
{' '}
- Contact
+ Contact
diff --git a/src/app/components/nav/new-nav.tsx b/src/app/components/nav/new-nav.tsx
new file mode 100644
index 00000000..c5140aeb
--- /dev/null
+++ b/src/app/components/nav/new-nav.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+
+const NewNav: React.FC = () => {
+ return (
+
+
+ {/* Content for id1 */}
+
+
+ {/* Content for id1 */}
+
+
+ {/* Content for id2 */}
+
+
+ {/* Content for id3 */}
+
+
+ );
+};
+
+export default NewNav;
diff --git a/src/app/components/protos/about-me1.tsx b/src/app/components/protos/about-me1.tsx
new file mode 100644
index 00000000..4049e406
--- /dev/null
+++ b/src/app/components/protos/about-me1.tsx
@@ -0,0 +1,198 @@
+/* eslint-disable */
+import React, { SVGProps } from 'react';
+
+import Link from 'next/link';
+import { Input } from '@/app/components/ui/input';
+import { Textarea } from '@/app/components/ui/textarea';
+import { Button } from '@/app/components/ui/button';
+
+export default function Component() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ Jane Doe
+
+
Product Designer
+
+
+
+ User experience enthusiast with a passion for designing beautiful
+ and functional interfaces. I believe in the power of simplicity to
+ create delightful user experiences.
+
+
+
+
+
+
+
+
+ Skills
+
+
+ UI/UX Design
+ Wireframing
+ Prototyping
+ Interaction Design
+ Usability Testing
+ Design Thinking
+
+
+
+
+ Experience
+
+
+
+ Senior Designer
+ Acme Inc
+
+ 2020 - Present
+
+
+
+ Lead Designer
+ Beta Co
+
+ 2016 - 2020
+
+
+
+
+
+
+ Education
+
+
+
+ Master of Design
+ Paradise University
+
+ 2014 - 2016
+
+
+
+ Bachelor of Arts
+ Horizon College
+
+ 2010 - 2013
+
+
+
+
+
+
+
+
+
+ Contact
+
+
+ Reach out to me for collaboration or inquiries.
+
+
+
+
+
+
+
Email
+
janedoe@example.com
+
+
+
+
+
+
Phone
+
+1 (123) 456-7890
+
+
+
+
+
+
+
+ Tweet Me
+
+
+
+
+
+ );
+}
+
+function MailIcon(props: SVGProps
) {
+ return (
+
+
+
+
+ );
+}
+
+function PhoneIcon(props: SVGProps) {
+ return (
+
+
+
+ );
+}
+interface TwitterIcon extends SVGProps {}
+
+function TwitterIcon(props: TwitterIcon) {
+ return (
+
+
+
+ );
+}
diff --git a/src/app/components/protos/about-me2.tsx b/src/app/components/protos/about-me2.tsx
new file mode 100644
index 00000000..25a3d602
--- /dev/null
+++ b/src/app/components/protos/about-me2.tsx
@@ -0,0 +1,92 @@
+/* eslint-disable */
+
+export default function Component() {
+ return (
+
+
+
+
+
+ About Me
+
+
+ Hi, I'm a passionate software engineer with a love for creating
+ elegant solutions to complex problems. My experience spans various
+ domains, from web development to cloud computing. I'm always eager
+ to learn new technologies and frameworks to stay ahead in the
+ ever-evolving tech landscape.
+
+
+
+
Skills
+
+
+ JavaScript
+
+
+ React
+
+
+ Node.js
+
+
+ TypeScript
+
+
+ AWS
+
+
+ Docker
+
+
+
+
+
Experience
+
+
+
Senior Frontend Engineer
+
+ Leading the development of a next-generation customer
+ engagement platform.
+
+
+
+
Cloud Architect
+
+ Designing scalable and secure cloud infrastructure for
+ enterprise clients.
+
+
+
+
+
+
Education
+
+
Bachelor of Computer Science
+
+ University of Science and Technology
+
+
+
+
+ Certified AWS Solutions Architect
+
+
+ Amazon Web Services
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/components/protos/contact-me1.tsx b/src/app/components/protos/contact-me1.tsx
new file mode 100644
index 00000000..02571a85
--- /dev/null
+++ b/src/app/components/protos/contact-me1.tsx
@@ -0,0 +1,107 @@
+/* eslint-disable */
+import React, { SVGProps } from 'react';
+
+import Link from 'next/link';
+import { Input } from '@/app/components/ui/input';
+import { Textarea } from '@/app/components/ui/textarea';
+import { Button } from '@/app/components/ui/button';
+
+export default function Component() {
+ return (
+
+
+
+
+ Acme Inc
+
+
+
+ Features
+
+
+ Pricing
+
+
+ About
+
+
+ Contact
+
+
+
+
+
+
+
+
+
+ Let's work together
+
+
+ I'm available for freelance work. Please fill out the form
+ below and I'll get back to you as soon as possible.
+
+
+
+
+
+
+
+
+
+ );
+}
+interface MountainIconProps extends SVGProps {}
+
+function MountainIcon(props: MountainIconProps) {
+ return (
+
+
+
+ );
+}
diff --git a/src/app/components/protos/hero-section.tsx b/src/app/components/protos/hero-section.tsx
new file mode 100644
index 00000000..b8fd4ea2
--- /dev/null
+++ b/src/app/components/protos/hero-section.tsx
@@ -0,0 +1,26 @@
+/* eslint-disable */
+import { Button } from '../ui/button';
+import { TextContent } from '../reusables/content';
+export default function HeroSection() {
+ return (
+
+
+
+
+
+ Discover Your Next Adventure aez
+
+
+ Explore our collection of unique destinations and experiences
+
+
+
+
+ Let's work together
+
+
+
+
+
+ );
+}
diff --git a/src/app/components/protos/my-services.tsx b/src/app/components/protos/my-services.tsx
new file mode 100644
index 00000000..43c4c032
--- /dev/null
+++ b/src/app/components/protos/my-services.tsx
@@ -0,0 +1,262 @@
+/* eslint-disable */
+import React, { SVGProps } from 'react';
+
+export default function Component() {
+ return (
+
+
+
+
+
+ Our Services
+
+
+
+ Expert Consulting. Custom Solutions.
+
+
+ Our team of experts is here to help you succeed. From
+ architecting scalable APIs to designing beautiful user
+ interfaces, we have the skills and experience to bring your
+ ideas to life.
+
+
+
+
+
+
+
+
Managed Databases
+
+ Focus on your apps, not your databases. Let us handle the
+ maintenance, backups, and updates.
+
+
+
+
+
Cloud Architecture
+
+ Migrate to the cloud with confidence. Our team can help you design
+ and deploy a scalable, secure architecture.
+
+
+
+
+
Code Review
+
+ Catch bugs before they reach production. Our experts will review
+ your code and provide actionable feedback.
+
+
+
+
+
API Development
+
+ Build the foundation of your app. We can create custom APIs to
+ power your frontend or mobile app.
+
+
+
+
+
Rust Consulting
+
+ Embrace the power of Rust. Our Rustaceans can help you write safe,
+ fast, and concurrent code.
+
+
+
+
+
Python Consulting
+
+ Supercharge your Python projects. Our experts can optimize
+ performance, squash bugs, and add new features.
+
+
+
+
+
Design System
+
+ Create a cohesive user experience. Our designers can craft a
+ custom design system for your app.
+
+
+
+
+
App Store Submission
+
+ Get your app in the hands of users. We'll handle the app store
+ submission process for iOS and Android.
+
+
+
+
+
+ );
+}
+
+function AppleIcon(props: IconProps) {
+ return (
+
+
+
+
+ );
+}
+
+function CloudIcon(props: IconProps) {
+ return (
+
+
+
+ );
+}
+
+function CodeIcon(props: IconProps) {
+ return (
+
+
+
+
+ );
+}
+
+function ComponentIcon(props: IconProps) {
+ return (
+
+
+
+
+
+
+ );
+}
+
+function DatabaseIcon(props: IconProps) {
+ return (
+
+
+
+
+
+ );
+}
+
+function KeyIcon(props: IconProps) {
+ return (
+
+
+
+
+
+ );
+}
+
+function PiIcon(props: IconProps) {
+ return (
+
+
+
+
+
+ );
+}
+interface IconProps extends SVGProps {}
+
+function RadiationIcon(props: IconProps) {
+ return (
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/components/protos/our-services.tsx b/src/app/components/protos/our-services.tsx
new file mode 100644
index 00000000..6ad45199
--- /dev/null
+++ b/src/app/components/protos/our-services.tsx
@@ -0,0 +1,56 @@
+/* eslint-disable */
+export default function OurServices() {
+ return (
+
+
+
+
+ Our Services
+
+
+ Let our experts guide your team to faster, more reliable software
+ delivery.
+
+
+
+
+
Cloud Migration
+
+ Move your workloads to the cloud with minimal disruption.
+
+
+
+
Continuous Integration
+
+ Automate your workflow with continuous integration.
+
+
+
+
Infrastructure as Code
+
+ Manage your infrastructure with version control.
+
+
+
+
Continuous Deployment
+
+ Automate your workflow with continuous deployment.
+
+
+
+
Site Reliability Engineering
+
+ Improve the reliability of your software systems.
+
+
+
+
DevSecOps
+
+ Integrate security into your software development process.
+
+
+
+
+
+ );
+}
diff --git a/src/app/components/protos/startup.tsx b/src/app/components/protos/startup.tsx
new file mode 100644
index 00000000..1bd98149
--- /dev/null
+++ b/src/app/components/protos/startup.tsx
@@ -0,0 +1,292 @@
+/* eslint-disable */
+import Link from 'next/link';
+import { Input } from '@/app/components/ui/input';
+import { Button } from '@/app/components/ui/button';
+import { Textarea } from '@/app/components/ui/textarea';
+import React, { SVGProps } from 'react';
+
+export default function StartUp() {
+ return (
+
+
+
+
+ Acme Inc
+
+
+
+ About
+
+
+ Services
+
+
+ Contact
+
+
+
+
+
+
+
+
+
+ Welcome to Acme Inc
+
+
+ Your trusted partner for building modern web applications
+ using the latest technologies.
+
+
+
+
+
+
+
+
+
+
+ About Us
+
+
+ We are a team of experienced developers who are passionate
+ about creating exceptional web experiences. We specialize in
+ using Next.js and React to build fast, modern, and scalable
+ web applications. Let us help you turn your ideas into
+ reality.
+
+
+
+
+
+ Subscribe
+
+
+ Sign up to get notified when we launch.
+
+ Terms & Conditions
+
+
+
+
+
+
+
+
+
+
+
+ Our Services
+
+
+ We offer a range of services to meet your needs. Whether
+ you're looking for a custom web application, an e-commerce
+ platform, or a company website, we've got you covered.
+
+
+
+
+
+
+
Custom Web Apps
+
+ Let us build a tailored web application to meet your
+ specific requirements.
+
+
+
+
+
+
+ E-commerce Platforms
+
+
+ We can create a seamless online shopping experience for
+ your customers.
+
+
+
+
+
+
Company Websites
+
+ Make a great first impression with a professional and
+ modern website.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Technologies We Use
+
+
+ We are experts in using the latest technologies to deliver
+ high-quality web applications. Our toolkit includes:
+
+
+
+
+
+
+
Next.js
+
+ The perfect framework for building fast and scalable web
+ applications.
+
+
+
+
+
+
React
+
+ The popular JavaScript library for building user
+ interfaces.
+
+
+
+
+
+
+ Backend Technologies
+
+
+ We use the latest backend technologies to power our web
+ applications.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Client Testimonials
+
+
+ Don't just take our word for it. Here's what our clients have
+ to say about our services.
+
+
+
+
+
+ Testimonial
+
+
+ Acme Inc did an amazing job building our web application.
+ The team was professional, responsive, and delivered
+ high-quality work on time. I would highly recommend their
+ services to anyone looking for a top-notch web development
+ company.
+
+
+
+
+ Testimonial
+
+
+ The Acme Inc team was a pleasure to work with. They took the
+ time to understand our requirements and provided valuable
+ insights throughout the project. The end result exceeded our
+ expectations, and we couldn't be happier with our new web
+ application.
+
+
+
+
+
+
+
+
+
+
+
+ Contact Us
+
+
+ Ready to get started? Contact us to discuss your project
+ requirements or to request a quote. We're here to help.
+
+
+
+
+
+
+
+ Submit
+
+
+
+
+
+
+
+
+ );
+}
+interface MountainIconProps extends SVGProps {}
+
+function MountainIcon(props: MountainIconProps) {
+ return (
+
+
+
+ );
+}
diff --git a/src/app/components/reusables/copy-code.tsx b/src/app/components/reusables/copy-code.tsx
index 3904f925..2f8dcbff 100644
--- a/src/app/components/reusables/copy-code.tsx
+++ b/src/app/components/reusables/copy-code.tsx
@@ -14,7 +14,7 @@ const CopyButton: FC = ({ code, className }) => {
return (
{
diff --git a/src/app/components/reusables/link.tsx b/src/app/components/reusables/link.tsx
index 25919f54..7e2ea7f2 100644
--- a/src/app/components/reusables/link.tsx
+++ b/src/app/components/reusables/link.tsx
@@ -13,7 +13,7 @@ export function Link({
return (
{props.children}
@@ -24,21 +24,11 @@ export function Link({
return (
{props.children}
-
+ ↗
);
}
diff --git a/src/app/components/reusables/loading-screen.tsx b/src/app/components/reusables/loading-screen.tsx
new file mode 100644
index 00000000..d4a1f895
--- /dev/null
+++ b/src/app/components/reusables/loading-screen.tsx
@@ -0,0 +1,14 @@
+import Loader from '@/app/components/reusables/loader';
+
+function LoadingScreen() {
+ return (
+
+
+
+ );
+}
+
+export default LoadingScreen;
diff --git a/src/app/components/ui/button.tsx b/src/app/components/ui/button.tsx
index e6dd1fc0..db5fdc47 100644
--- a/src/app/components/ui/button.tsx
+++ b/src/app/components/ui/button.tsx
@@ -9,8 +9,10 @@ const buttonVariants = cva(
{
variants: {
variant: {
+ navbar:
+ 'glowsup average-transition hover:average-translate rounded-[1.1rem] bg-primary/95 opacity-95 text-primary-foreground hover:bg-primary hover:opacity-100',
default:
- 'rounded-[1.1rem] bg-primary/95 opacity-95 text-primary-foreground hover:bg-primary hover:opacity-100 transition-all duration-300 ease-in-out',
+ 'rounded-[1.1rem] average-transition bg-primary/95 opacity-95 text-primary-foreground hover:bg-primary hover:opacity-100',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline:
diff --git a/src/app/components/ui/input.tsx b/src/app/components/ui/input.tsx
new file mode 100644
index 00000000..d2008f0b
--- /dev/null
+++ b/src/app/components/ui/input.tsx
@@ -0,0 +1,25 @@
+import * as React from 'react';
+
+import { cn } from '@/lib/utils';
+
+export interface InputProps
+ extends React.InputHTMLAttributes {}
+
+const Input = React.forwardRef(
+ ({ className, type, ...props }, ref) => {
+ return (
+
+ );
+ }
+);
+Input.displayName = 'Input';
+
+export { Input };
diff --git a/src/app/components/ui/label.tsx b/src/app/components/ui/label.tsx
new file mode 100644
index 00000000..1e24ec01
--- /dev/null
+++ b/src/app/components/ui/label.tsx
@@ -0,0 +1,26 @@
+'use client';
+
+import * as React from 'react';
+import * as LabelPrimitive from '@radix-ui/react-label';
+import { cva, type VariantProps } from 'class-variance-authority';
+
+import { cn } from '@/lib/utils';
+
+const labelVariants = cva(
+ 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'
+);
+
+const Label = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef &
+ VariantProps
+>(({ className, ...props }, ref) => (
+
+));
+Label.displayName = LabelPrimitive.Root.displayName;
+
+export { Label };
diff --git a/src/app/components/ui/separator.tsx b/src/app/components/ui/separator.tsx
new file mode 100644
index 00000000..da040615
--- /dev/null
+++ b/src/app/components/ui/separator.tsx
@@ -0,0 +1,31 @@
+'use client';
+
+import * as React from 'react';
+import * as SeparatorPrimitive from '@radix-ui/react-separator';
+
+import { cn } from '@/lib/utils';
+
+const Separator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(
+ (
+ { className, orientation = 'horizontal', decorative = true, ...props },
+ ref
+ ) => (
+
+ )
+);
+Separator.displayName = SeparatorPrimitive.Root.displayName;
+
+export { Separator };
diff --git a/src/app/components/ui/textarea.tsx b/src/app/components/ui/textarea.tsx
new file mode 100644
index 00000000..4ca06111
--- /dev/null
+++ b/src/app/components/ui/textarea.tsx
@@ -0,0 +1,24 @@
+import * as React from 'react';
+
+import { cn } from '@/lib/utils';
+
+export interface TextareaProps
+ extends React.TextareaHTMLAttributes {}
+
+const Textarea = React.forwardRef(
+ ({ className, ...props }, ref) => {
+ return (
+
+ );
+ }
+);
+Textarea.displayName = 'Textarea';
+
+export { Textarea };
diff --git a/src/app/globals.css b/src/app/globals.css
index d2587e96..8c604756 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -17,6 +17,7 @@
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 96.1%;
+ --deeper-purple: rgba(255, 46, 200, 0.25);
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
@@ -49,31 +50,50 @@
}
}
@layer utilities {
+ .average-translate {
+ @apply -translate-y-1;
+ }
+ .slower-transition {
+ transition: ease-in-out 0.2s;
+ }
+
+ .average-transition {
+ transition: ease-in-out 0.15s;
+ }
+
.dimmed-0 {
+ /* blog dates */
color: hsl(0, 0%, 48%);
}
.dimmed-1 {
+ /* blog after 'x' minutes */
color: hsl(0, 0%, 65%);
}
.dimmed-3 {
+ /* content reading */
color: hsl(0, 0%, 75%);
}
.dimmed-4 {
+ /*H2s */
color: hsl(0, 0%, 90%);
}
.dimmed-5 {
+ /* H1s */
color: hsl(0, 0%, 95%);
}
+ .glowsup:hover {
+ filter: drop-shadow(0 0 0.75rem var(--deeper-purple));
+ }
- .average-transition {
- transition: ease-in-out 0.15s;
+ .glowsup-res:hover {
+ filter: drop-shadow(0 0 0.75rem rebeccapurple);
}
- .bg-gradient::after {
+ .turn-bg-gradient::after {
content: '';
position: fixed;
left: -1px;
@@ -85,7 +105,7 @@
transition: opacity 0.5s;
}
- .bg-gradient::after {
+ .turn-bg-gradient::after {
/*If i change my mind abouut the theme I'll use this for inidividual components*/
background-image: linear-gradient(
84.16deg,
@@ -95,42 +115,46 @@
);
}
- .bg-gradient:hover::after {
+ .turn-bg-gradient:hover::after {
opacity: 1;
}
-}
-.nav-link-shadow {
- position: relative;
-}
-
-@media (min-width: 1024px) {
- .nav-link-shadow::before {
- content: '';
- position: absolute;
- height: 33px;
- width: 70px;
- z-index: -1;
- background: linear-gradient(
- 86.87deg,
- rgba(255, 0, 255, 0.3),
- rgba(150, 255, 30, 0.2)
- );
- filter: blur(25px);
- opacity: 0;
- transition: opacity 0.3s ease-out;
+ .nav-link-shadow {
+ position: relative;
}
- .nav-link-shadow:hover::before {
- opacity: 0.8;
+ @media (min-width: 1024px) {
+ .nav-link-shadow::before {
+ content: '';
+ position: absolute;
+ height: 33px;
+ width: 70px;
+ z-index: -1;
+ background: var(--deeper-purple);
+ filter: blur(25px);
+ opacity: 0;
+ transition: opacity 0.3s ease-out;
+ }
+
+ .nav-link-shadow:hover::before {
+ opacity: 0.8;
+ }
}
-}
-@keyframes nav-link-shadow {
- 0% {
- opacity: 0;
+ .gradient-text-purple {
+ /*
+ for links
+ */
+ @apply bg-gradient-to-r from-pink-500 to-purple-500 text-transparent bg-clip-text;
+ -webkit-background-clip: text; /* older browsers can get this too */
}
- 100% {
- opacity: 0.8;
+
+ @keyframes nav-link-shadow {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 0.8;
+ }
}
}
@@ -145,7 +169,7 @@
84.16deg,
rgba(150, 46, 200, 0.15),
rgba(255, 215, 111, 0.042),
- rgba(30, 17, 224, 0.1)
+ rgba(150, 0, 100, 0.1)
);
}
diff --git a/src/app/loading.tsx b/src/app/loading.tsx
index d4a1f895..f43dfc2d 100644
--- a/src/app/loading.tsx
+++ b/src/app/loading.tsx
@@ -1,14 +1,2 @@
-import Loader from '@/app/components/reusables/loader';
-
-function LoadingScreen() {
- return (
-
-
-
- );
-}
-
+import LoadingScreen from './components/reusables/loading-screen';
export default LoadingScreen;
diff --git a/src/app/page.tsx b/src/app/page.tsx
index f26126e9..f11c1af9 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,17 +1,17 @@
-'use client';
-
-import ThemeModeToggler from '@/app/components/reusables/theme-toggler';
import CopyRight from '@/app/components/footer/copyright';
-import { Button } from '@/app/components/ui/button';
import Nav from '@/app/components/nav/nav';
-import { Badge } from '@/app/components/ui/badge';
import { TextContent } from './components/reusables/content';
import { MediumSection } from './components/reusables/sections';
+import HeroSection from './components/protos/hero-section';
+import OurServices from './components/protos/our-services';
export default function Home() {
return (
<>
+
+
+
If youd like to preserve the default values for a theme option but
diff --git a/src/app/robots.ts b/src/app/robots.ts
index 9111fef8..a9134946 100644
--- a/src/app/robots.ts
+++ b/src/app/robots.ts
@@ -7,7 +7,7 @@ export default function robots(): MetadataRoute.Robots {
rules: {
userAgent: '*',
allow: '/',
- disallow: ['/private', '/xtc6'],
+ disallow: ['/private'],
},
sitemap: BASE_URL + '/sitemap.xml',
};
diff --git a/src/lib/constants.ts b/src/lib/constants.ts
index 43fdc9ee..aa8f45a4 100644
--- a/src/lib/constants.ts
+++ b/src/lib/constants.ts
@@ -1,2 +1,3 @@
export const BLOG_CONTENT_PATH = '/public/blogs';
export const BLOG_URI = '/blog';
+export const BLOG_API_URI = '/api/blogs';
diff --git a/src/lib/types/global.ts b/src/lib/types/global.ts
new file mode 100644
index 00000000..d4891800
--- /dev/null
+++ b/src/lib/types/global.ts
@@ -0,0 +1,2 @@
+export type Optional = T | null;
+export type Maybe = T | undefined;
diff --git a/src/app/(pages)/blog/_types.ts b/src/lib/types/mdx.ts
similarity index 100%
rename from src/app/(pages)/blog/_types.ts
rename to src/lib/types/mdx.ts
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 86202740..ded984a3 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -77,6 +77,7 @@ const config = {
},
plugins: [
require('tailwindcss-animate'),
+ require('@tailwindcss/typography'), // only render any mdx that's a non blog
nextui({
layout: {
disabledOpacity: '0.3',
diff --git a/test/lib/form-date.test.ts b/test/lib/form-date.test.ts
deleted file mode 100644
index 14900da1..00000000
--- a/test/lib/form-date.test.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { formatDate } from '@/lib/funcs/dates';
-
-const defaultTestDate = new Date(2024, 3, 7);
-
-beforeEach(() => {
- Date.now = jest.fn(() => defaultTestDate.getTime());
-});
-
-test('formatDate - past year', () => {
- const result = formatDate('2023-01-15');
- expect(result).toEqual('January 15, 2023 (1y ago)');
-});
-
-test('formatDate - today is a new day', () => {
- const result = formatDate('2024-03-07');
- expect(result).toEqual('March 7, 2024 (Today)');
-});
-
-test('formatDate - past months', () => {
- const result = formatDate('2024-01-01');
- expect(result).toEqual('January 1, 2024 (1mo ago)');
-});
-
-test('formatDate - Same month', () => {
- const result = formatDate('2024-02-01');
- expect(result).toEqual('February 1, 2024 (6d ago)');
-});