Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates #52

Merged
merged 6 commits into from
Dec 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
16 changes: 16 additions & 0 deletions src/lib/content/work/mbr.svx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
name: Medical Bill Rights
url: https://www.cms.gov/medical-bill-rights
slug: medical-bill-rights
description: 'react forms, drupal, salesforce, internationalization'
type: professional
date: 2023-06-01
---

The No Surprises Act is a federal law that went into effect on January 1, 2022.

The Medical Bill Rights sub-site for https://cms.gov is a collection of resources to inform and assist every American their rights as enshrined by the No Surprises Act. This law provides protections against "surprise medical bills", which can be any bill that has greater than $400 difference than what you were initially told.

The MBR site contains two React apps and 30 additional pages of informational content, initially available in English and Spanish. I architected both React apps and consulted on the Drupal implementation of content. The main React app is a human-friendly form for American consumers to register complaints related to surprise medical bills. This form submits data to Salesforce, where a government team can review and responds to every complaint submitted. The second React app is a short question flow to direct users to the appropriate resource page for their situation.

This sub-site was built in about four months, launching smoothly after numerous pivots and unexpected challenges along the way.
File renamed without changes.
10 changes: 5 additions & 5 deletions src/routes/+layout.svelte → src/routes/(main)/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script>
import '../tailwind.css';
import Header from '../components/Header.svelte';
import Icon from '../components/Icon.svelte';
import NavLink from '../components/NavLink.svelte';
import Slice from '../components/Slice.svelte';
import '../../tailwind.css';
import Header from '$lib/components/Header.svelte';
import Icon from '$lib/components/Icon.svelte';
import NavLink from '$lib/components/NavLink.svelte';
import Slice from '$lib/components/Slice.svelte';
import { page } from '$app/stores';
import { onMount } from 'svelte';
import { MY_TWITTER_HANDLE, GH_USER, SITE_TITLE } from '$lib/siteConfig';
Expand Down
4 changes: 2 additions & 2 deletions src/routes/+page.svelte → src/routes/(main)/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script>
import Slice from '../components/Slice.svelte';
import Card from '../components/Card.svelte';
import Slice from '$lib/components/Slice.svelte';
import Card from '$lib/components/Card.svelte';
import {
SITE_URL,
SITE_TITLE,
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script>
import { MY_TWITTER_HANDLE, SITE_URL } from '$lib/siteConfig';
import Comments from '../../components/Comments.svelte';
import Comments from '$lib/components/Comments.svelte';

import 'prism-themes/themes/prism-shades-of-purple.min.css';
import Reactions from '../../components/Reactions.svelte';
import Reactions from '$lib/components/Reactions.svelte';
import { page } from '$app/stores';

/** @type {import('./$types').PageData} */
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
import PostItem from '../../components/PostItem.svelte';
import PostItem from '$lib/components/PostItem.svelte';
import queryString from 'query-string';
import { onMount } from 'svelte';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import satori from 'satori';
import { Resvg } from '@resvg/resvg-js';
import PTSerif from '$lib/font/PTSerif-Regular.ttf';
import { html as toReactNode } from 'satori-html';
import Og from '../../components/Og.svelte';
import Og from '$lib/components/Og.svelte';

const height = 400;
const width = 800;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script>
import { SITE_DESCRIPTION } from '$lib/siteConfig';
import Slice from '../../components/Slice.svelte';
import Slice from '$lib/components/Slice.svelte';
</script>

<svelte:head>
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import { SITE_TITLE } from '$lib/siteConfig';
import Slice from '../../components/Slice.svelte';
import ProjectItem from '../../components/ProjectItem.svelte';
import Slice from '$lib/components/Slice.svelte';
import ProjectItem from '$lib/components/ProjectItem.svelte';

export let data;
</script>
Expand Down
File renamed without changes.
7 changes: 7 additions & 0 deletions src/routes/(nowrapper)/+layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
// keep tailwind, but no layout otherwise
// any route in this group can render without header/footer
import '../../tailwind.css';
</script>

<slot />
8 changes: 8 additions & 0 deletions src/routes/(nowrapper)/christmas/+page.server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { json } from './christmas';

/** @type {import('./$types').PageLoad} */
export function load() {
return {
...json
};
}
159 changes: 159 additions & 0 deletions src/routes/(nowrapper)/christmas/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<script>
import { onMount } from 'svelte'
import './christmas.css'
export let data

// https://codepen.io/HektorW/pen/ZBryeV
onMount(() => {
// https://codepen.io/EightArmsHQ/pen/PbPQyd
const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')

let width, height, lastNow
let snowflakes
const maxSnowflakes = 100

function init() {
snowflakes = []
resize()
render(lastNow = performance.now())
}

function render(now) {
requestAnimationFrame(render)

const elapsed = now - lastNow
lastNow = now

ctx.clearRect(0, 0, width, height)
if (snowflakes.length < maxSnowflakes)
snowflakes.push(new Snowflake())

ctx.fillStyle = ctx.strokeStyle = '#fff'

snowflakes.forEach(snowflake => snowflake.update(elapsed, now))
}

function pause() {
cancelAnimationFrame(render)
}
function resume() {
lastNow = performance.now()
requestAnimationFrame(render)
}


class Snowflake {
constructor() {
this.spawn()
}

spawn(anyY = false) {
this.x = rand(0, width)
this.y = anyY === true
? rand(-50, height + 50)
: rand(-50, -10)
this.xVel = rand(-.05, .05)
this.yVel = rand(.02, .1)
this.angle = rand(0, Math.PI * 2)
this.angleVel = rand(-.001, .001)
this.size = rand(7, 12)
this.sizeOsc = rand(.01, .5)
}

update(elapsed, now) {
const xForce = rand(-.001, .001);

if (Math.abs(this.xVel + xForce) < .075) {
this.xVel += xForce
}

this.x += this.xVel * elapsed
this.y += this.yVel * elapsed
this.angle += this.xVel * 0.05 * elapsed //this.angleVel * elapsed

if (
this.y - this.size > height ||
this.x + this.size < 0 ||
this.x - this.size > width
) {
this.spawn()
}

this.render()
}

render() {
ctx.save()
const { x, y, angle, size } = this
ctx.beginPath()
ctx.arc(x, y, size * 0.2, 0, Math.PI * 2, false)
ctx.fill()
ctx.restore()
}
}

// Utils
const rand = (min, max) => min + Math.random() * (max - min)

function resize() {
width = canvas.width = window.innerWidth
height = canvas.height = window.innerHeight
}

window.addEventListener('resize', resize)
window.addEventListener('blur', pause)
window.addEventListener('focus', resume)
init()
});
</script>

<svelte:head>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Gloock&family=Pragati+Narrow">
</svelte:head>

<canvas id="snow"></canvas>


<div class="holly-container">
<img src="/assets/holly-clipart-corner-11.png" alt="" class="holly left"/>
<img src="/assets/holly-clipart-corner-11.png" alt="" class="holly right"/>
</div>

<section class="pt-[10rem] h-full text-center text-white serif">
<h1 class="text-6xl mb-10 text-shadow">{data.title}</h1>
<p>at</p>
<p class="text-3xl mt-6 mb-12 text-shadow">{data.where} | <span class="sans">{data.when}</span><p>
<!-- <p class="text-4xl sans">{data.when}</p>
<p class="text-4xl my-6">at {data.where}<p> -->


<h2 class="text-2xl mt-20 mb-6 underline underline-offset-4">Schedule</h2>
<ul class="list-none">
{#each data.agenda as {event, time}}
<li class="my-2">
<p class="text-lg">{event} - <span class="sans">{time}<span></p>
</li>
{/each}
</ul>


<h2 class="text-2xl mt-20 mb-6 underline underline-offset-4"> Menu </h2>

<ul class="list-none">
{#each data.menu as {name, ingredients}}
<li class="my-6">
<p class="text-lg">{name}</p>
<p class="sans">{ingredients}</p>
</li>
{/each}
</ul>

<p class="mt-12 text-md">{data.disclaimer}</p>

</section>

<div class="holly-container">
<img src="/assets/holly-clipart-corner-11.png" alt="" class="holly bottom left"/>
<img src="/assets/holly-clipart-corner-11.png" alt="" class="holly bottom right"/>
</div>
50 changes: 50 additions & 0 deletions src/routes/(nowrapper)/christmas/christmas.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
body {
background-color: rgb(17 24 39 / var(--tw-bg-opacity)) !important;
}
body::-webkit-scrollbar-thumb {
background: repeating-linear-gradient(60deg, red 0 9%, white 10% 18%) !important;
border-radius: 100vw !important;
margin-block: 10px !important;
}
body::-webkit-scrollbar-track {
background: powderblue !important;
}

.serif {
font-family: 'Gloock', serif;
}
.sans {
font-family: 'Pragati Narrow', sans-serif;
}

#snow {
position: fixed;
height: 100%;
left: 0;
top: 0;
width: 100%;
z-index: 1;
}

.holly-container {
position: relative;
}
.holly {
position: absolute;
top: 0;
background: none;
width: 20%;
}
.left {
left: 0;
}
.right {
right: 0;
transform: scaleX(-1);
}
.bottom {
transform: scaleY(-1);
}
.bottom.right {
transform: scaleX(-1) scaleY(-1);
}
42 changes: 42 additions & 0 deletions src/routes/(nowrapper)/christmas/christmas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
export const json = {
"title": "Christmas Dinner",
"where": "the purr palace",
"when": "december 23, 2023",
"agenda": [
{
"event": "cocktails",
"time": "first"
},
{
"event": "dinner",
"time": "next"
},
{
"event": "presents",
"time": "eventually"
},
{
"event": "fun & games",
"time": "throughout"
}
],
"menu": [
{
"name": "baked potato soup",
"ingredients": "yukon gold potatoes, cream, roasted pork belly, chives, cheese"
},
{
"name": "winter salad",
"ingredients": "mixed greens, apples, cranberries, walnuts, cranberry vinaigrette",
},
{
"name": "duck a l'orange",
"ingredients": "roasted duck breast, orange pan sauce, porcini mushroom risotto, baked vegetables",
},
{
"name": "dessert",
"ingredients": "creme brulee, assorted cookies, mousse"
}
],
"disclaimer": "all items are gluten-free, however some may contain dairy products"
}
Binary file added static/assets/holly-clipart-corner-11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading