diff --git a/src/web/.web/bun.lockb b/src/web/.web/bun.lockb index 55f4e02..2a35965 100755 Binary files a/src/web/.web/bun.lockb and b/src/web/.web/bun.lockb differ diff --git a/src/web/.web/package.json b/src/web/.web/package.json index 139527e..bcc6b67 100644 --- a/src/web/.web/package.json +++ b/src/web/.web/package.json @@ -10,6 +10,7 @@ "@emotion/react": "11.11.1", "@radix-ui/themes": "^2.0.0", "axios": "1.6.0", + "framer-motion": "^11.0.8", "json5": "2.2.3", "lucide-react": "0.314.0", "next": "14.0.1", diff --git a/src/web/.web/pages/404.js b/src/web/.web/pages/404.js index 20baf35..30da05e 100644 --- a/src/web/.web/pages/404.js +++ b/src/web/.web/pages/404.js @@ -8,14 +8,15 @@ import { WifiOffIcon as LucideWifiOffIcon } from "lucide-react" import { keyframes } from "@emotion/react" import { Box as RadixThemesBox, Dialog as RadixThemesDialog, Flex as RadixThemesFlex, Heading as RadixThemesHeading, Link as RadixThemesLink, Text as RadixThemesText } from "@radix-ui/themes" import env from "/env.json" +import { motion } from "framer-motion" import NextLink from "next/link" import NextHead from "next/head" -export function Fragment_966c0378eb9d65bdfb5286644be9b831 () { - const [addEvents, connectErrors] = useContext(EventLoopContext); +export function Fragment_e9a05c105aa9215aeba52aeec8fe2e76 () { const state = useContext(StateContexts.state) + const [addEvents, connectErrors] = useContext(EventLoopContext); return ( @@ -33,6 +34,9 @@ export function Fragment_966c0378eb9d65bdfb5286644be9b831 () { ) } + import { useIsPresent } from "framer-motion"; + + export function Fragment_14636cc997c0546c0967a25d8e600f96 () { const [addEvents, connectErrors] = useContext(EventLoopContext); @@ -78,68 +82,63 @@ export default function Component() {
- +
+ + - - - + + {`About`} - - - - + + {`Projects`} - - - - + + {`Resume`} - - - - + + {`Blog`} - - - - + + {`Shop`} - + + {`Whoops, this page doesn't exist...`} - + + @@ -149,6 +148,8 @@ export default function Component() { + + diff --git a/src/web/.web/pages/index.js b/src/web/.web/pages/index.js index e3fcb1a..11b104b 100644 --- a/src/web/.web/pages/index.js +++ b/src/web/.web/pages/index.js @@ -8,14 +8,15 @@ import { WifiOffIcon as LucideWifiOffIcon } from "lucide-react" import { keyframes } from "@emotion/react" import { Box as RadixThemesBox, Dialog as RadixThemesDialog, Flex as RadixThemesFlex, Heading as RadixThemesHeading, Link as RadixThemesLink, Text as RadixThemesText } from "@radix-ui/themes" import env from "/env.json" +import { motion } from "framer-motion" import NextLink from "next/link" import NextHead from "next/head" -export function Fragment_966c0378eb9d65bdfb5286644be9b831 () { - const [addEvents, connectErrors] = useContext(EventLoopContext); +export function Fragment_e9a05c105aa9215aeba52aeec8fe2e76 () { const state = useContext(StateContexts.state) + const [addEvents, connectErrors] = useContext(EventLoopContext); return ( @@ -33,6 +34,9 @@ export function Fragment_966c0378eb9d65bdfb5286644be9b831 () { ) } + import { useIsPresent } from "framer-motion"; + + export function Fragment_14636cc997c0546c0967a25d8e600f96 () { const [addEvents, connectErrors] = useContext(EventLoopContext); @@ -78,56 +82,48 @@ export default function Component() { <Fragment> <Fragment> <div css={{"position": "fixed", "width": "100vw", "height": "0"}}> - <Fragment_966c0378eb9d65bdfb5286644be9b831/> + <Fragment_e9a05c105aa9215aeba52aeec8fe2e76/> </div> <Fragment_14636cc997c0546c0967a25d8e600f96/> </Fragment> + <RadixThemesBox> + <motion.div animate={{"opacity": 1, "y": 0, "transition": {"duration": 0.5, "ease": "easeInOut"}}} initial={{"opacity": 0, "y": -50}}> <RadixThemesBox> <RadixThemesBox> <RadixThemesFlex css={{"display": "flex", "alignItems": "center", "justifyContent": "center"}} gap={`7`}> <RadixThemesFlex> - <RadixThemesLink asChild={true} css={{"fontFamily": "ComicCode", "fontSize": 24, "color": "#000000", "textDecoration": "none", "&:hover": {"color": "#b8bb26"}}}> - <NextLink href={`http://about.timmypidashev.localhost`} passHref={true}> - <RadixThemesText as={`p`} css={{"color": "#ebdbb2", "fontFamily": "ComicCode", "fontSize": 24}}> + <RadixThemesLink css={{"fontFamily": "ComicCode", "fontSize": 24, "color": "#000000", "textDecoration": "none", "&:hover": {"color": "#b8bb26"}}}> + <RadixThemesText as={`p`} css={{"href": "/about", "fontFamily": "ComicCode", "fontSize": 24, "color": "#ebdbb2"}}> {`About`} </RadixThemesText> -</NextLink> </RadixThemesLink> </RadixThemesFlex> <RadixThemesFlex> - <RadixThemesLink asChild={true} css={{"fontFamily": "ComicCode", "fontSize": 24, "color": "#000000", "textDecoration": "none", "&:hover": {"color": "#b8bb26"}}}> - <NextLink href={`http://projects.timmypidashev.localhost`} passHref={true}> - <RadixThemesText as={`p`} css={{"color": "#ebdbb2", "fontFamily": "ComicCode", "fontSize": 24}}> + <RadixThemesLink css={{"fontFamily": "ComicCode", "fontSize": 24, "color": "#000000", "textDecoration": "none", "&:hover": {"color": "#b8bb26"}}}> + <RadixThemesText as={`p`} css={{"href": "/projects", "fontFamily": "ComicCode", "fontSize": 24, "color": "#ebdbb2"}}> {`Projects`} </RadixThemesText> -</NextLink> </RadixThemesLink> </RadixThemesFlex> <RadixThemesFlex> - <RadixThemesLink asChild={true} css={{"fontFamily": "ComicCode", "fontSize": 24, "color": "#000000", "textDecoration": "none", "&:hover": {"color": "#b8bb26"}}}> - <NextLink href={`http://resume.timmypidashev.localhost`} passHref={true}> - <RadixThemesText as={`p`} css={{"color": "#ebdbb2", "fontFamily": "ComicCode", "fontSize": 24}}> + <RadixThemesLink css={{"fontFamily": "ComicCode", "fontSize": 24, "color": "#000000", "textDecoration": "none", "&:hover": {"color": "#b8bb26"}}}> + <RadixThemesText as={`p`} css={{"href": "/resume", "fontFamily": "ComicCode", "fontSize": 24, "color": "#ebdbb2"}}> {`Resume`} </RadixThemesText> -</NextLink> </RadixThemesLink> </RadixThemesFlex> <RadixThemesFlex> - <RadixThemesLink asChild={true} css={{"fontFamily": "ComicCode", "fontSize": 24, "color": "#000000", "textDecoration": "none", "&:hover": {"color": "#b8bb26"}}}> - <NextLink href={`http://blog.timmypidashev.localhost`} passHref={true}> - <RadixThemesText as={`p`} css={{"color": "#ebdbb2", "fontFamily": "ComicCode", "fontSize": 24}}> + <RadixThemesLink css={{"fontFamily": "ComicCode", "fontSize": 24, "color": "#000000", "textDecoration": "none", "&:hover": {"color": "#b8bb26"}}}> + <RadixThemesText as={`p`} css={{"href": "/blog", "fontFamily": "ComicCode", "fontSize": 24, "color": "#ebdbb2"}}> {`Blog`} </RadixThemesText> -</NextLink> </RadixThemesLink> </RadixThemesFlex> <RadixThemesFlex> - <RadixThemesLink asChild={true} css={{"fontFamily": "ComicCode", "fontSize": 24, "color": "#000000", "textDecoration": "none", "&:hover": {"color": "#b8bb26"}}}> - <NextLink href={`http://shop.timmypidashev.localhost`} passHref={true}> - <RadixThemesText as={`p`} css={{"color": "#ebdbb2", "fontFamily": "ComicCode", "fontSize": 24}}> + <RadixThemesLink css={{"fontFamily": "ComicCode", "fontSize": 24, "color": "#000000", "textDecoration": "none", "&:hover": {"color": "#b8bb26"}}}> + <RadixThemesText as={`p`} css={{"href": "shop", "fontFamily": "ComicCode", "fontSize": 24, "color": "#ebdbb2"}}> {`Shop`} </RadixThemesText> -</NextLink> </RadixThemesLink> </RadixThemesFlex> </RadixThemesFlex> @@ -150,6 +146,8 @@ export default function Component() { </RadixThemesFlex> </RadixThemesFlex> </RadixThemesBox> +</RadixThemesBox> +</motion.div> </RadixThemesBox> <NextHead> <title> diff --git a/src/web/.web/reflex.install_frontend_packages.cached b/src/web/.web/reflex.install_frontend_packages.cached index 702224f..b263eb1 100644 --- a/src/web/.web/reflex.install_frontend_packages.cached +++ b/src/web/.web/reflex.install_frontend_packages.cached @@ -1 +1 @@ -['@radix-ui/themes@^2.0.0', 'lucide-react@0.314.0'],{"app_name": "landing", "loglevel": "info", "frontend_port": 3000, "frontend_path": "", "backend_port": 8000, "api_url": "http://localhost:8000", "deploy_url": "http://localhost:3000", "backend_host": "0.0.0.0", "db_url": "sqlite:///reflex.db", "redis_url": null, "telemetry_enabled": true, "bun_path": "/home/timmy/.local/share/reflex/bun/bin/bun", "cors_allowed_origins": ["*"], "tailwind": {"content": ["./pages/**/*.{js,ts,jsx,tsx}", "./utils/**/*.{js,ts,jsx,tsx}"]}, "timeout": 120, "next_compression": true, "event_namespace": null, "frontend_packages": [], "cp_backend_url": "https://rxcp-prod-control-plane.fly.dev", "cp_web_url": "https://control-plane.reflex.run", "gunicorn_worker_class": "uvicorn.workers.UvicornH11Worker"} \ No newline at end of file +['@radix-ui/themes@^2.0.0', 'framer-motion', 'lucide-react@0.314.0'],{"app_name": "web", "loglevel": "info", "frontend_port": 3000, "frontend_path": "", "backend_port": 8000, "api_url": "http://localhost:8000", "deploy_url": "http://localhost:3000", "backend_host": "0.0.0.0", "db_url": "sqlite:///reflex.db", "redis_url": null, "telemetry_enabled": true, "bun_path": "/home/timmy/.local/share/reflex/bun/bin/bun", "cors_allowed_origins": ["*"], "tailwind": {"content": ["./pages/**/*.{js,ts,jsx,tsx}", "./utils/**/*.{js,ts,jsx,tsx}"]}, "timeout": 120, "next_compression": true, "event_namespace": null, "frontend_packages": [], "cp_backend_url": "https://rxcp-prod-control-plane.fly.dev", "cp_web_url": "https://control-plane.reflex.run", "gunicorn_worker_class": "uvicorn.workers.UvicornH11Worker"} \ No newline at end of file diff --git a/src/web/.web/reflex.json b/src/web/.web/reflex.json index a5cbc9d..64b666f 100644 --- a/src/web/.web/reflex.json +++ b/src/web/.web/reflex.json @@ -1 +1 @@ -{"version": "0.4.3", "project_hash": 133404493286750418693195899744043836434} \ No newline at end of file +{"version": "0.4.3", "project_hash": 133404493286750418693195899744043836434, "last_version_check_datetime": "2024-03-12 00:10:35.074745"} \ No newline at end of file diff --git a/src/web/.web/utils/context.js b/src/web/.web/utils/context.js index f8832e1..333bc3e 100644 --- a/src/web/.web/utils/context.js +++ b/src/web/.web/utils/context.js @@ -1,7 +1,7 @@ import { createContext, useContext, useMemo, useReducer, useState } from "react" import { applyDelta, Event, hydrateClientStorage, useEventLoop, refs } from "/utils/state.js" -export const initialState = {"state": {"is_hydrated": false, "router": {"session": {"client_token": "", "client_ip": "", "session_id": ""}, "headers": {"host": "", "origin": "", "upgrade": "", "connection": "", "pragma": "", "cache_control": "", "user_agent": "", "sec_websocket_version": "", "sec_websocket_key": "", "sec_websocket_extensions": "", "accept_encoding": "", "accept_language": ""}, "page": {"host": "", "path": "", "raw_path": "", "full_path": "", "full_raw_path": "", "params": {}}}}, "state.on_load_internal_state": {}, "state.update_vars_internal_state": {}, "state.state": {}, "state.state.theme_state": {"current_theme": 0, "theme": {"background_color": "#282828"}, "themes": {"0": {"background_color": "#282828"}, "1": {"background_color": "#000000"}}}} +export const initialState = {"state": {"is_hydrated": false, "router": {"session": {"client_token": "", "client_ip": "", "session_id": ""}, "headers": {"host": "", "origin": "", "upgrade": "", "connection": "", "pragma": "", "cache_control": "", "user_agent": "", "sec_websocket_version": "", "sec_websocket_key": "", "sec_websocket_extensions": "", "accept_encoding": "", "accept_language": ""}, "page": {"host": "", "path": "", "raw_path": "", "full_path": "", "full_raw_path": "", "params": {}}}}, "state.on_load_internal_state": {}, "state.state": {}, "state.state.theme_state": {"current_theme": 0, "theme": {"background_color": "#282828"}, "themes": {"0": {"background_color": "#282828"}, "1": {"background_color": "#000000"}}}, "state.update_vars_internal_state": {}} export const defaultColorMode = "light" export const ColorModeContext = createContext(null); @@ -10,9 +10,9 @@ export const DispatchContext = createContext(null); export const StateContexts = { state: createContext(null), state__on_load_internal_state: createContext(null), - state__update_vars_internal_state: createContext(null), state__state: createContext(null), state__state__theme_state: createContext(null), + state__update_vars_internal_state: createContext(null), } export const EventLoopContext = createContext(null); export const clientStorage = {"cookies": {}, "local_storage": {}} @@ -81,31 +81,31 @@ export function EventLoopProvider({ children }) { export function StateProvider({ children }) { const [state, dispatch_state] = useReducer(applyDelta, initialState["state"]) const [state__on_load_internal_state, dispatch_state__on_load_internal_state] = useReducer(applyDelta, initialState["state.on_load_internal_state"]) - const [state__update_vars_internal_state, dispatch_state__update_vars_internal_state] = useReducer(applyDelta, initialState["state.update_vars_internal_state"]) const [state__state, dispatch_state__state] = useReducer(applyDelta, initialState["state.state"]) const [state__state__theme_state, dispatch_state__state__theme_state] = useReducer(applyDelta, initialState["state.state.theme_state"]) + const [state__update_vars_internal_state, dispatch_state__update_vars_internal_state] = useReducer(applyDelta, initialState["state.update_vars_internal_state"]) const dispatchers = useMemo(() => { return { "state": dispatch_state, "state.on_load_internal_state": dispatch_state__on_load_internal_state, - "state.update_vars_internal_state": dispatch_state__update_vars_internal_state, "state.state": dispatch_state__state, "state.state.theme_state": dispatch_state__state__theme_state, + "state.update_vars_internal_state": dispatch_state__update_vars_internal_state, } }, []) return ( <StateContexts.state.Provider value={ state }> <StateContexts.state__on_load_internal_state.Provider value={ state__on_load_internal_state }> - <StateContexts.state__update_vars_internal_state.Provider value={ state__update_vars_internal_state }> <StateContexts.state__state.Provider value={ state__state }> <StateContexts.state__state__theme_state.Provider value={ state__state__theme_state }> + <StateContexts.state__update_vars_internal_state.Provider value={ state__update_vars_internal_state }> <DispatchContext.Provider value={dispatchers}> {children} </DispatchContext.Provider> + </StateContexts.state__update_vars_internal_state.Provider> </StateContexts.state__state__theme_state.Provider> </StateContexts.state__state.Provider> - </StateContexts.state__update_vars_internal_state.Provider> </StateContexts.state__on_load_internal_state.Provider> </StateContexts.state.Provider> ) diff --git a/src/web/Dockerfile.dev b/src/web/Dockerfile.dev index d1cf3a2..3079d9e 100644 --- a/src/web/Dockerfile.dev +++ b/src/web/Dockerfile.dev @@ -1,53 +1,15 @@ -# Stage 1: init -FROM python:3.11 as init +# This Dockerfile is used to deploy a simple single-container Reflex app instance. +FROM python:3.11 # Copy local context to `/app` inside container (see .dockerignore) WORKDIR /app COPY . . -# Create virtualenv which will be copied into the final container -ENV VIRTUAL_ENV=/app/.venv -ENV PATH="$VIRTUAL_ENV/bin:$PATH" -RUN python3.11 -m venv $VIRTUAL_ENV - -# Install app requirements and reflex inside virtualenv +# Install app requirements and reflex in the container RUN pip install -r requirements.txt # Deploy templates and prepare app RUN reflex init -# Export static copy of frontend to /app/.web/_static -RUN echo "Exporting reflex app to shrink the docker image size, not actually a prod build." -RUN reflex export --frontend-only --no-zip - -# Copy static files out of /app to save space in backend image -RUN mv .web/_static /tmp/_static -RUN rm -rf .web && mkdir .web -RUN mv /tmp/_static .web/_static - -# Stage 2: copy artifacts into slim image -FROM python:3.11-slim -WORKDIR /app -RUN adduser --disabled-password --home /app reflex - -# Install Node.js and unzip -RUN apt-get update && apt-get install -y nodejs unzip curl && curl -fsSL https://bun.sh/install | bash - -# Copy only the necessary files from the "init" stage -COPY --chown=reflex --from=init /app/.venv /app/.venv -COPY --chown=reflex --from=init /app/requirements.txt /app/requirements.txt -COPY --chown=reflex --from=init /app /app - -# Change the ownership and permissions of /app/.local -USER root -RUN mkdir -p /app -RUN chown -R reflex /app -USER reflex - -# Activate the virtual environment and install application requirements -ENV PATH="/app/.venv/bin:$PATH" -RUN python3.11 -m venv /app/.venv -RUN /app/.venv/bin/pip install -r /app/requirements.txt - -# The following lines are for the specific command for the application. -CMD reflex init && reflex run --env dev +# Always apply migrations before starting the backend. +CMD reflex run --env dev diff --git a/src/web/web/components/navbar.py b/src/web/web/components/navbar.py index 66b74bf..87be852 100644 --- a/src/web/web/components/navbar.py +++ b/src/web/web/components/navbar.py @@ -6,27 +6,27 @@ def navbar(): rx.center( rx.flex( rx.link( - rx.text("About", color=color["white"]), href="/about" + rx.text("About", href="/about") ) ), rx.flex( rx.link( - rx.text("Projects", color=color["white"]), href="/projects" + rx.text("Projects", href="/projects") ) ), rx.flex( rx.link( - rx.text("Resume", color=color["white"]), href="/resume" + rx.text("Resume", href="/resume") ) ), rx.flex( rx.link( - rx.text("Blog", color=color["white"]), href="/blog" + rx.text("Blog", href="/blog") ) ), rx.flex( rx.link( - rx.text("Shop", color=color["white"]), href="shop" + rx.text("Shop", href="shop") ) ), spacing="7",