Compare commits
	
		
			2 commits
		
	
	
		
			f4aaf13c17
			...
			553b7bbc5f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 553b7bbc5f | |||
| ccaf5492ef | 
					 4 changed files with 29 additions and 14 deletions
				
			
		|  | @ -3,6 +3,7 @@ | |||
| from os.path import isfile, join, dirname | ||||
| from nicegui import ui | ||||
| 
 | ||||
| # TODO: Read from configuration | ||||
| _tab_to_content = { | ||||
|     "Home": "page_content/home.md", | ||||
|     "Portfolio": "page_content/portfolio.md", | ||||
|  | @ -11,6 +12,8 @@ _tab_to_content = { | |||
| } | ||||
| 
 | ||||
| _error_page = "page_content/404.md" | ||||
| _footer_block = "page_content/footer.html" | ||||
| 
 | ||||
| 
 | ||||
| def _get_content_from_file(file_name: str) -> str: | ||||
|     """ | ||||
|  | @ -25,23 +28,30 @@ def _get_content_from_file(file_name: str) -> str: | |||
| 
 | ||||
| def render_tab(tab_name: str): | ||||
|     file_name = _tab_to_content.get(tab_name, _error_page) | ||||
|     ui.markdown(_get_content_from_file(file_name), extras=['cuddled-lists', 'fenced-code-blocks', 'tables']) | ||||
|     with ui.scroll_area().classes('w-full h-screen no-wrap'): | ||||
|         ui.markdown(_get_content_from_file(file_name), extras=['cuddled-lists', 'fenced-code-blocks', 'tables']) | ||||
| 
 | ||||
| 
 | ||||
| def render_header() -> ui.tab_panels: | ||||
| def render_main() -> ui.tab_panels: | ||||
|     """ | ||||
|     Render sticky page header with navigation | ||||
|     """ | ||||
|     tab_names = _tab_to_content.keys() | ||||
|     with ui.tabs().classes('w-full') as tabs: | ||||
|         tab_list = {name: ui.tab(name) for name in tab_names} | ||||
|     with ui.tab_panels(tabs).classes('w-full') as header: | ||||
|     with ui.tab_panels(tabs).classes('w-full h-screen no-wrap') as header: | ||||
|         for name, t in tab_list.items(): | ||||
|             with ui.tab_panel(t): | ||||
|                 render_tab(name) | ||||
|     return header | ||||
| 
 | ||||
| def main(): | ||||
|     header = render_header() | ||||
|     header = render_main() | ||||
|     header.set_value(list(_tab_to_content.keys())[0]) | ||||
|     ui.query('.nicegui-content').classes('h-screen no-wrap') | ||||
|     ui.html(_get_content_from_file(_footer_block), tag="footer").classes("rounded-lg shadow-sm m-4 w-full text-center") | ||||
|     ui.run(dark=None, reload=False, title="Daniel McKnight") | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
							
								
								
									
										3
									
								
								site_mcknight_tech/page_content/footer.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								site_mcknight_tech/page_content/footer.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| <span class="text-sm text-gray-500 sm:text-center dark:text-gray-400"> | ||||
|     © 2025 Daniel McKnight. All Rights Reserved. | ||||
| </span> | ||||
|  | @ -2,3 +2,5 @@ | |||
| ## Coder, Sysadmin, Manager | ||||
| 
 | ||||
| I work in the design and implementation of voice assistants, LLMs, infrastructure, and plenty more. | ||||
| I built this site using [NiceGUI](https://nicegui.io/), with the source code available  | ||||
| [on Forgejo](https://forge.mcknight.tech/d_mcknight/website-mcknight-tech). | ||||
|  |  | |||
|  | @ -2,49 +2,49 @@ | |||
| I have developed and contributed to hundreds of open source repositories on GitHub (as well as some Private ones that | ||||
| I cannot share here). This is just a selection of some of my favorite projects and what I like about them. | ||||
| 
 | ||||
| ## Neon Core | ||||
| ## [Neon Core](https://github.com/neongeckocom/NeonCore) | ||||
| This is the primary project I contribute to as part of my work at NeonGecko. It started as work with the (now defunct) | ||||
| open source Mycroft AI project, turned into a proprietary fork, and then we ended up open sourcing that fork. Working on | ||||
| this project, I learned a lot about contributing to open source and managing open source projects. At the start, I learned | ||||
| how to be a helpful individual contributor, and later I was on the other side, learning how to interface with the community | ||||
| to balance internal goals with community feedback. | ||||
| 
 | ||||
| ## `neon-data-models` | ||||
| ## [`neon-data-models`](https://github.com/neongeckocom/neon-data-models) | ||||
| This repository contains barely any functional code, but it was an exercise in careful planning. | ||||
| It is structured into a logical hierarchy with documentation and unit tests. | ||||
| This project was not fully integrated to the extent I planned, but it proved invaluable in defining/validating | ||||
| messages sent between modules. The use of Pydantic also means that validator methods can be used to adapt an old-style | ||||
| input into a new one when an API changes. | ||||
| 
 | ||||
| ## `neon-users-service` | ||||
| ## [`neon-users-service`](https://github.com/neongeckocom/neon-users-service) | ||||
| This project defines a service for managing a user database with a flexible backend; initially, it supports SQLite for | ||||
| a standalone system (and easy development/testing) and MongoDb, which is what we used for production at NeonGecko. | ||||
| I implemented a very simple CRUD (Create/Read/Update/Delete) design, with RBAC (Role-Based Access Controls) to enable | ||||
| easy integration with applications. The design enables the service to be easily adapted to any user database and to | ||||
| allow other services to easily operate on user entries (with the proper permissions, of course). | ||||
| 
 | ||||
| ## `neon-hana` | ||||
| ## [`neon-hana`](https://github.com/neongeckocom/neon-hana) | ||||
| This is primarily a RESTful API used to access other services. This is one of the more complex FastAPI applications | ||||
| I have written; it implements JWT authentication and Pydantic models to validate requests/responses. | ||||
| 
 | ||||
| ## `neon-diana` | ||||
| ## [`neon-diana`](https://github.com/neongeckocom/neon-diana-utils) | ||||
| This isn't the prettiest project, but it is my first foray into writing Helm charts. The module provides some | ||||
| developer-oriented CLI tools for generating Helm charts to deploy the same services NeonGecko uses in production | ||||
| systems. | ||||
| 
 | ||||
| ## `neon-debos` | ||||
| ## [`neon-debos`](https://github.com/neongeckocom/neon_debos) | ||||
| This project was my first exposure to Go templates. It started as a fork of another similar project which I adapted to  | ||||
| our needs. As part of this project, I used squashfs/overlayfs to enable safe OS updates with methods to roll back or  | ||||
| reset an installation in case of any errors. To support this, I compiled custom kernels and implemented a customized | ||||
| initramfs. | ||||
| 
 | ||||
| ## `.github` | ||||
| ## [`.github`](https://github.com/neongeckocom/.github) | ||||
| This repository contains a number of shared GitHub Actions, in addition to the standard issue templates and other special | ||||
| files GitHub supports here. Creating this repository was part of an effort to consolidate code and make sprawling | ||||
| repositories more manageable.  | ||||
| 
 | ||||
| ## `neon-docs` | ||||
| ## [`neon-docs`](https://neongeckocom.github.io/neon-docs/) | ||||
| Just what it says, this is all documentation.  | ||||
| 
 | ||||
| ## This Site | ||||
| I fully defined this site using [nicegui](https://nicegui.io/)! | ||||
| ## [This Site](https://forge.mcknight.tech/d_mcknight/website-mcknight-tech) | ||||
| I built this site using [nicegui](https://nicegui.io/)! | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue