flatten folder structure

This commit is contained in:
jc 2024-03-26 01:14:51 -04:00
commit 9c20148159
No known key found for this signature in database
10 changed files with 302 additions and 459 deletions

10
go.mod
View file

@ -11,12 +11,12 @@ require (
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/labstack/gommon v0.4.0 // indirect github.com/labstack/gommon v0.4.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect
golang.org/x/crypto v0.14.0 // indirect golang.org/x/crypto v0.16.0 // indirect
golang.org/x/net v0.17.0 // indirect golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.13.0 // indirect golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.13.0 // indirect golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.3.0 // indirect
) )

20
go.sum
View file

@ -14,8 +14,8 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -27,19 +27,19 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -11,8 +11,6 @@ import (
"github.com/joho/godotenv" "github.com/joho/godotenv"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware" "github.com/labstack/echo/v4/middleware"
"github.com/juancwu/potoforio/pkg/pages"
) )
type TemplateRenderer struct { type TemplateRenderer struct {
@ -29,7 +27,7 @@ func main() {
} }
} }
templates, err := template.New("").ParseGlob("public/views/*.html") templates, err := template.New("").ParseGlob("views/*.html")
if err != nil { if err != nil {
log.Fatalf("Error initializing templates: %v", err) log.Fatalf("Error initializing templates: %v", err)
os.Exit(1) os.Exit(1)
@ -43,7 +41,7 @@ func main() {
e.Use(middleware.Logger()) e.Use(middleware.Logger())
e.Static("/static", "static") e.Static("/static", "static")
e.GET("/", pages.Index) e.GET("/", renderPage)
e.GET("/service/health-check", func(c echo.Context) error { e.GET("/service/health-check", func(c echo.Context) error {
return c.NoContent(http.StatusOK) return c.NoContent(http.StatusOK)

View file

@ -5,8 +5,8 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"dev": "concurrently \"pnpm run tw:dev\" \"air\"", "dev": "concurrently \"pnpm run tw:dev\" \"air\"",
"tw:dev": "tailwindcss -i ./styles.css -o ./static/styles.css --watch", "tw:dev": "tailwindcss -i ./views/styles.css -o ./static/styles.css --watch",
"tw:prod": "tailwindcss -i ./styles.css -o ./static/styles.css --minify", "tw:prod": "tailwindcss -i ./views/styles.css -o ./static/styles.css --minify",
"prettier": "prettier ./public --write", "prettier": "prettier ./public --write",
"prettier:check": "prettier ./public --check" "prettier:check": "prettier ./public --check"
}, },

View file

@ -1,4 +1,4 @@
package pages package main
import ( import (
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
@ -23,8 +23,7 @@ type Page struct {
Projects []Project Projects []Project
} }
func Index(c echo.Context) error { func renderPage(c echo.Context) error {
data := Page{} data := Page{}
data.Projects = []Project{ data.Projects = []Project{
{ {

View file

@ -1,357 +0,0 @@
<!doctype html>
<html
lang="en"
class="relative h-full w-full scroll-smooth bg-zinc-900 font-inter text-white"
>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
content="Juan Wu software developer portfolio site"
/>
<meta name="author" content="Juan Wu" />
<meta
name="keywords"
content="software developer, fullstack developer, portfolio"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/static/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/static/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/static/favicon-16x16.png"
/>
<link rel="manifest" href="/static/site.webmanifest" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="/static/styles.css" />
<link
rel="preload"
fetchpriority="high"
as="image"
href="/static/touching-grass-pic.jpg"
type="image/jpeg"
/>
<link
rel="preload"
fetchpriority="high"
as="image"
href="/static/grid.svg"
type="image/svg+xml"
/>
<script
src="https://unpkg.com/htmx.org@1.9.6"
integrity="sha384-FhXw7b6AlE/jyjlZH5iHa/tTe9EpJ1Y55RjcgPbjeWMskSxZt1v9qkxLJWNJaGni"
crossorigin="anonymous"
></script>
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
<title>Juan Wu | Portfolio</title>
</head>
<body class="h-full w-full">
<div class="polka-pattern fixed inset-0 -z-10" aria-hidden="true"></div>
<header class="border-b border-white/10 bg-zinc-900 px-8 lg:px-16">
<div class="flex items-center py-6 font-medium">
<div>
<span class="text-white"> JUAN WU </span>
<div
class="group relative text-sm text-teal-400 hover:line-through"
>
SOFTWARE DEVELOPER
<span
aria-hidden="true"
class="absolute left-0 top-full hidden text-red-500 group-hover:inline"
>CHROOT</span
>
</div>
</div>
<button
class="ml-auto lg:hidden"
aria-label="Open mobile navigation menu"
_="on click remove .translate-x-full from <nav /> then add .overflow-hidden to <body />"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
aria-hidden="true"
class="h-6 w-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"
/>
</svg>
</button>
<nav
class="fixed inset-0 z-10 translate-x-full items-center bg-zinc-900 transition-transform lg:relative lg:ml-auto lg:flex lg:translate-x-0 lg:bg-transparent"
>
<div class="flex justify-end p-8">
<button
class="block lg:hidden"
aria-label="close mobile navigation menu"
_="on click add .translate-x-full to <nav /> then remove .overflow-hidden from <body />"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="h-6 w-6 text-red-500"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<ul
class="flex flex-col items-center justify-center gap-8 uppercase text-white lg:flex-row lg:gap-4"
>
<li>
<a
href="#projects"
class="relative z-0 p-2 after:absolute after:left-0 after:top-1/2 after:-z-10 after:h-3/4 after:w-0 after:-translate-y-1/2 after:bg-gradient-to-r after:from-purple-500 after:to-pink-500 after:transition-all hover:after:w-full focus:after:w-full"
>
Projects
</a>
</li>
<li aria-hidden="true">
<span
aria-hidden="true"
class="hidden select-none font-normal text-fuchsia-400 lg:inline"
>
-
</span>
</li>
<li>
<a
href="https://github.com/juancwu"
class="relative z-0 p-2 after:absolute after:left-1/2 after:top-1/2 after:-z-10 after:h-3/4 after:w-full after:-translate-x-1/2 after:-translate-y-1/2 after:scale-75 after:bg-white after:opacity-0 after:transition-all hover:text-gray-950 hover:after:scale-100 hover:after:opacity-100 focus:text-gray-950 focus:after:scale-100 focus:after:opacity-100"
>GitHub</a
>
</li>
<li aria-hidden="true">
<span
aria-hidden="true"
class="hidden select-none font-normal text-fuchsia-400 lg:inline"
>
-
</span>
</li>
<li>
<a
href="https://linkedin.com/in/juancwu"
class="relative z-0 p-2 after:absolute after:-left-2 after:top-1/2 after:-z-10 after:h-3/4 after:w-full after:bg-gradient-to-r after:from-sky-500 after:to-indigo-500 after:opacity-0 after:transition-all hover:after:left-0 hover:after:top-0 hover:after:translate-y-[15%] hover:after:opacity-100 focus:after:left-0 focus:after:top-0 focus:after:translate-y-[15%] focus:after:opacity-100"
>LinkedIn</a
>
</li>
<!--
<li aria-hidden="true">
<span
aria-hidden="true"
class="hidden select-none font-normal text-fuchsia-400 lg:inline"
>
-
</span>
</li>
<li>
<a
href="https://linkedin.com/in/juancwu"
class="relative z-0 p-2 after:absolute after:right-0 after:top-1/2 after:-z-10 after:h-3/4 after:w-0 after:-translate-y-1/2 after:-scale-x-100 after:bg-gradient-to-r after:from-orange-500 after:to-yellow-500 after:transition-all hover:after:w-full focus:after:w-full"
>RESUME</a
>
</li>
-->
</ul>
</nav>
</div>
</header>
<main class="relative z-0 px-16 py-24">
<div class="grid-pattern absolute inset-0" aria-hidden="true"></div>
<div
class="radial-overlay absolute inset-0"
aria-hidden="true"
></div>
<section
id="hero"
aria-label="Hero Section"
class="flex h-full w-full items-center justify-center"
>
<div class="flex items-center justify-center gap-16">
<div class="relative z-10 space-y-4 text-white">
<p class="text-md text-zinc-300 lg:text-xl">
Hello there <span aria-hidden="true">👋</span>,
</p>
<p
class="text-5xl font-bold text-zinc-100 md:text-6xl lg:text-7xl xl:text-9xl"
>
I am Juan
</p>
<p
class="text-2xl text-zinc-300 md:text-2xl lg:text-3xl xl:text-4xl"
>
I am a Software Developer during the day
</p>
<p
class="text-2xl text-zinc-300 md:text-2xl lg:text-3xl xl:text-4xl"
>
<span aria-label="and">&amp;</span>
work at
<a
href="https://lauriercs.ca"
class="relative z-0 whitespace-nowrap font-medium underline decoration-sky-400 transition-all after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full"
>LCS</a
>
and
<a
href="https://hawkhacks.ca"
class="relative z-0 whitespace-nowrap font-medium underline decoration-sky-400 transition-all after:absolute after:left-0 after:top-0 after:-z-10 after:h-0 after:w-full after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:h-full focus:text-white focus:decoration-sky-500 focus:after:h-full"
>Hawk Hacks</a
>
at night
</p>
<p class="text-xs">(send help, I have been enslaved)</p>
<div class="h-4" aria-hidden="true"></div>
<p
class="text-4xl font-medium md:inline-block lg:text-5xl"
>
Check out my
</p>
<a
href="#projects"
class="colourful-card inline-block text-4xl font-semibold focus:outline-offset-2 md:ml-2 lg:mt-4 lg:text-5xl"
>
PROJECTS
</a>
</div>
<div
class="clip-me-from-grass hidden bg-gray-200 p-2 opacity-100 drop-shadow-lg lg:block lg:max-w-lg retina:h-auto retina:w-96"
>
<img
class="clip-me-from-grass z-0 h-full w-full"
src="/static/touching-grass-pic.jpg"
alt="Juan's portrait photo of him touching grass (figuratively)"
/>
</div>
</div>
</section>
</main>
<div class="hidden h-12 lg:block" aria-hidden="true"></div>
<section
id="projects"
aria-label="Juan's Projects"
class="relative px-8"
>
<div class="relative flex items-center justify-center pt-8">
<div class="flex flex-col items-center">
<h1
class="flex flex-col gap-2 p-8 text-3xl font-bold uppercase md:text-5xl"
>
<span
class="relative text-xl font-medium text-zinc-300 md:text-2xl"
>Welcome to</span
>
<span
class="relative inline-block before:absolute before:-inset-1 before:block before:-skew-y-3 before:scale-90 before:bg-gradient-to-r before:from-purple-500 before:to-pink-500 before:opacity-60 before:transition-all hover:before:scale-100"
>
<span class="relative"> Project Graveyard </span>
</span>
</h1>
<a
href="https://shoto.at/l/dumb-projects"
class="relative underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full"
>
Juan's dumb projects archive
</a>
</div>
</div>
<div class="h-16" aria-hidden="true"></div>
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2 2xl:grid-cols-3">
{{ range .Projects }}
<div
class="flex w-full flex-col justify-between gap-4 rounded border-2 bg-zinc-800/10 p-6 shadow-lg backdrop-blur-[2px] transition {{ .Classes }}"
>
<div>
<div
class="flex flex-col items-center justify-between gap-4 md:flex-row md:gap-0"
>
{{ if gt (len .URL) 1 }}
<a
href="{{ .URL }}"
class="relative flex items-center gap-2 transition-colors hover:text-sky-400"
>
<h3 class="text-2xl font-medium">
{{ .Name }}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="-mt-1 inline-block h-6 w-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"
/>
</svg>
</h3>
</a>
{{ else }}
<h3 class="text-2xl font-medium">{{ .Name }}</h3>
{{ end }}
<ul class="flex gap-2">
{{ range .TechList }}
<li>
<a
href="{{ .TechURL }}"
class="relative text-sm underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full md:text-base"
>{{ .TechName }}</a
>
</li>
{{ end }}
</ul>
</div>
<div class="h-4" aria-hidden="true"></div>
<hr class="border-white/25" />
<div class="h-4" aria-hidden="true"></div>
<p>{{ .Description }}</p>
</div>
<p>
Checkout the code in
<a
href="{{ .Repo }}"
class="relative underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full"
>GitHub</a
>
</p>
</div>
{{ end }}
</div>
</section>
<div class="h-64" aria-hidden="true"></div>
</body>
</html>

View file

@ -1,75 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.colourful-card {
@apply relative bg-white p-2 text-zinc-950 transition-all after:absolute after:-right-2
after:top-2 after:-z-10
after:h-full
after:w-full after:bg-gradient-to-r after:from-purple-500 after:to-pink-500
after:transition-all hover:bg-transparent
hover:text-white hover:after:right-0 hover:after:top-0
focus:bg-transparent focus:text-white
focus:after:right-0 focus:after:top-0;
}
.clip-me-from-grass {
clip-path: polygon(
58.36% 5.19%,
52.34% 3.68%,
45.85% 3.05%,
37.74% 7.64%,
35.66% 12.39%,
34.82% 19.98%,
32.57% 27.81%,
29.87% 32.92%,
22.01% 37.14%,
17.02% 42.9%,
10.6% 53.43%,
8.22% 70.71%,
6.32% 80.67%,
10.69% 91.75%,
9.18% 99.36%,
47.27% 99.44%,
92.39% 99.2%,
91.85% 86.29%,
94.77% 74.28%,
88.08% 54.82%,
83.74% 45.14%,
78.61% 37.63%,
71.62% 34.03%,
64.62% 23.61%,
63.88% 18.13%,
62.23% 10.25%
);
}
.grid-pattern {
width: 100%;
height: 100%;
background-size: cover;
background-position: center center;
background-repeat: repeat;
background-image: url("/static/grid.svg");
}
.radial-overlay {
background: radial-gradient(
circle,
rgba(24, 24, 27, 0) 0%,
rgba(24, 24, 27, 1) 50%
);
}
.polka-pattern {
background-color: #18181b;
opacity: 1;
background-image: radial-gradient(#27272a 1.3px, transparent 1.3px),
radial-gradient(#27272a 1.3px, #18181b 1.3px);
background-size: 52px 52px;
background-position:
0 0,
26px 26px;
}
}

View file

@ -1,6 +1,6 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
content: ["./pkg/pages/**/*.go", "./public/views/**/*.html"], content: ["./page.go", "./views/**/*.html"],
theme: { theme: {
extend: { extend: {
fontFamily: { fontFamily: {

214
views/index.html Normal file
View file

@ -0,0 +1,214 @@
<!doctype html>
<html lang="en" class="relative h-full w-full scroll-smooth bg-zinc-900 font-inter text-white">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Juan Wu software developer portfolio site" />
<meta name="author" content="Juan Wu" />
<meta name="keywords" content="software developer, fullstack developer, portfolio" />
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png" />
<link rel="manifest" href="/static/site.webmanifest" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="/static/styles.css" />
<link rel="preload" fetchpriority="high" as="image" href="/static/touching-grass-pic.jpg" type="image/jpeg" />
<link rel="preload" fetchpriority="high" as="image" href="/static/grid.svg" type="image/svg+xml" />
<script src="https://unpkg.com/htmx.org@1.9.6"
integrity="sha384-FhXw7b6AlE/jyjlZH5iHa/tTe9EpJ1Y55RjcgPbjeWMskSxZt1v9qkxLJWNJaGni"
crossorigin="anonymous"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
<title>Juan Wu | Portfolio</title>
</head>
<body class="h-full w-full">
<div class="polka-pattern fixed inset-0 -z-10" aria-hidden="true"></div>
<header class="border-b border-white/10 bg-zinc-900 px-8 lg:px-16">
<div class="flex items-center py-6 font-medium">
<div>
<span class="text-white"> JUAN WU </span>
<div class="group relative text-sm text-teal-400 hover:line-through">
SOFTWARE DEVELOPER
<span aria-hidden="true"
class="absolute left-0 top-full hidden text-red-500 group-hover:inline">CHROOT</span>
</div>
</div>
<button class="ml-auto lg:hidden" aria-label="Open mobile navigation menu"
_="on click remove .translate-x-full from <nav /> then add .overflow-hidden to <body />">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" aria-hidden="true" class="h-6 w-6">
<path stroke-linecap="round" stroke-linejoin="round"
d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
</svg>
</button>
<nav
class="fixed inset-0 z-10 translate-x-full items-center bg-zinc-900 transition-transform lg:relative lg:ml-auto lg:flex lg:translate-x-0 lg:bg-transparent">
<div class="flex justify-end p-8">
<button class="block lg:hidden" aria-label="close mobile navigation menu"
_="on click add .translate-x-full to <nav /> then remove .overflow-hidden from <body />">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="h-6 w-6 text-red-500">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<ul class="flex flex-col items-center justify-center gap-8 uppercase text-white lg:flex-row lg:gap-4">
<li>
<a href="#projects"
class="relative z-0 p-2 after:absolute after:left-0 after:top-1/2 after:-z-10 after:h-3/4 after:w-0 after:-translate-y-1/2 after:bg-gradient-to-r after:from-purple-500 after:to-pink-500 after:transition-all hover:after:w-full focus:after:w-full">
Projects
</a>
</li>
<li aria-hidden="true">
<span aria-hidden="true" class="hidden select-none font-normal text-fuchsia-400 lg:inline">
-
</span>
</li>
<li>
<a href="https://github.com/juancwu"
class="relative z-0 p-2 after:absolute after:left-1/2 after:top-1/2 after:-z-10 after:h-3/4 after:w-full after:-translate-x-1/2 after:-translate-y-1/2 after:scale-75 after:bg-white after:opacity-0 after:transition-all hover:text-gray-950 hover:after:scale-100 hover:after:opacity-100 focus:text-gray-950 focus:after:scale-100 focus:after:opacity-100">GitHub</a>
</li>
<li aria-hidden="true">
<span aria-hidden="true" class="hidden select-none font-normal text-fuchsia-400 lg:inline">
-
</span>
</li>
<li>
<a href="https://linkedin.com/in/juancwu"
class="relative z-0 p-2 after:absolute after:-left-2 after:top-1/2 after:-z-10 after:h-3/4 after:w-full after:bg-gradient-to-r after:from-sky-500 after:to-indigo-500 after:opacity-0 after:transition-all hover:after:left-0 hover:after:top-0 hover:after:translate-y-[15%] hover:after:opacity-100 focus:after:left-0 focus:after:top-0 focus:after:translate-y-[15%] focus:after:opacity-100">LinkedIn</a>
</li>
<!--
<li aria-hidden="true">
<span
aria-hidden="true"
class="hidden select-none font-normal text-fuchsia-400 lg:inline"
>
-
</span>
</li>
<li>
<a
href="https://linkedin.com/in/juancwu"
class="relative z-0 p-2 after:absolute after:right-0 after:top-1/2 after:-z-10 after:h-3/4 after:w-0 after:-translate-y-1/2 after:-scale-x-100 after:bg-gradient-to-r after:from-orange-500 after:to-yellow-500 after:transition-all hover:after:w-full focus:after:w-full"
>RESUME</a
>
</li>
-->
</ul>
</nav>
</div>
</header>
<main class="relative z-0 px-16 py-24">
<div class="grid-pattern absolute inset-0" aria-hidden="true"></div>
<div class="radial-overlay absolute inset-0" aria-hidden="true"></div>
<section id="hero" aria-label="Hero Section" class="flex h-full w-full items-center justify-center">
<div class="flex items-center justify-center gap-16">
<div class="relative z-10 space-y-4 text-white">
<p class="text-md text-zinc-300 lg:text-xl">
Hello there <span aria-hidden="true">👋</span>,
</p>
<p class="text-5xl font-bold text-zinc-100 md:text-6xl lg:text-7xl xl:text-9xl">
I am Juan
</p>
<p class="text-2xl text-zinc-300 md:text-2xl lg:text-3xl xl:text-4xl">
I am a Software Developer during the day
</p>
<p class="text-2xl text-zinc-300 md:text-2xl lg:text-3xl xl:text-4xl">
<span aria-label="and">&amp;</span>
work at
<a href="https://lauriercs.ca"
class="relative z-0 whitespace-nowrap font-medium underline decoration-sky-400 transition-all after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full">LCS</a>
and
<a href="https://hawkhacks.ca"
class="relative z-0 whitespace-nowrap font-medium underline decoration-sky-400 transition-all after:absolute after:left-0 after:top-0 after:-z-10 after:h-0 after:w-full after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:h-full focus:text-white focus:decoration-sky-500 focus:after:h-full">Hawk
Hacks</a>
at night
</p>
<p class="text-xs">(send help, I have been enslaved)</p>
<div class="h-4" aria-hidden="true"></div>
<p class="text-4xl font-medium md:inline-block lg:text-5xl">
Check out my
</p>
<a href="#projects"
class="colourful-card inline-block text-4xl font-semibold focus:outline-offset-2 md:ml-2 lg:mt-4 lg:text-5xl">
PROJECTS
</a>
</div>
<div
class="clip-me-from-grass hidden bg-gray-200 p-2 opacity-100 drop-shadow-lg lg:block lg:max-w-lg retina:h-auto retina:w-96">
<img class="clip-me-from-grass z-0 h-full w-full" src="/static/touching-grass-pic.jpg"
alt="Juan's portrait photo of him touching grass (figuratively)" />
</div>
</div>
</section>
</main>
<div class="hidden h-12 lg:block" aria-hidden="true"></div>
<section id="projects" aria-label="Juan's Projects" class="relative px-8">
<div class="relative flex items-center justify-center pt-8">
<div class="flex flex-col items-center">
<h1 class="flex flex-col gap-2 p-8 text-3xl font-bold uppercase md:text-5xl">
<span class="relative text-xl font-medium text-zinc-300 md:text-2xl">Welcome to</span>
<span
class="relative inline-block before:absolute before:-inset-1 before:block before:-skew-y-3 before:scale-90 before:bg-gradient-to-r before:from-purple-500 before:to-pink-500 before:opacity-60 before:transition-all hover:before:scale-100">
<span class="relative"> Project Graveyard </span>
</span>
</h1>
<a href="https://shoto.at/l/dumb-projects"
class="relative underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full">
Juan's dumb projects archive
</a>
</div>
</div>
<div class="h-16" aria-hidden="true"></div>
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2 2xl:grid-cols-3">
{{ range .Projects }}
<div
class="flex w-full flex-col justify-between gap-4 rounded border-2 bg-zinc-800/10 p-6 shadow-lg backdrop-blur-[2px] transition {{ .Classes }}">
<div>
<div class="flex flex-col items-center justify-between gap-4 md:flex-row md:gap-0">
{{ if gt (len .URL) 1 }}
<a href="{{ .URL }}"
class="relative flex items-center gap-2 transition-colors hover:text-sky-400">
<h3 class="text-2xl font-medium">
{{ .Name }}
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" class="-mt-1 inline-block h-6 w-6">
<path stroke-linecap="round" stroke-linejoin="round"
d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
</svg>
</h3>
</a>
{{ else }}
<h3 class="text-2xl font-medium">{{ .Name }}</h3>
{{ end }}
<ul class="flex gap-2">
{{ range .TechList }}
<li>
<a href="{{ .TechURL }}"
class="relative text-sm underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full md:text-base">{{
.TechName }}</a>
</li>
{{ end }}
</ul>
</div>
<div class="h-4" aria-hidden="true"></div>
<hr class="border-white/25" />
<div class="h-4" aria-hidden="true"></div>
<p>{{ .Description }}</p>
</div>
<p>
Checkout the code in
<a href="{{ .Repo }}"
class="relative underline decoration-sky-400 after:absolute after:left-0 after:top-0 after:-z-10 after:h-full after:w-0 after:bg-sky-500 after:transition-all hover:text-white hover:decoration-sky-500 hover:after:w-full focus:text-white focus:decoration-sky-500 focus:after:w-full">GitHub</a>
</p>
</div>
{{ end }}
</div>
</section>
<div class="h-64" aria-hidden="true"></div>
</body>
</html>

64
views/styles.css Normal file
View file

@ -0,0 +1,64 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.colourful-card {
@apply relative bg-white p-2 text-zinc-950 transition-all after:absolute after:-right-2 after:top-2 after:-z-10 after:h-full after:w-full after:bg-gradient-to-r after:from-purple-500 after:to-pink-500 after:transition-all hover:bg-transparent hover:text-white hover:after:right-0 hover:after:top-0 focus:bg-transparent focus:text-white focus:after:right-0 focus:after:top-0;
}
.clip-me-from-grass {
clip-path: polygon(58.36% 5.19%,
52.34% 3.68%,
45.85% 3.05%,
37.74% 7.64%,
35.66% 12.39%,
34.82% 19.98%,
32.57% 27.81%,
29.87% 32.92%,
22.01% 37.14%,
17.02% 42.9%,
10.6% 53.43%,
8.22% 70.71%,
6.32% 80.67%,
10.69% 91.75%,
9.18% 99.36%,
47.27% 99.44%,
92.39% 99.2%,
91.85% 86.29%,
94.77% 74.28%,
88.08% 54.82%,
83.74% 45.14%,
78.61% 37.63%,
71.62% 34.03%,
64.62% 23.61%,
63.88% 18.13%,
62.23% 10.25%);
}
.grid-pattern {
width: 100%;
height: 100%;
background-size: cover;
background-position: center center;
background-repeat: repeat;
background-image: url("/static/grid.svg");
}
.radial-overlay {
background: radial-gradient(circle,
rgba(24, 24, 27, 0) 0%,
rgba(24, 24, 27, 1) 50%);
}
.polka-pattern {
background-color: #18181b;
opacity: 1;
background-image: radial-gradient(#27272a 1.3px, transparent 1.3px),
radial-gradient(#27272a 1.3px, #18181b 1.3px);
background-size: 52px 52px;
background-position:
0 0,
26px 26px;
}
}