feat: animations, responsive design
Animations - added opacity animation for experience page - added stagger animation for navbar items on mobile - added animation for landing page for years and language indications Pages - About Page mockup Redesign - Navbar to include icons on desktop
This commit is contained in:
@@ -2,11 +2,201 @@ package components
|
||||
|
||||
templ AboutPage() {
|
||||
@rootLayout() {
|
||||
<main class="w-full h-full flex flex-col gap-0 items-center justify-center">
|
||||
<section class="flex flex-col gap-6">
|
||||
<h1 class="text-3xl">About Me</h1>
|
||||
<p class="text-base">I am a software engineer with a passion for web development. I have experience with a variety of technologies including React, Node.js, and MongoDB. I am always looking to learn new things and improve my skills.</p>
|
||||
</section>
|
||||
<main class="w-full min-h-full py-16 px-4 sm:px-6 lg:px-8">
|
||||
<div class="max-w-4xl mx-auto flex flex-col gap-16">
|
||||
<!-- Hero Section -->
|
||||
<section class="text-center flex flex-col items-center gap-6">
|
||||
<div class="relative inline-block">
|
||||
<img
|
||||
src="/assets/images/profile.jpg"
|
||||
alt="Mohammad Hariri"
|
||||
class="w-40 h-40 rounded-full object-cover border-4 border-emerald-500 shadow-xl"
|
||||
/>
|
||||
<div class="absolute -bottom-2 left-1/2 -translate-x-1/2 bg-emerald-500 text-white px-3 py-1 rounded-full text-sm font-medium whitespace-nowrap">
|
||||
Available for Work
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-4xl font-bold text-slate-100 mb-4">Your Name</h1>
|
||||
<p class="text-xl text-slate-300">Full Stack Developer & Problem Solver</p>
|
||||
</div>
|
||||
<p class="text-slate-400 max-w-2xl mx-auto">
|
||||
Passionate about crafting elegant solutions to complex problems. With expertise in modern web technologies,
|
||||
I bring ideas to life through clean code and intuitive user experiences.
|
||||
</p>
|
||||
</section>
|
||||
<!-- Journey Section -->
|
||||
<section class="bg-slate-800/50 rounded-2xl p-8 backdrop-blur-sm">
|
||||
<h2 class="text-2xl font-bold text-slate-100">My Journey</h2>
|
||||
<div class="flex flex-col gap-8 mt-6">
|
||||
<div class="flex gap-4">
|
||||
<div class="flex-shrink-0 w-1 bg-emerald-500 rounded relative">
|
||||
<div class="absolute w-3 h-3 bg-emerald-500 rounded-full -left-1 top-0"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-emerald-400">Where I Started</h3>
|
||||
<p class="text-slate-300 mt-2">
|
||||
My journey in software development began with a curiosity about how things work.
|
||||
From building simple websites to developing complex applications, every step has been a learning experience.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-4">
|
||||
<div class="flex-shrink-0 w-1 bg-emerald-500 rounded relative">
|
||||
<div class="absolute w-3 h-3 bg-emerald-500 rounded-full -left-1 top-0"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-emerald-400">Where I Am</h3>
|
||||
<p class="text-slate-300 mt-2">
|
||||
Currently, I specialize in full-stack development, focusing on creating scalable and maintainable applications.
|
||||
I'm passionate about using technology to solve real-world problems.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-4">
|
||||
<div class="flex-shrink-0 w-1 bg-emerald-500 rounded relative">
|
||||
<div class="absolute w-3 h-3 bg-emerald-500 rounded-full -left-1 top-0"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-emerald-400">Where I'm Going</h3>
|
||||
<p class="text-slate-300 mt-2">
|
||||
My goal is to continue growing as a developer while contributing to meaningful projects that make a difference.
|
||||
I'm always excited to learn new technologies and tackle new challenges.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Skills Section -->
|
||||
<section class="flex flex-col gap-6">
|
||||
<h2 class="text-2xl font-bold text-slate-100">Technical Expertise</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<div class="bg-slate-800/50 p-6 rounded-xl backdrop-blur-sm">
|
||||
<h3 class="text-lg font-semibold text-emerald-400">Frontend Development</h3>
|
||||
<ul class="flex flex-col gap-2 text-slate-300 mt-4">
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-emerald-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
React & Next.js
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-emerald-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
TypeScript
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-emerald-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
Tailwind CSS
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-slate-800/50 p-6 rounded-xl backdrop-blur-sm">
|
||||
<h3 class="text-lg font-semibold text-emerald-400">Backend Development</h3>
|
||||
<ul class="flex flex-col gap-2 text-slate-300 mt-4">
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-emerald-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
Go & Fiber
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-emerald-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
Node.js
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-emerald-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
PostgreSQL
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-slate-800/50 p-6 rounded-xl backdrop-blur-sm">
|
||||
<h3 class="text-lg font-semibold text-emerald-400">Tools & Practices</h3>
|
||||
<ul class="flex flex-col gap-2 text-slate-300 mt-4">
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-emerald-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
Git & GitHub
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-emerald-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
Docker
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<svg class="w-5 h-5 text-emerald-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
CI/CD
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Personal Section -->
|
||||
<section class="bg-slate-800/50 rounded-2xl p-8 backdrop-blur-sm">
|
||||
<h2 class="text-2xl font-bold text-slate-100 mb-6">Beyond the Code</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-emerald-400">When I'm Not Coding</h3>
|
||||
<p class="text-slate-300">
|
||||
Outside of development, I enjoy [Your Hobbies/Interests]. I believe in maintaining a healthy work-life balance
|
||||
and finding inspiration in various aspects of life.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-emerald-400">Let's Connect</h3>
|
||||
<div class="flex flex-col gap-4">
|
||||
<p class="text-slate-300">
|
||||
I'm always interested in hearing about new projects and opportunities.
|
||||
Feel free to reach out if you'd like to collaborate or just chat about technology.
|
||||
</p>
|
||||
<div class="flex gap-4">
|
||||
<a
|
||||
href="https://github.com/yourusername"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-slate-400 hover:text-emerald-500 transition-colors"
|
||||
>
|
||||
<svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="https://linkedin.com/in/yourprofile"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-slate-400 hover:text-emerald-500 transition-colors"
|
||||
>
|
||||
<svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="https://twitter.com/yourhandle"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-slate-400 hover:text-emerald-500 transition-colors"
|
||||
>
|
||||
<svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
1
components/about_page_templ.txt
Normal file
1
components/about_page_templ.txt
Normal file
File diff suppressed because one or more lines are too long
1
components/contact_page_templ.txt
Normal file
1
components/contact_page_templ.txt
Normal file
File diff suppressed because one or more lines are too long
@@ -1,46 +0,0 @@
|
||||
package components
|
||||
|
||||
import "github.com/moh682/portfolio/domain"
|
||||
import "slices"
|
||||
import "strings"
|
||||
|
||||
templ experienceCard(exp domain.Experience) {
|
||||
<section class="h-full w-full flex relative items-center">
|
||||
<div class="flex h-[600px] sm:px-12 lg:py-40 w-full items-center gap-12 justify-between">
|
||||
<!-- Left Side: Job Details -->
|
||||
<div class="p-6 w-1/2 flex flex-col gap-4 bg-slate-800 rounded-lg hover:bg-slate-800 transition-all animate-slide">
|
||||
<h3 class="text-2xl font-semibold text-white">{ exp.Job.Title }</h3>
|
||||
<div class="flex flex-col gap-2">
|
||||
<a href={ templ.SafeURL(exp.Company.Link) } class="text-emerald-400 font-medium text-lg ">{ exp.Company.Name }</a>
|
||||
<p class="text-slate-400 ">{ exp.Duration() }</p>
|
||||
<p class="text-slate-600 text-sm">{ exp.GetStartDate() } - { exp.GetEndDate() } </p>
|
||||
<a href={ templ.SafeURL(exp.Company.LocationLink) } class="text-emerald-500">{ exp.Company.City }</a>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
for _, stack := range slices.Concat(exp.Job.FrontendStack, exp.Job.BackendStack, exp.Job.InfrastructureStack) {
|
||||
@techStack(stack)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Timeline Marker -->
|
||||
<div></div>
|
||||
<!-- Right Side: Company & Role Details -->
|
||||
<div class="flex flex-col w-1/2 gap-6 p-6 bg-slate-800 rounded-lg animate-slideIn">
|
||||
<div class="flex flex-col gap-2">
|
||||
<h4 class="text-xl font-medium">About { exp.Company.Name }</h4>
|
||||
for _, description := range strings.Split(exp.Company.Description, "\n") {
|
||||
<p class="text-slate-300">
|
||||
{ description }
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<h4 class="text-xl font-medium">Role & Responsibilities</h4>
|
||||
<div class="text-slate-300 whitespace-pre-wrap">
|
||||
{ exp.Job.Description }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.833
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/moh682/portfolio/domain"
|
||||
import "slices"
|
||||
import "strings"
|
||||
|
||||
func experienceCard(exp domain.Experience) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<section class=\"h-full w-full flex relative items-center\"><div class=\"flex h-[600px] sm:px-12 lg:py-40 w-full items-center gap-12 justify-between\"><!-- Left Side: Job Details --><div class=\"p-6 w-1/2 flex flex-col gap-4 bg-slate-800 rounded-lg hover:bg-slate-800 transition-all animate-slide\"><h3 class=\"text-2xl font-semibold text-white\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Job.Title)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experience_card.templ`, Line: 12, Col: 65}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</h3><div class=\"flex flex-col gap-2\"><a href=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 templ.SafeURL = templ.SafeURL(exp.Company.Link)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var3)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\" class=\"text-emerald-400 font-medium text-lg \">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Company.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experience_card.templ`, Line: 14, Col: 113}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</a><p class=\"text-slate-400 \">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Duration())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experience_card.templ`, Line: 15, Col: 48}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</p><p class=\"text-slate-600 text-sm\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(exp.GetStartDate())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experience_card.templ`, Line: 16, Col: 59}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " - ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(exp.GetEndDate())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experience_card.templ`, Line: 16, Col: 82}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</p><a href=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 templ.SafeURL = templ.SafeURL(exp.Company.LocationLink)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var8)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\" class=\"text-emerald-500\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Company.City)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experience_card.templ`, Line: 17, Col: 100}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</a></div><div class=\"flex flex-wrap gap-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, stack := range slices.Concat(exp.Job.FrontendStack, exp.Job.BackendStack, exp.Job.InfrastructureStack) {
|
||||
templ_7745c5c3_Err = techStack(stack).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</div></div><!-- Timeline Marker --><div></div><!-- Right Side: Company & Role Details --><div class=\"flex flex-col w-1/2 gap-6 p-6 bg-slate-800 rounded-lg animate-slideIn\"><div class=\"flex flex-col gap-2\"><h4 class=\"text-xl font-medium\">About ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Company.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experience_card.templ`, Line: 30, Col: 61}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</h4>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, description := range strings.Split(exp.Company.Description, "\n") {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<p class=\"text-slate-300\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(description)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experience_card.templ`, Line: 33, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</div><div class=\"flex flex-col gap-2\"><h4 class=\"text-xl font-medium\">Role & Responsibilities</h4><div class=\"text-slate-300 whitespace-pre-wrap\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Job.Description)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experience_card.templ`, Line: 40, Col: 27}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</div></div></div></div></section>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
@@ -2,59 +2,61 @@
|
||||
package components
|
||||
|
||||
import "github.com/moh682/portfolio/domain"
|
||||
import "fmt"
|
||||
|
||||
import "slices"
|
||||
import "strings"
|
||||
|
||||
templ experienceCard(exp domain.Experience) {
|
||||
<section class="min-h-[var(--content-height)] w-full flex relative items-center">
|
||||
<!-- Left Side: Job Details -->
|
||||
<div class="p-6 flex flex-col gap-4 transition-all opacity-0">
|
||||
<h3 class="text-xl font-semibold text-white">{ exp.Job.Title }</h3>
|
||||
<div class="flex flex-col gap-2">
|
||||
<a href={ templ.SafeURL(exp.Company.Link) } class="text-emerald-400 font-medium text-lg ">{ exp.Company.Name }</a>
|
||||
<p class="text-slate-400 ">{ exp.Duration() }</p>
|
||||
<p class="text-slate-600 text-sm">{ exp.GetStartDate() } - { exp.GetEndDate() } </p>
|
||||
<a href={ templ.SafeURL(exp.Company.LocationLink) } class="text-emerald-500">{ exp.Company.City }</a>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
for _, stack := range slices.Concat(exp.Job.FrontendStack, exp.Job.BackendStack, exp.Job.InfrastructureStack) {
|
||||
@techStack(stack)
|
||||
}
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<h4 class="text-xl font-medium">About { exp.Company.Name }</h4>
|
||||
for _, description := range strings.Split(exp.Company.Description, "\n") {
|
||||
<p class="text-slate-300">
|
||||
{ description }
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<h4 class="text-xl font-medium">Role & Responsibilities</h4>
|
||||
<div class="text-slate-300 whitespace-pre-wrap">
|
||||
{ exp.Job.Description }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ ExperiencesPage(experiences []domain.Experience) {
|
||||
@rootLayout() {
|
||||
<main class="bg-gradient-to-b from-slate-900 w-full h-full to-slate-800 overflow-hidden">
|
||||
<div class="relative h-full flex w-full items-center justify-between" x-data="{active:$persist(0)}">
|
||||
<!-- Progress Indicator -->
|
||||
<div class="flex items-center px-2 top-0 h-screen z-10 ">
|
||||
<div class="flex flex-col z-100 gap-4 -translate-y-1/2">
|
||||
for i := range experiences {
|
||||
<div
|
||||
class="flex items-center justify-center pointer-events-auto py-2 px-2 hover:cursor-pointer"
|
||||
x-on:click={ fmt.Sprintf("active = %d", i) }
|
||||
>
|
||||
<div
|
||||
class={ "h-12 w-1 mb-4 transition-all duration-300 cursor-pointer hover:bg-emerald-400" }
|
||||
data-index={ templ.JSONString(i) }
|
||||
x-bind:class={ fmt.Sprintf("active == %d ? 'bg-emerald-500' : 'bg-slate-700'", i) }
|
||||
></div>
|
||||
</div>
|
||||
}
|
||||
<script defer src="assets/js/experiences.js"></script>
|
||||
<main class="bg-gradient-to-b from-slate-900 w-full to-slate-800 px-6 overflow-x-hidden">
|
||||
<div class="flex w-full items-center justify-between" x-data="{active:$persist(0)}">
|
||||
<div class="relative w-full flex items-center justify-center">
|
||||
<!-- Timeline -->
|
||||
<div id="timeline" class="fixed w-10 top-[var(--navbar-height)] left-2 h-[var(--content-height)] flex items-center justify-center">
|
||||
<div class="absolute bg-radial-[at_50%_25%] from-40% from-slate-700 h-full w-0.5 to-slate-800"></div>
|
||||
<div id="timeline-point" class={ "flex items-center flex-grow-0 justify-center w-10 h-10 rounded-full bg-emerald-900 border-4 border-slate-800 z-[80]" }>
|
||||
<div class="absolute w-2 h-2 z-[80] bg-emerald-400 rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full h-full flex items-center justify-center">
|
||||
<div class="w-full h-full items-center content-center relative xl:w-[1600px]">
|
||||
<div class="text-center py-8 animate-fade">
|
||||
<h2 class="text-3xl sm:text-4xl font-bold text-white mb-4">Professional Experience</h2>
|
||||
<p class="text-slate-400">Building and scaling software solutions that matter</p>
|
||||
</div>
|
||||
<div class="w-full h-full absolute flex items-center justify-center">
|
||||
<div class="h-full w-0.5 bg-slate-700 transform"></div>
|
||||
</div>
|
||||
<div class="h-full custom-scrollbar scroll-smooth">
|
||||
<div>
|
||||
for i, exp := range experiences {
|
||||
<div
|
||||
class={ "absolute w-full transition-all opacity-0 duration-700 ease-out translate-y-10" }
|
||||
data-experience-index={ templ.JSONString(i) }
|
||||
x-bind:class={ fmt.Sprintf("active == %d ? 'z-10 opacity-100 translate-y-0' : ' -z-10 translate-y-10'", i) }
|
||||
>
|
||||
<div class="h-full w-full">
|
||||
<div class={ fmt.Sprintf("relative flex w-full h-full items-center justify-center translate-y-[%dpx]", i*4*32) }>
|
||||
<div class="absolute animate-pulse w-16 h-16 rounded-full bg-slate-800/50 z-50"></div>
|
||||
<div class={ "flex items-center flex-grow-0 justify-center w-10 h-10 rounded-full bg-emerald-900 border-4 border-slate-800 z-[80]" }>
|
||||
<div class="absolute w-2 h-2 z-[80] bg-emerald-400 rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@experienceCard(exp)
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div id="exps-container" class="ml-4 items-center content-center relative xl:w-[1600px]">
|
||||
for _, exp := range experiences {
|
||||
@experienceCard(exp)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,9 +10,11 @@ import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/moh682/portfolio/domain"
|
||||
import "fmt"
|
||||
|
||||
func ExperiencesPage(experiences []domain.Experience) templ.Component {
|
||||
import "slices"
|
||||
import "strings"
|
||||
|
||||
func experienceCard(exp domain.Experience) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
@@ -33,7 +35,191 @@ func ExperiencesPage(experiences []domain.Experience) templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<section class=\"min-h-[var(--content-height)] w-full flex relative items-center\"><!-- Left Side: Job Details --><div class=\"p-6 flex flex-col gap-4 transition-all opacity-0\"><h3 class=\"text-xl font-semibold text-white\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Job.Title)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 13, Col: 63}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</h3><div class=\"flex flex-col gap-2\"><a href=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 templ.SafeURL = templ.SafeURL(exp.Company.Link)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var3)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\" class=\"text-emerald-400 font-medium text-lg \">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Company.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 15, Col: 112}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</a><p class=\"text-slate-400 \">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Duration())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 16, Col: 47}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</p><p class=\"text-slate-600 text-sm\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(exp.GetStartDate())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 17, Col: 58}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " - ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(exp.GetEndDate())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 17, Col: 81}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</p><a href=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 templ.SafeURL = templ.SafeURL(exp.Company.LocationLink)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var8)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\" class=\"text-emerald-500\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Company.City)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 18, Col: 99}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</a></div><div class=\"flex flex-wrap gap-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, stack := range slices.Concat(exp.Job.FrontendStack, exp.Job.BackendStack, exp.Job.InfrastructureStack) {
|
||||
templ_7745c5c3_Err = techStack(stack).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</div><div class=\"flex flex-col gap-2\"><h4 class=\"text-xl font-medium\">About ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Company.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 26, Col: 60}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</h4>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, description := range strings.Split(exp.Company.Description, "\n") {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<p class=\"text-slate-300\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(description)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 29, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</div><div class=\"flex flex-col gap-2\"><h4 class=\"text-xl font-medium\">Role & Responsibilities</h4><div class=\"text-slate-300 whitespace-pre-wrap\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(exp.Job.Description)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 36, Col: 26}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</div></div></div></section>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func ExperiencesPage(experiences []domain.Experience) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var13 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var13 == nil {
|
||||
templ_7745c5c3_Var13 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var14 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
@@ -45,190 +231,45 @@ func ExperiencesPage(experiences []domain.Experience) templ.Component {
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<main class=\"bg-gradient-to-b from-slate-900 w-full h-full to-slate-800 overflow-hidden\"><div class=\"relative h-full flex w-full items-center justify-between\" x-data=\"{active:$persist(0)}\"><!-- Progress Indicator --><div class=\"flex items-center px-2 top-0 h-screen z-10 \"><div class=\"flex flex-col z-100 gap-4 -translate-y-1/2\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<script defer src=\"assets/js/experiences.js\"></script> <main class=\"bg-gradient-to-b from-slate-900 w-full to-slate-800 px-6 overflow-x-hidden\"><div class=\"flex w-full items-center justify-between\" x-data=\"{active:$persist(0)}\"><div class=\"relative w-full flex items-center justify-center\"><!-- Timeline --><div id=\"timeline\" class=\"fixed w-10 top-[var(--navbar-height)] left-2 h-[var(--content-height)] flex items-center justify-center\"><div class=\"absolute bg-radial-[at_50%_25%] from-40% from-slate-700 h-full w-0.5 to-slate-800\"></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for i := range experiences {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<div class=\"flex items-center justify-center pointer-events-auto py-2 px-2 hover:cursor-pointer\" x-on:click=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("active = %d", i))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 17, Col: 50}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 = []any{"h-12 w-1 mb-4 transition-all duration-300 cursor-pointer hover:bg-emerald-400"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var4).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" data-index=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(templ.JSONString(i))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 21, Col: 41}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\" x-bind:class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("active == %d ? 'bg-emerald-500' : 'bg-slate-700'", i))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 22, Col: 90}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\"></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</div></div><div class=\"w-full h-full flex items-center justify-center\"><div class=\"w-full h-full items-center content-center relative xl:w-[1600px]\"><div class=\"text-center py-8 animate-fade\"><h2 class=\"text-3xl sm:text-4xl font-bold text-white mb-4\">Professional Experience</h2><p class=\"text-slate-400\">Building and scaling software solutions that matter</p></div><div class=\"w-full h-full absolute flex items-center justify-center\"><div class=\"h-full w-0.5 bg-slate-700 transform\"></div></div><div class=\"h-full custom-scrollbar scroll-smooth\"><div>")
|
||||
var templ_7745c5c3_Var15 = []any{"flex items-center flex-grow-0 justify-center w-10 h-10 rounded-full bg-emerald-900 border-4 border-slate-800 z-[80]"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var15...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for i, exp := range experiences {
|
||||
var templ_7745c5c3_Var8 = []any{"absolute w-full transition-all opacity-0 duration-700 ease-out translate-y-10"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var8).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\" data-experience-index=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(templ.JSONString(i))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 42, Col: 53}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\" x-bind:class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("active == %d ? 'z-10 opacity-100 translate-y-0' : ' -z-10 translate-y-10'", i))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 43, Col: 116}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"><div class=\"h-full w-full\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 = []any{fmt.Sprintf("relative flex w-full h-full items-center justify-center translate-y-[%dpx]", i*4*32)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var12).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\"><div class=\"absolute animate-pulse w-16 h-16 rounded-full bg-slate-800/50 z-50\"></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 = []any{"flex items-center flex-grow-0 justify-center w-10 h-10 rounded-full bg-emerald-900 border-4 border-slate-800 z-[80]"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var14).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "\"><div class=\"absolute w-2 h-2 z-[80] bg-emerald-400 rounded-full\"></div></div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<div id=\"timeline-point\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var16 string
|
||||
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var15).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `components/experiences_page.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "\"><div class=\"absolute w-2 h-2 z-[80] bg-emerald-400 rounded-full\"></div></div></div><div id=\"exps-container\" class=\"ml-4 items-center content-center relative xl:w-[1600px]\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, exp := range experiences {
|
||||
templ_7745c5c3_Err = experienceCard(exp).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</div></div></div></div></div></main>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "</div></div></div></main>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = rootLayout().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = rootLayout().Render(templ.WithChildren(ctx, templ_7745c5c3_Var14), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
19
components/experiences_page_templ.txt
Normal file
19
components/experiences_page_templ.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
<section class=\"min-h-[var(--content-height)] w-full flex relative items-center\"><!-- Left Side: Job Details --><div class=\"p-6 flex flex-col gap-4 transition-all opacity-0\"><h3 class=\"text-xl font-semibold text-white\">
|
||||
</h3><div class=\"flex flex-col gap-2\"><a href=\"
|
||||
\" class=\"text-emerald-400 font-medium text-lg \">
|
||||
</a><p class=\"text-slate-400 \">
|
||||
</p><p class=\"text-slate-600 text-sm\">
|
||||
-
|
||||
</p><a href=\"
|
||||
\" class=\"text-emerald-500\">
|
||||
</a></div><div class=\"flex flex-wrap gap-2\">
|
||||
</div><div class=\"flex flex-col gap-2\"><h4 class=\"text-xl font-medium\">About
|
||||
</h4>
|
||||
<p class=\"text-slate-300\">
|
||||
</p>
|
||||
</div><div class=\"flex flex-col gap-2\"><h4 class=\"text-xl font-medium\">Role & Responsibilities</h4><div class=\"text-slate-300 whitespace-pre-wrap\">
|
||||
</div></div></div></section>
|
||||
<script defer src=\"assets/js/experiences.js\"></script> <main class=\"bg-gradient-to-b from-slate-900 w-full to-slate-800 px-6 overflow-x-hidden\"><div class=\"flex w-full items-center justify-between\" x-data=\"{active:$persist(0)}\"><div class=\"relative w-full flex items-center justify-center\"><!-- Timeline --><div id=\"timeline\" class=\"fixed w-10 top-[var(--navbar-height)] left-2 h-[var(--content-height)] flex items-center justify-center\"><div class=\"absolute bg-radial-[at_50%_25%] from-40% from-slate-700 h-full w-0.5 to-slate-800\"></div>
|
||||
<div id=\"timeline-point\" class=\"
|
||||
\"><div class=\"absolute w-2 h-2 z-[80] bg-emerald-400 rounded-full\"></div></div></div><div id=\"exps-container\" class=\"ml-4 items-center content-center relative xl:w-[1600px]\">
|
||||
</div></div></div></main>
|
||||
5
components/external_links_templ.txt
Normal file
5
components/external_links_templ.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
<div class=\"fixed flex flex-col gap-6 right-5 bottom-0 p-5 w-5\"><a href=\"https://github.com/moh682\" target=\"_blank\" rel=\"noopener noreferrer\"><svg class=\"hover:cursor-pointer\" xmlns=\"http://www.w3.org/2000/svg\" width=\"
|
||||
\" height=\"
|
||||
\" viewBox=\"0 0 24 24\" fill=\"transparent\" stroke=\"var(--color-emerald-500)\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-github\"><path d=\"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4\"></path><path d=\"M9 18c-4.51 2-5-2-7-2\"></path></svg></a> <a href=\"https://www.linkedin.com/in/mohammad-hariri-337a0116b\" target=\"_blank\" rel=\"noopener noreferrer\"><svg class=\"hover:cursor-pointer\" xmlns=\"http://www.w3.org/2000/svg\" width=\"
|
||||
\" height=\"
|
||||
\" viewBox=\"0 0 {iconSize} {iconSize}\" fill=\"none\" stroke=\"var(--color-emerald-500)\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-linkedin\"><path d=\"M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z\"></path><rect width=\"4\" height=\"12\" x=\"2\" y=\"9\"></rect><circle cx=\"4\" cy=\"4\" r=\"2\"></circle></svg></a></div>
|
||||
@@ -2,16 +2,16 @@ package components
|
||||
|
||||
templ LandingPage() {
|
||||
@rootLayout() {
|
||||
<script defer src="assets/js/landing-page-animations.js"></script>
|
||||
<main class="flex items-center justify-center h-full bg-gradient-to-b from-slate-900 to-slate-800">
|
||||
<script defer src="assets/js/landing.js"></script>
|
||||
<main class="flex flex-col gap-8 bg-gradient-to-b from-slate-900 to-slate-800">
|
||||
<!-- Hero Section -->
|
||||
<div class="container mx-auto px-4 sm:px-6 lg:px-8 py-16 mb-24 sm:py-24">
|
||||
<div class="max-w-7xl mx-auto">
|
||||
<div class="px-4 sm:px-6 lg:px-8 py-16 sm:py-24">
|
||||
<div class="flex flex-col gap-24 ">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
|
||||
<!-- Left Content -->
|
||||
<div class="space-y-8">
|
||||
<div class="space-y-4">
|
||||
<span class="px-4 py-2 bg-emerald-900/50 text-emerald-400 rounded-full text-sm font-medium">Software Developer</span>
|
||||
<div class="flex flex-col gap-8">
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="px-4 w-fit py-2 bg-emerald-900/50 text-emerald-400 rounded-full text-sm font-medium">Software Engineer</span>
|
||||
<h1 class="text-4xl sm:text-5xl lg:text-6xl font-bold text-white leading-tight">
|
||||
Hey there! I'm Mohammad Hariri
|
||||
</h1>
|
||||
@@ -46,7 +46,7 @@ templ LandingPage() {
|
||||
<div class="absolute -inset-4 bg-gradient-to-r from-emerald-500 to-teal-500 rounded-2xl opacity-30 blur-xl"></div>
|
||||
<div class="relative bg-slate-800 p-4 rounded-2xl shadow-xl">
|
||||
<img
|
||||
src="/images/profile.jpg"
|
||||
src="/assets/images/portfolio-photo.webp"
|
||||
alt="Mohammad Hariri"
|
||||
class="w-full h-full object-cover rounded-xl"
|
||||
/>
|
||||
@@ -54,7 +54,7 @@ templ LandingPage() {
|
||||
</div>
|
||||
</div>
|
||||
<!-- Stats Section -->
|
||||
<div class="mt-20 grid grid-cols-2 sm:grid-cols-4 gap-8">
|
||||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-8">
|
||||
<div class="text-center">
|
||||
<div id="years-experience" class="text-4xl font-bold text-emerald-400">0</div>
|
||||
<div class="text-slate-400 mt-2">Years Experience</div>
|
||||
|
||||
@@ -41,7 +41,7 @@ func LandingPage() templ.Component {
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<script defer src=\"static/js/landing-page-animations.js\"></script> <main class=\"flex items-center justify-center h-full bg-gradient-to-b from-slate-900 to-slate-800\"><!-- Hero Section --><div class=\"container mx-auto px-4 sm:px-6 lg:px-8 py-16 mb-24 sm:py-24\"><div class=\"max-w-7xl mx-auto\"><div class=\"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center\"><!-- Left Content --><div class=\"space-y-8\"><div class=\"space-y-4\"><span class=\"px-4 py-2 bg-emerald-900/50 text-emerald-400 rounded-full text-sm font-medium\">Software Developer</span><h1 class=\"text-4xl sm:text-5xl lg:text-6xl font-bold text-white leading-tight\">Hey there! I'm Mohammad Hariri</h1><p class=\"text-xl text-slate-400 leading-relaxed\">I turn complex problems into elegant code solutions. Passionate about building robust applications that make a real difference in people's lives.</p></div><div class=\"flex flex-col sm:flex-row gap-4\"><a href=\"#contact\" class=\"inline-flex items-center justify-center px-6 py-3 border border-transparent text-base font-medium rounded-lg text-white bg-emerald-600 hover:bg-emerald-700 transition duration-300 shadow-lg hover:shadow-xl\">Let's get in touch</a> <a href=\"#portfolio\" class=\"inline-flex items-center justify-center px-6 py-3 border-2 border-slate-700 text-base font-medium rounded-lg text-slate-300 hover:bg-slate-800 transition duration-300\">View My Work</a></div><!-- Social Links --><div class=\"flex gap-6 pt-4\"><a href=\"https://github.com/moh682\" class=\"text-slate-400 hover:text-emerald-400 transition-colors\"><svg class=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"></path></svg></a> <a href=\"https://www.linkedin.com/in/mohammad-hariri-337a0116b/\" class=\"text-gray-600 hover:text-emerald-600 transition-colors\"><svg class=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z\"></path></svg></a></div></div><!-- Right Content - Hero Image --><div class=\"relative\"><div class=\"absolute -inset-4 bg-gradient-to-r from-emerald-500 to-teal-500 rounded-2xl opacity-30 blur-xl\"></div><div class=\"relative bg-slate-800 p-4 rounded-2xl shadow-xl\"><img src=\"/images/profile.jpg\" alt=\"Mohammad Hariri\" class=\"w-full h-full object-cover rounded-xl\"></div></div></div><!-- Stats Section --><div class=\"mt-20 grid grid-cols-2 sm:grid-cols-4 gap-8\"><div class=\"text-center\"><div id=\"years-experience\" class=\"text-4xl font-bold text-emerald-400\">0</div><div class=\"text-slate-400 mt-2\">Years Experience</div></div><div class=\"text-center\"><div id=\"programming-languages\" class=\"text-4xl font-bold text-emerald-600\">0</div><div class=\"text-gray-600 mt-2\">Programming Languages</div></div></div></div></div></main>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<script defer src=\"assets/js/landing.js\"></script> <main class=\"flex flex-col gap-8 bg-gradient-to-b from-slate-900 to-slate-800\"><!-- Hero Section --><div class=\"px-4 sm:px-6 lg:px-8 py-16 sm:py-24\"><div class=\"flex flex-col gap-24 \"><div class=\"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center\"><!-- Left Content --><div class=\"flex flex-col gap-8\"><div class=\"flex flex-col gap-2\"><span class=\"px-4 w-fit py-2 bg-emerald-900/50 text-emerald-400 rounded-full text-sm font-medium\">Software Engineer</span><h1 class=\"text-4xl sm:text-5xl lg:text-6xl font-bold text-white leading-tight\">Hey there! I'm Mohammad Hariri</h1><p class=\"text-xl text-slate-400 leading-relaxed\">I turn complex problems into elegant code solutions. Passionate about building robust applications that make a real difference in people's lives.</p></div><div class=\"flex flex-col sm:flex-row gap-4\"><a href=\"#contact\" class=\"inline-flex items-center justify-center px-6 py-3 border border-transparent text-base font-medium rounded-lg text-white bg-emerald-600 hover:bg-emerald-700 transition duration-300 shadow-lg hover:shadow-xl\">Let's get in touch</a> <a href=\"#portfolio\" class=\"inline-flex items-center justify-center px-6 py-3 border-2 border-slate-700 text-base font-medium rounded-lg text-slate-300 hover:bg-slate-800 transition duration-300\">View My Work</a></div><!-- Social Links --><div class=\"flex gap-6 pt-4\"><a href=\"https://github.com/moh682\" class=\"text-slate-400 hover:text-emerald-400 transition-colors\"><svg class=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"></path></svg></a> <a href=\"https://www.linkedin.com/in/mohammad-hariri-337a0116b/\" class=\"text-gray-600 hover:text-emerald-600 transition-colors\"><svg class=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z\"></path></svg></a></div></div><!-- Right Content - Hero Image --><div class=\"relative\"><div class=\"absolute -inset-4 bg-gradient-to-r from-emerald-500 to-teal-500 rounded-2xl opacity-30 blur-xl\"></div><div class=\"relative bg-slate-800 p-4 rounded-2xl shadow-xl\"><img src=\"/assets/images/portfolio-photo.webp\" alt=\"Mohammad Hariri\" class=\"w-full h-full object-cover rounded-xl\"></div></div></div><!-- Stats Section --><div class=\"grid grid-cols-2 sm:grid-cols-4 gap-8\"><div class=\"text-center\"><div id=\"years-experience\" class=\"text-4xl font-bold text-emerald-400\">0</div><div class=\"text-slate-400 mt-2\">Years Experience</div></div><div class=\"text-center\"><div id=\"programming-languages\" class=\"text-4xl font-bold text-emerald-600\">0</div><div class=\"text-gray-600 mt-2\">Programming Languages</div></div></div></div></div></main>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
1
components/landing_page_templ.txt
Normal file
1
components/landing_page_templ.txt
Normal file
@@ -0,0 +1 @@
|
||||
<script defer src=\"assets/js/landing.js\"></script> <main class=\"flex flex-col gap-8 bg-gradient-to-b from-slate-900 to-slate-800\"><!-- Hero Section --><div class=\"px-4 sm:px-6 lg:px-8 py-16 sm:py-24\"><div class=\"flex flex-col gap-24 \"><div class=\"grid grid-cols-1 lg:grid-cols-2 gap-12 items-center\"><!-- Left Content --><div class=\"flex flex-col gap-8\"><div class=\"flex flex-col gap-2\"><span class=\"px-4 w-fit py-2 bg-emerald-900/50 text-emerald-400 rounded-full text-sm font-medium\">Software Engineer</span><h1 class=\"text-4xl sm:text-5xl lg:text-6xl font-bold text-white leading-tight\">Hey there! I'm Mohammad Hariri</h1><p class=\"text-xl text-slate-400 leading-relaxed\">I turn complex problems into elegant code solutions. Passionate about building robust applications that make a real difference in people's lives.</p></div><div class=\"flex flex-col sm:flex-row gap-4\"><a href=\"#contact\" class=\"inline-flex items-center justify-center px-6 py-3 border border-transparent text-base font-medium rounded-lg text-white bg-emerald-600 hover:bg-emerald-700 transition duration-300 shadow-lg hover:shadow-xl\">Let's get in touch</a> <a href=\"#portfolio\" class=\"inline-flex items-center justify-center px-6 py-3 border-2 border-slate-700 text-base font-medium rounded-lg text-slate-300 hover:bg-slate-800 transition duration-300\">View My Work</a></div><!-- Social Links --><div class=\"flex gap-6 pt-4\"><a href=\"https://github.com/moh682\" class=\"text-slate-400 hover:text-emerald-400 transition-colors\"><svg class=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"></path></svg></a> <a href=\"https://www.linkedin.com/in/mohammad-hariri-337a0116b/\" class=\"text-gray-600 hover:text-emerald-600 transition-colors\"><svg class=\"w-6 h-6\" fill=\"currentColor\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z\"></path></svg></a></div></div><!-- Right Content - Hero Image --><div class=\"relative\"><div class=\"absolute -inset-4 bg-gradient-to-r from-emerald-500 to-teal-500 rounded-2xl opacity-30 blur-xl\"></div><div class=\"relative bg-slate-800 p-4 rounded-2xl shadow-xl\"><img src=\"/assets/images/portfolio-photo.webp\" alt=\"Mohammad Hariri\" class=\"w-full h-full object-cover rounded-xl\"></div></div></div><!-- Stats Section --><div class=\"grid grid-cols-2 sm:grid-cols-4 gap-8\"><div class=\"text-center\"><div id=\"years-experience\" class=\"text-4xl font-bold text-emerald-400\">0</div><div class=\"text-slate-400 mt-2\">Years Experience</div></div><div class=\"text-center\"><div id=\"programming-languages\" class=\"text-4xl font-bold text-emerald-600\">0</div><div class=\"text-gray-600 mt-2\">Programming Languages</div></div></div></div></div></main>
|
||||
@@ -1,58 +1,23 @@
|
||||
package components
|
||||
|
||||
templ rootLayout() {
|
||||
<html class="w-full h-full overflow-hidden bg-slate-900 text-white">
|
||||
<html class="w-screen h-screen overflow-x-hidden bg-slate-900 text-white">
|
||||
<head>
|
||||
<!-- tailwindcss -->
|
||||
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
|
||||
<link rel="stylesheet" href="assets/css/styles.css"/>
|
||||
<!-- Motion.js -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/motion@latest/dist/motion.js"></script>
|
||||
<!-- Alpine.js -->
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/anchor@3.x.x/dist/cdn.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/persist@3.x.x/dist/cdn.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>Mohammad's Portfolio</title>
|
||||
<style>
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
opacity: 0;
|
||||
animation: fadeIn 1s ease-in forwards;
|
||||
}
|
||||
|
||||
.animate-slide-in {
|
||||
opacity: 0;
|
||||
animation: slideIn 1s ease-out forwards;
|
||||
}
|
||||
|
||||
.delay-300 {
|
||||
animation-delay: 300ms;
|
||||
}
|
||||
|
||||
.delay-600 {
|
||||
animation-delay: 600ms;
|
||||
}
|
||||
|
||||
.delay-900 {
|
||||
animation-delay: 900ms;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="flex flex-col w-full h-full">
|
||||
@navbar()
|
||||
<div class="h-full w-full">
|
||||
{ children... }
|
||||
</div>
|
||||
{ children... }
|
||||
</body>
|
||||
</html>
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ func rootLayout() templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<html class=\"w-full h-full overflow-hidden bg-slate-900 text-white\"><head><script src=\"https://unpkg.com/@tailwindcss/browser@4\"></script><script src=\"https://cdn.jsdelivr.net/npm/motion@latest/dist/motion.js\"></script><script defer src=\"https://cdn.jsdelivr.net/npm/@alpinejs/persist@3.x.x/dist/cdn.min.js\"></script><script defer src=\"https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js\"></script><title>Mohammad's Portfolio</title><style>\n\t\t\t@keyframes fadeIn {\n\t\t\t\tfrom { opacity: 0; }\n\t\t\t\tto { opacity: 1; }\n\t\t\t}\n\n\t\t\t@keyframes slideIn {\n\t\t\t\tfrom { \n\t\t\t\t\topacity: 0;\n\t\t\t\t\ttransform: translateY(20px);\n\t\t\t\t}\n\t\t\t\tto {\n\t\t\t\t\topacity: 1;\n\t\t\t\t\ttransform: translateY(0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t.animate-fade-in {\n\t\t\t\topacity: 0;\n\t\t\t\tanimation: fadeIn 1s ease-in forwards;\n\t\t\t}\n\n\t\t\t.animate-slide-in {\n\t\t\t\topacity: 0;\n\t\t\t\tanimation: slideIn 1s ease-out forwards;\n\t\t\t}\n\n\t\t\t.delay-300 {\n\t\t\t\tanimation-delay: 300ms;\n\t\t\t}\n\n\t\t\t.delay-600 {\n\t\t\t\tanimation-delay: 600ms;\n\t\t\t}\n\n\t\t\t.delay-900 {\n\t\t\t\tanimation-delay: 900ms;\n\t\t\t}\n\t\t</style></head><body class=\"flex flex-col w-full h-full\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<html class=\"w-screen h-screen overflow-x-hidden bg-slate-900 text-white\"><head><!-- tailwindcss --><script src=\"https://unpkg.com/@tailwindcss/browser@4\"></script><link rel=\"stylesheet\" href=\"assets/css/styles.css\"><!-- Motion.js --><script src=\"https://cdn.jsdelivr.net/npm/motion@latest/dist/motion.js\"></script><!-- Alpine.js --><script defer src=\"https://cdn.jsdelivr.net/npm/@alpinejs/anchor@3.x.x/dist/cdn.min.js\"></script><script defer src=\"https://cdn.jsdelivr.net/npm/@alpinejs/persist@3.x.x/dist/cdn.min.js\"></script><script defer src=\"https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js\"></script><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Mohammad's Portfolio</title></head><body class=\"flex flex-col w-full h-full\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -37,15 +37,11 @@ func rootLayout() templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<div class=\"h-full w-full\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</div></body></html>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</body></html>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
2
components/layout_templ.txt
Normal file
2
components/layout_templ.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
<html class=\"w-screen h-screen overflow-x-hidden bg-slate-900 text-white\"><head><!-- tailwindcss --><script src=\"https://unpkg.com/@tailwindcss/browser@4\"></script><link rel=\"stylesheet\" href=\"assets/css/styles.css\"><!-- Motion.js --><script src=\"https://cdn.jsdelivr.net/npm/motion@latest/dist/motion.js\"></script><!-- Alpine.js --><script defer src=\"https://cdn.jsdelivr.net/npm/@alpinejs/anchor@3.x.x/dist/cdn.min.js\"></script><script defer src=\"https://cdn.jsdelivr.net/npm/@alpinejs/persist@3.x.x/dist/cdn.min.js\"></script><script defer src=\"https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js\"></script><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Mohammad's Portfolio</title></head><body class=\"flex flex-col w-full h-full\">
|
||||
</body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
components/logo_templ.txt
Normal file
1
components/logo_templ.txt
Normal file
File diff suppressed because one or more lines are too long
@@ -1,28 +1,86 @@
|
||||
package components
|
||||
|
||||
templ navbar() {
|
||||
<nav class="bg-slate-900 z-50 w-full py-4 justify-between items-center h-20 flex gap-6 px-6">
|
||||
<script src="/assets/js/navigation.js"></script>
|
||||
<nav x-data="navbar" class="fixed h-[var(--navbar-height)] backdrop-blur-md bg-slate-900/90 z-50 w-full py-4 justify-between items-center flex gap-6 px-6 border-b border-slate-800">
|
||||
<ul class="flex gap-4">
|
||||
<li>
|
||||
<a href="/">
|
||||
@Logo(4 * 32)
|
||||
<a href="/" class="text-white hover:text-blue-400 transition-colors duration-300">
|
||||
@Logo()
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="flex gap-4">
|
||||
<div class="hidden md:block">
|
||||
<div class="flex gap-6">
|
||||
<li><a href="/experiences">Experiences</a></li>
|
||||
<li><a href="/projects">Projects</a></li>
|
||||
<li><a href="/about">About</a></li>
|
||||
<li><a href="/contact">Contact</a></li>
|
||||
<div class="flex gap-8" id="desktop-nav">
|
||||
<li class="relative group">
|
||||
<a href="/experiences" class="flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300">
|
||||
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M20.25 14.15v4.25c0 1.094-.787 2.036-1.872 2.18-2.087.277-4.216.42-6.378.42s-4.291-.143-6.378-.42c-1.085-.144-1.872-1.086-1.872-2.18v-4.25m16.5 0a2.18 2.18 0 00.75-1.661V8.706c0-1.081-.768-2.015-1.837-2.175a48.114 48.114 0 00-3.413-.387m4.5 8.006c-.194.165-.42.295-.673.38A23.978 23.978 0 0112 15.75c-2.648 0-5.195-.429-7.577-1.22a2.016 2.016 0 01-.673-.38m0 0A2.18 2.18 0 013 12.489V8.706c0-1.081.768-2.015 1.837-2.175a48.111 48.111 0 013.413-.387m7.5 0V5.25A2.25 2.25 0 0013.5 3h-3a2.25 2.25 0 00-2.25 2.25v.894m7.5 0a48.667 48.667 0 00-7.5 0M12 12.75h.008v.008H12v-.008z"></path>
|
||||
</svg>
|
||||
<span>Experiences</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="relative group">
|
||||
<a href="/projects" class="flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300">
|
||||
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5"></path>
|
||||
</svg>
|
||||
<span>Projects</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="relative group">
|
||||
<a href="/about" class="flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300">
|
||||
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z"></path>
|
||||
</svg>
|
||||
<span>About</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="relative group">
|
||||
<a href="/contact" class="flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300">
|
||||
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75"></path>
|
||||
</svg>
|
||||
<span>Contact</span>
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
<ul class="w-6">
|
||||
<li class="md:hidden">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-align-justify"><path d="M3 12h18"></path><path d="M3 18h18"></path><path d="M3 6h18"></path></svg>
|
||||
</li>
|
||||
<button @click="toggle" class="md:hidden relative w-8 h-8 focus:outline-none">
|
||||
<div class="absolute w-6 transform transition-all duration-300" :class="{'rotate-45 translate-y-0': isOpen, 'translate-y-[-8px]': !isOpen}">
|
||||
<div class="h-[2px] w-full bg-white rounded-lg"></div>
|
||||
</div>
|
||||
<div class="absolute w-6 transform transition-all duration-300" :class="{'opacity-0': isOpen}">
|
||||
<div class="h-[2px] w-full bg-white rounded-lg"></div>
|
||||
</div>
|
||||
<div class="absolute w-6 transform transition-all duration-300" :class="{'-rotate-45 translate-y-0': isOpen, 'translate-y-[8px]': !isOpen}">
|
||||
<div class="h-[2px] w-full bg-white rounded-lg"></div>
|
||||
</div>
|
||||
</button>
|
||||
<div
|
||||
@click="close"
|
||||
x-show="isOpen"
|
||||
x-cloak
|
||||
x-transition:enter="transition ease-out duration-300"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="transition ease-in duration-300"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
class="navbar-drawer top-[var(--navbar-height)] fixed inset-0 z-50 bg-slate-900/98 backdrop-blur-sm pt-24"
|
||||
>
|
||||
<div class="flex items-center justify-center h-full w-full">
|
||||
<div id="mobile-nav" class="flex gap-12 flex-col items-center justify-center px-2">
|
||||
<li><a class="text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300" href="/experiences">Experiences</a></li>
|
||||
<li><a class="text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300" href="/projects">Projects</a></li>
|
||||
<li><a class="text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300" href="/about">About</a></li>
|
||||
<li><a class="text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300" href="/contact">Contact</a></li>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
</nav>
|
||||
}
|
||||
|
||||
@@ -29,15 +29,15 @@ func navbar() templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<nav class=\"bg-slate-900 z-50 w-full py-4 justify-between items-center h-20 flex gap-6 px-6\"><ul class=\"flex gap-4\"><li><a href=\"/\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<script src=\"/assets/js/navigation.js\"></script><nav x-data=\"navbar\" class=\"fixed h-[var(--navbar-height)] backdrop-blur-md bg-slate-900/90 z-50 w-full py-4 justify-between items-center flex gap-6 px-6 border-b border-slate-800\"><ul class=\"flex gap-4\"><li><a href=\"/\" class=\"text-white hover:text-blue-400 transition-colors duration-300\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = Logo(4*32).Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = Logo().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</a></li></ul><ul class=\"flex gap-4\"><div class=\"hidden md:block\"><div class=\"flex gap-6\"><li><a href=\"/experiences\">Experiences</a></li><li><a href=\"/projects\">Projects</a></li><li><a href=\"/about\">About</a></li><li><a href=\"/contact\">Contact</a></li></div></div></ul><ul class=\"w-6\"><li class=\"md:hidden\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-align-justify\"><path d=\"M3 12h18\"></path><path d=\"M3 18h18\"></path><path d=\"M3 6h18\"></path></svg></li></ul></nav>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</a></li></ul><ul class=\"flex gap-4\"><div class=\"hidden md:block\"><div class=\"flex gap-8\" id=\"desktop-nav\"><li class=\"relative group\"><a href=\"/experiences\" class=\"flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300\"><svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M20.25 14.15v4.25c0 1.094-.787 2.036-1.872 2.18-2.087.277-4.216.42-6.378.42s-4.291-.143-6.378-.42c-1.085-.144-1.872-1.086-1.872-2.18v-4.25m16.5 0a2.18 2.18 0 00.75-1.661V8.706c0-1.081-.768-2.015-1.837-2.175a48.114 48.114 0 00-3.413-.387m4.5 8.006c-.194.165-.42.295-.673.38A23.978 23.978 0 0112 15.75c-2.648 0-5.195-.429-7.577-1.22a2.016 2.016 0 01-.673-.38m0 0A2.18 2.18 0 013 12.489V8.706c0-1.081.768-2.015 1.837-2.175a48.111 48.111 0 013.413-.387m7.5 0V5.25A2.25 2.25 0 0013.5 3h-3a2.25 2.25 0 00-2.25 2.25v.894m7.5 0a48.667 48.667 0 00-7.5 0M12 12.75h.008v.008H12v-.008z\"></path></svg> <span>Experiences</span></a></li><li class=\"relative group\"><a href=\"/projects\" class=\"flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300\"><svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5\"></path></svg> <span>Projects</span></a></li><li class=\"relative group\"><a href=\"/about\" class=\"flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300\"><svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z\"></path></svg> <span>About</span></a></li><li class=\"relative group\"><a href=\"/contact\" class=\"flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300\"><svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75\"></path></svg> <span>Contact</span></a></li></div></div></ul><ul class=\"w-6\"><button @click=\"toggle\" class=\"md:hidden relative w-8 h-8 focus:outline-none\"><div class=\"absolute w-6 transform transition-all duration-300\" :class=\"{'rotate-45 translate-y-0': isOpen, 'translate-y-[-8px]': !isOpen}\"><div class=\"h-[2px] w-full bg-white rounded-lg\"></div></div><div class=\"absolute w-6 transform transition-all duration-300\" :class=\"{'opacity-0': isOpen}\"><div class=\"h-[2px] w-full bg-white rounded-lg\"></div></div><div class=\"absolute w-6 transform transition-all duration-300\" :class=\"{'-rotate-45 translate-y-0': isOpen, 'translate-y-[8px]': !isOpen}\"><div class=\"h-[2px] w-full bg-white rounded-lg\"></div></div></button><div @click=\"close\" x-show=\"isOpen\" x-cloak x-transition:enter=\"transition ease-out duration-300\" x-transition:enter-start=\"opacity-0\" x-transition:enter-end=\"opacity-100\" x-transition:leave=\"transition ease-in duration-300\" x-transition:leave-start=\"opacity-100\" x-transition:leave-end=\"opacity-0\" class=\"navbar-drawer top-[var(--navbar-height)] fixed inset-0 z-50 bg-slate-900/98 backdrop-blur-sm pt-24\"><div class=\"flex items-center justify-center h-full w-full\"><div id=\"mobile-nav\" class=\"flex gap-12 flex-col items-center justify-center px-2\"><li><a class=\"text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300\" href=\"/experiences\">Experiences</a></li><li><a class=\"text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300\" href=\"/projects\">Projects</a></li><li><a class=\"text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300\" href=\"/about\">About</a></li><li><a class=\"text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300\" href=\"/contact\">Contact</a></li></div></div></div></ul></nav>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
2
components/navbar_templ.txt
Normal file
2
components/navbar_templ.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
<script src=\"/assets/js/navigation.js\"></script><nav x-data=\"navbar\" class=\"fixed h-[var(--navbar-height)] backdrop-blur-md bg-slate-900/90 z-50 w-full py-4 justify-between items-center flex gap-6 px-6 border-b border-slate-800\"><ul class=\"flex gap-4\"><li><a href=\"/\" class=\"text-white hover:text-blue-400 transition-colors duration-300\">
|
||||
</a></li></ul><ul class=\"flex gap-4\"><div class=\"hidden md:block\"><div class=\"flex gap-8\" id=\"desktop-nav\"><li class=\"relative group\"><a href=\"/experiences\" class=\"flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300\"><svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M20.25 14.15v4.25c0 1.094-.787 2.036-1.872 2.18-2.087.277-4.216.42-6.378.42s-4.291-.143-6.378-.42c-1.085-.144-1.872-1.086-1.872-2.18v-4.25m16.5 0a2.18 2.18 0 00.75-1.661V8.706c0-1.081-.768-2.015-1.837-2.175a48.114 48.114 0 00-3.413-.387m4.5 8.006c-.194.165-.42.295-.673.38A23.978 23.978 0 0112 15.75c-2.648 0-5.195-.429-7.577-1.22a2.016 2.016 0 01-.673-.38m0 0A2.18 2.18 0 013 12.489V8.706c0-1.081.768-2.015 1.837-2.175a48.111 48.111 0 013.413-.387m7.5 0V5.25A2.25 2.25 0 0013.5 3h-3a2.25 2.25 0 00-2.25 2.25v.894m7.5 0a48.667 48.667 0 00-7.5 0M12 12.75h.008v.008H12v-.008z\"></path></svg> <span>Experiences</span></a></li><li class=\"relative group\"><a href=\"/projects\" class=\"flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300\"><svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5\"></path></svg> <span>Projects</span></a></li><li class=\"relative group\"><a href=\"/about\" class=\"flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300\"><svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z\"></path></svg> <span>About</span></a></li><li class=\"relative group\"><a href=\"/contact\" class=\"flex items-center gap-2 text-slate-300 group-hover:text-white transition-colors duration-300\"><svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75\"></path></svg> <span>Contact</span></a></li></div></div></ul><ul class=\"w-6\"><button @click=\"toggle\" class=\"md:hidden relative w-8 h-8 focus:outline-none\"><div class=\"absolute w-6 transform transition-all duration-300\" :class=\"{'rotate-45 translate-y-0': isOpen, 'translate-y-[-8px]': !isOpen}\"><div class=\"h-[2px] w-full bg-white rounded-lg\"></div></div><div class=\"absolute w-6 transform transition-all duration-300\" :class=\"{'opacity-0': isOpen}\"><div class=\"h-[2px] w-full bg-white rounded-lg\"></div></div><div class=\"absolute w-6 transform transition-all duration-300\" :class=\"{'-rotate-45 translate-y-0': isOpen, 'translate-y-[8px]': !isOpen}\"><div class=\"h-[2px] w-full bg-white rounded-lg\"></div></div></button><div @click=\"close\" x-show=\"isOpen\" x-cloak x-transition:enter=\"transition ease-out duration-300\" x-transition:enter-start=\"opacity-0\" x-transition:enter-end=\"opacity-100\" x-transition:leave=\"transition ease-in duration-300\" x-transition:leave-start=\"opacity-100\" x-transition:leave-end=\"opacity-0\" class=\"navbar-drawer top-[var(--navbar-height)] fixed inset-0 z-50 bg-slate-900/98 backdrop-blur-sm pt-24\"><div class=\"flex items-center justify-center h-full w-full\"><div id=\"mobile-nav\" class=\"flex gap-12 flex-col items-center justify-center px-2\"><li><a class=\"text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300\" href=\"/experiences\">Experiences</a></li><li><a class=\"text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300\" href=\"/projects\">Projects</a></li><li><a class=\"text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300\" href=\"/about\">About</a></li><li><a class=\"text-4xl font-light text-slate-300 hover:text-white transition-colors duration-300\" href=\"/contact\">Contact</a></li></div></div></div></ul></nav>
|
||||
1
components/notfound_templ.txt
Normal file
1
components/notfound_templ.txt
Normal file
@@ -0,0 +1 @@
|
||||
<main class=\"w-full h-full flex flex-col gap-0 items-center justify-center\"><h1 class=\"text-3xl\">404</h1><p class=\"text-base\">Page not found</p></main>
|
||||
17
components/projects_page_templ.txt
Normal file
17
components/projects_page_templ.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
<span class=\"px-3 py-1 w-fit text-sm bg-slate-700 text-slate-300 rounded-full\">
|
||||
</span>
|
||||
<span class=\"
|
||||
\">
|
||||
</span>
|
||||
<div class=\"group bg-slate-800 rounded-lg overflow-hidden transition-all duration-300 hover:transform hover:scale-[1.02] hover:shadow-xl\"><div class=\"relative overflow-hidden aspect-video\"><img src=\"
|
||||
\" alt=\"
|
||||
\" class=\"w-full h-full object-cover transition-transform duration-300 group-hover:scale-110\"><div class=\"absolute inset-0 bg-gradient-to-t from-slate-900 to-transparent opacity-0 group-hover:opacity-60 transition-opacity duration-300\"></div></div><div class=\"flex flex-col gap-4 p-6\"><div class=\"flex flex-col gap-2\"><h3 class=\"text-xl font-bold text-slate-100\">
|
||||
</h3>
|
||||
<p class=\"text-slate-400 mb-4 line-clamp-2\">
|
||||
</p><div class=\"flex flex-wrap gap-2\">
|
||||
</div></div>
|
||||
<a href=\"
|
||||
\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"inline-flex items-center text-emerald-500 hover:text-emerald-400 transition-colors\">View Project <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4 ml-1\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z\" clip-rule=\"evenodd\"></path></svg></a>
|
||||
</div></div>
|
||||
<main class=\"w-full min-h-full py-16 px-4 sm:px-6 lg:px-8\"><div class=\"max-w-7xl mx-auto\"><h1 class=\"text-4xl font-bold text-slate-100 mb-2\">Projects</h1><p class=\"text-slate-400 mb-12\">A collection of projects I've worked on</p><div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8\">
|
||||
</div></div></main>
|
||||
13
components/tech_stack_templ.txt
Normal file
13
components/tech_stack_templ.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
<a href=\"
|
||||
\" class=\"group flex items-center gap-2 px-3 py-2 rounded-md bg-slate-700/30 hover:bg-slate-700/50 transition-colors duration-200\">
|
||||
<img src=\"
|
||||
\" alt=\"
|
||||
\" class=\"w-5 h-5 object-contain\">
|
||||
<span class=\"text-emerald-500 w-fit font-medium group-hover:text-emerald-400\">
|
||||
</span></a>
|
||||
<div class=\"flex items-center gap-2 px-3 py-2 rounded-md bg-slate-700\">
|
||||
<img src=\"
|
||||
\" alt=\"
|
||||
\" class=\"w-5 h-5 object-contain\">
|
||||
<span class=\"text-white w-fit font-medium\">
|
||||
</span></div>
|
||||
Reference in New Issue
Block a user