diff --git a/assets/css/app.css b/assets/css/app.css index 378c8f9..a3c19bb 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -3,3 +3,48 @@ @import "tailwindcss/utilities"; /* This file is for your main application CSS */ + +*, +*:before, +*:after { + box-sizing: inherit; +} + +html { + height: 100%; + box-sizing: border-box; + touch-action: manipulation; + font-feature-settings: 'case' 1, 'rlig' 1, 'calt' 0; +} + +html, +body { + font-family: -apple-system, system-ui, BlinkMacSystemFont, 'Helvetica Neue', + 'Helvetica', sans-serif; + text-rendering: optimizeLegibility; + -moz-osx-font-smoothing: grayscale; + @apply text-white bg-white antialiased; +} + +body { + position: relative; + min-height: 100%; + margin: 0; +} + +a { + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +.animated { + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-duration: 1s; + animation-duration: 1s; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +.height-screen-helper { + height: calc(100vh - 80px); +} diff --git a/assets/js/react/App.tsx b/assets/js/react/App.tsx index 4a050bc..c9f6b81 100644 --- a/assets/js/react/App.tsx +++ b/assets/js/react/App.tsx @@ -1,9 +1,10 @@ -import * as React from 'react' +import * as React from "react"; +import { Footer } from "./components/Footer"; export default function App() { return (
- Hello React! +
- ) + ); } diff --git a/assets/js/react/components/Container.tsx b/assets/js/react/components/Container.tsx new file mode 100644 index 0000000..cd06fd2 --- /dev/null +++ b/assets/js/react/components/Container.tsx @@ -0,0 +1,23 @@ +import * as React from "react"; +import clsx from "clsx"; + +type ContainerProps = { + as?: T; + className?: string; + children: React.ReactNode; +}; + +export function Container({ + as, + className, + children, +}: Omit, keyof ContainerProps> & + ContainerProps) { + let Component = as ?? "div"; + + return ( + +
{children}
+
+ ); +} diff --git a/assets/js/react/components/Footer.tsx b/assets/js/react/components/Footer.tsx new file mode 100644 index 0000000..0e3a438 --- /dev/null +++ b/assets/js/react/components/Footer.tsx @@ -0,0 +1,64 @@ +import * as React from "react"; + +import { Container } from "./Container"; +import { Logo } from "./Logo"; + +const navigation = [ + { + title: "Students", + links: [{ title: "Find a Coach", href: "/c/" }], + }, + { + title: "Company", + links: [ + { title: "About Us", href: "/about/" }, + { title: "Contact Us", href: "/contact/" }, + ], + }, +]; + +function Navigation() { + return ( + + ); +} + +export function Footer() { + return ( + +
+ +
+
+ + + +

+ © BoardWise LLC {new Date().getFullYear()} +

+
+
+ ); +} diff --git a/assets/js/react/components/Logo.tsx b/assets/js/react/components/Logo.tsx new file mode 100644 index 0000000..9cb752e --- /dev/null +++ b/assets/js/react/components/Logo.tsx @@ -0,0 +1,25 @@ +import * as React from "react"; +import clsx from "clsx"; + +import LogoMark from "../icons/Logomark"; + +export function Logo({ + invert = false, +}: React.ComponentPropsWithoutRef<"svg"> & { invert?: boolean }) { + return ( +
+ +

+ BoardWise +

+
+ ); +} diff --git a/assets/js/react/icons/Logomark.tsx b/assets/js/react/icons/Logomark.tsx new file mode 100644 index 0000000..c7c1202 --- /dev/null +++ b/assets/js/react/icons/Logomark.tsx @@ -0,0 +1,33 @@ +import * as React from "react"; + +const SvgComponent = ({ invert = false, size = 25, ...props }) => { + const color = invert ? "rgb(255, 255, 255)" : "rgb(10 10 10)"; + const radius = 5; + const roundedTopRightPath = ` + M ${size / 2} 0 + H ${size - radius} + Q ${size} 0, ${size} ${radius} + V ${size / 2} + H ${size / 2} + Z`; + const roundedBottomLeftPath = ` + M 0 ${size - radius} + Q 0 ${size}, ${radius} ${size} + H ${size / 2} + V ${size / 2} + H 0 + Z`; + + return ( + + + + + ); +}; +export default SvgComponent; diff --git a/assets/node-packages.nix b/assets/node-packages.nix index 506e303..4b9959a 100644 --- a/assets/node-packages.nix +++ b/assets/node-packages.nix @@ -4,6 +4,15 @@ let sources = { + "clsx-2.0.0" = { + name = "clsx"; + packageName = "clsx"; + version = "2.0.0"; + src = fetchurl { + url = "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz"; + sha512 = "rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q=="; + }; + }; "js-tokens-4.0.0" = { name = "js-tokens"; packageName = "js-tokens"; @@ -56,6 +65,7 @@ let version = "0.1.0"; src = ./.; dependencies = [ + sources."clsx-2.0.0" sources."js-tokens-4.0.0" sources."loose-envify-1.4.0" sources."react-18.2.0" diff --git a/assets/package-lock.json b/assets/package-lock.json index e96b46b..36cdd96 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -8,6 +8,7 @@ "name": "boardwise", "version": "0.1.0", "dependencies": { + "clsx": "^2.0.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -72,6 +73,14 @@ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", "dev": true }, + "node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", @@ -172,6 +181,11 @@ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", "dev": true }, + "clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==" + }, "csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", diff --git a/assets/package.json b/assets/package.json index ebf7433..e3535c6 100644 --- a/assets/package.json +++ b/assets/package.json @@ -2,6 +2,7 @@ "name": "boardwise", "version": "0.1.0", "dependencies": { + "clsx": "^2.0.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/assets/tsconfig.json b/assets/tsconfig.json index 0b48eff..fab4f2c 100644 --- a/assets/tsconfig.json +++ b/assets/tsconfig.json @@ -3,6 +3,8 @@ "compilerOptions": { // Keep in mind that ES6+ syntax to ES5 is not supported in esbuild yet. "target": "es2016", + // https://www.typescriptlang.org/docs/handbook/modules/theory.html + "module": "nodenext", // Even when transpiling a single module, the TypeScript compiler actually // parses imported files so it can tell whether an imported name is a type // or a value. However, tools like esbuild compile each file in isolation so @@ -25,6 +27,6 @@ // calls. It seems like the "react" value mirrors esbuild's native // "transform" option, but it isn't obvious how these two relate from the // documentation: https://esbuild.github.io/api/#jsx. - "jsx": "react" + "jsx": "react", } } diff --git a/config/config.exs b/config/config.exs index 4a6111e..2356abd 100644 --- a/config/config.exs +++ b/config/config.exs @@ -47,7 +47,7 @@ config :boardwise, BoardWise.Mailer, adapter: Swoosh.Adapters.Local # specified in this command (e.g. `useDefineForClassFields` as explained in # https://esbuild.github.io/content-types/#tsconfig-json). config :esbuild, - version: "0.17.11", + version: "0.19.7", default: [ args: ~w( ./js/app.js @@ -65,7 +65,7 @@ config :esbuild, # Configure tailwind (the version is required) config :tailwind, - version: "3.3.2", + version: "3.3.5", default: [ args: ~w( --config=tailwind.config.js