{"id":28171651,"url":"https://github.com/danerxc/dane.gg","last_synced_at":"2025-05-15T19:15:48.784Z","repository":{"id":292338311,"uuid":"880417130","full_name":"danerxc/dane.gg","owner":"danerxc","description":"🌐 My personal portfolio website w/ admin CMS dashboard","archived":false,"fork":false,"pushed_at":"2025-05-09T11:04:42.000Z","size":8024,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-09T12:23:10.024Z","etag":null,"topics":["cms","express","personal-website","portfolio","react","vite"],"latest_commit_sha":null,"homepage":"https://dane.gg","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danerxc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-10-29T17:27:42.000Z","updated_at":"2025-05-09T11:04:46.000Z","dependencies_parsed_at":"2025-05-09T12:23:23.214Z","dependency_job_id":"bdb33e6d-f51f-4b78-801f-c9b9c96a8b44","html_url":"https://github.com/danerxc/dane.gg","commit_stats":null,"previous_names":["danerxc/dane.gg"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danerxc%2Fdane.gg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danerxc%2Fdane.gg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danerxc%2Fdane.gg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danerxc%2Fdane.gg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danerxc","download_url":"https://codeload.github.com/danerxc/dane.gg/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254404325,"owners_count":22065641,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cms","express","personal-website","portfolio","react","vite"],"created_at":"2025-05-15T19:15:43.982Z","updated_at":"2025-05-15T19:15:48.753Z","avatar_url":"https://github.com/danerxc.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://i.imgur.com/pRf4zZU.png\" alt=\"dane.gg\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eMy personal portfolio/blog site + admin management (CMS) dashboard\u003c/b\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://dane.gg\"\u003e\u003cimg src=\"https://img.shields.io/website-up-down-green-red/http/dane.gg.svg\" alt=\"\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/danerxc/dane.gg/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/danexrc/dane.gg.svg\" alt=\"License\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003chr\u003e\n\n## 📌 Overview\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3\u003e\u003cb\u003ePublic Website\u003c/b\u003e\u003c/h3\u003e\u003c/summary\u003e\n\u003cimg src=\"https://i.imgur.com/8k0C3bT.png\" alt=\"Homepage\"/\u003e\n  \n### Notable features\n- Automatic online/offline status (status from Discord)\n- Automatic latest tweet status update (via Tweetshift)\n- Automatic service status section for monitored services from Uptime Kuma (via webhook call)\n- Real-time websocket chat (two way sync with Discord)\n- Dynamic blog (managed via admin dashboard)\n- Dynamic projects list (managed via admin dashboard\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3\u003e\u003cb\u003eAdmin Dashboard\u003c/b\u003e\u003c/h3\u003e\u003c/summary\u003e\n\u003ch3\u003eLogin\u003c/h3\u003e\n\u003cimg src=\"https://i.imgur.com/hnm2ye1.png\" alt=\"Login Page\"/\u003e\n  \n- Secure login page\n- 2FA prompt (if setup, optional)\n\n\u003ch3\u003eStatistics Page\u003c/h3\u003e\n\u003cimg src=\"https://i.imgur.com/wHsRfZ2.png\" alt=\"Statistics Page\"/\u003e\n\u003cimg src=\"https://i.imgur.com/NoqtzHG.png\" alt=\"Statistics Page\"/\u003e\n\n- Displays statistics of web traffic (public pages only)\n- Configurable timeframe (24h, 7d, 30d, all time)\n- Displays total site visits, number of individual visitors,\n- Chart displaying total visits + individual visitor changes over time\n- Chart displaying individual page popularity and total page visits per page\n- Table of top ten most-viewed blog posts w/ number of views per post\n- Visitor countries donut chart + list of top ten countries\n- List of top ten most popular visitor user agents\n- Raw request logs (public pages only)\n\n\u003ch3\u003eBlog Page\u003c/h3\u003e\n\u003cimg src=\"https://i.imgur.com/v0IzJzV.png\" alt=\"Blog Page\"/\u003e\n\u003cimg src=\"https://i.imgur.com/PLNqi3a.png\" alt=\"Blog Page - Add/Edit\"/\u003e\n\n- List of all blog posts\n- Option to create new blog post\n- Edit/delete existing post functionality\n- Rich-text content editor w/ preview (markdown formatting)\n- Image upload functionality (thumbnail + blog post content)\n- Publish/unpublish option (changes whether post is shown on public website or not)\n- Blog post tagging functionality (displays on public website)\n\n\u003ch3\u003eProjects Page\u003c/h3\u003e\n\u003cimg src=\"https://i.imgur.com/0MT5E9e.png\" alt=\"Projects Page\"/\u003e\n\u003cimg src=\"https://i.imgur.com/l1EERt0.png\" alt=\"Projects Page - Add/Edit\"/\u003e\n\n- List of all projects\n- Seperate project list per category\n- Drag'n'drop ordering of projects (order that projects are returned on public site)\n- Option to create new project\n- Edit/delete existing project functionality\n- Project category selection dropdown + management modal to add/edit/delete categories\n- Rich-text description editor w/ preview (markdown formatting)\n- Image upload functionality (thumbnail)\n- Featured option (if disabled, project is only shown when clicking \"view all\" on public site)\n- Customizable button URL + text\n- Project tagging functionality + management modal to add/edit/delete tags\n\n\u003ch3\u003eUser Management Page\u003c/h3\u003e\n\u003cimg src=\"https://i.imgur.com/kSyU8dC.png\" alt=\"User Management Page\"/\u003e\n\u003cimg src=\"https://i.imgur.com/SkeIpBb.png\" alt=\"User Management Page - Add\"/\u003e\n\u003cimg src=\"https://i.imgur.com/qTd7AAb.png\" alt=\"User Management Page - Edit\"/\u003e\n\n- List of all available user accounts\n- Ability to add new accounts\n- Ability to edit/delete existing user accounts\n- Ability to reset existing user passwords + reset 2FA if setup\n- Only accessible by user accounts marked as admin (standard accounts cannot reach this page)\n\n\u003ch3\u003eAccount Page\u003c/h3\u003e\n\u003cimg src=\"https://i.imgur.com/QHuPH0D.png\" alt=\"Account Management Page\"/\u003e\n\n- Management page for logged-in user\n- Displays whether account is an administrator account or standard account\n- Option to change username w/ availability checking\n- Option to change password w/ existing password checking\n- Option to setup \u0026 enable app-based 2FA authentication on account\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ch3\u003e\u003cb\u003eDiscord Integrations\u003c/b\u003e\u003c/h3\u003e\u003c/summary\u003e\nI use a custom Discord bot for both the logic behind retrieving and displaying my latest tweet from Twitter \u0026 to enable the websockets chat to post/send from a channel in my Discord channel.\n\u003cbr\u003e\n\u003cbr\u003e\nYou can read the \u003ca href=\"https://github.com/danerxc/dane.gg/wiki\"\u003erepo wiki\u003c/a\u003e for information on these integrations \u0026 how to set them up.\n\u003c/details\u003e\n\n\u003chr\u003e\n\n## 📂 Project Structure\n\n- The files for the public website are located within the **``/public``** folder\n- The admin panel react project is located within the **``/admin``** folder\n\n*The full project structure is shown below:*\n```\n.\n├── admin/             # React admin panel\n├── config/            # Configuration for uptime status monitoring\n├── controllers/       # API/webhook controllers\n├── data/              # JSON files to store API data (latest tweet, online/offline status, services status)\n├── middleware/        # Express auth/stats tracking middleware\n├── public/            # Public website files\n├── routes/            # Express routes\n├── services/          # Express API service logic\n└── server.js          # Express app entry point\n```\n\u003chr\u003e\n\n## 📦 Build\n\n### Prerequisites\n\n- Node.js 20+\n- PostgreSQL database\n- Docker (Recommended)\n\n### Environment Variables\n\nCreate a ``.env`` file in the root directory:\n\n```env\nDATABASE_URL=postgresql://user:password@localhost:5432/dbname //PostgreSQL datatbase connection string\nLASTFM_USERNAME=your_lastfm_username //Last.fm username\nLASTFM_API_KEY=your_lastfm_api_key //API key from last.fm development account\nWEBHOOK_AUTH_TOKEN=your_webhook_token //Random token to use for authorization when posting to the webhook endpoints\nDEFAULT_WEATHER=snow/rain //\nJWT_SECRET=your_jwt_secret\n```\n\n## Docker (Recommended)\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eDevelopment\u003c/b\u003e\u003c/summary\u003e\n\n1. Build the development image\n```sh\ndocker compose build\n```\n\n2. Run the image in Docker\nThis will automatically create a PostgreSQL Docker image with the required schema\n```sh\ndocker compose up\n```\n\n3. Create the initial admin user in the users database:\n```sh\ndocker compose exec web node createInitialUser.js \u003cusername\u003e \u003cpassword\u003e\n```\n\nThis will start:\n- Backend server on port 3000\n- Admin dev server on port 3001\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cb\u003eProduction\u003c/b\u003e\u003c/summary\u003e\n\n  1. Build the production image\n```sh\ndocker compose -f docker-compose.prod.yml build\n```\n\n2. Run the production Docker image\n```sh\ndocker compose -f docker-compose.prod.yml up -d\n```\n\n3. Create the initial admin user:\n```sh\ndocker compose -f docker-compose.prod.yml exec web node createInitialUser.js \u003cusername\u003e \u003cpassword\u003e\n```\n\u003c/details\u003e\n\n## Node.js\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cb\u003eDevelopment\u003c/b\u003e\u003c/summary\u003e\n\n  1. Install dependencies:\n```sh\nnpm install\ncd admin \u0026\u0026 npm install\n```\n\n2. Create initial admin user:\n```sh\nnode createInitialUser.js \u003cusername\u003e \u003cpassword\u003e\n```\n\n3. Start development servers:\n```\nnpm run dev\n```\n\nThis will start:\n- Backend server on port 3000\n- Admin dev server on port 3001\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cb\u003eProduction\u003c/b\u003e\u003c/summary\u003e\n\n  1. Install dependencies and build admin panel:\n```\nnpm install\ncd admin \u0026\u0026 npm install \u0026\u0026 npm run build\ncd ..\n```\n\n2. Create initial admin user:\n```\nnode createInitialUser.js \u003cusername\u003e \u003cpassword\u003e\n```\n\n3. Start production server:\n```\nnpm start\n```\n\n\u003c/details\u003e\n\n\u003chr\u003e\n\n## Technologies\n\n- Backend: \u003cimg alt=\"Node JS\" src=\"https://img.shields.io/badge/Node%20JS-87cf30?style=flat\u0026logo=nodedotjs\u0026logoColor=87cf30\u0026labelColor=595959\u0026color=87cf30\" height=\"18\"\u003e \u003cimg alt=\"Express JS\" src=\"https://img.shields.io/badge/Express_JS-000000?style=flat\u0026logo=express\u0026logoColor=000000\u0026labelColor=595959\u0026color=000000\" height=\"18\"\u003e\n- Frontend: \u003cimg alt=\"HTML\" src=\"https://img.shields.io/badge/HTML-dd4b25?style=flat\u0026logo=html5\u0026logoColor=dd4b25\u0026labelColor=595959\u0026color=dd4b25\" height=\"18\"\u003e \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/CSS-2d53e5?style=flat\u0026logo=css3\u0026logoColor=2d53e5\u0026labelColor=595959\u0026color=2d53e5\" height=\"18\"\u003e \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/JavaScript-f7e025?style=flat\u0026logo=javascript\u0026logoColor=f7e025\u0026labelColor=595959\u0026color=f7e025\" height=\"18\"\u003e \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/Handlebars-ff26523?style=flat\u0026logo=handlebarsdotjs\u0026logoColor=f26523\u0026labelColor=595959\u0026color=f26523\" height=\"18\"\u003e\n- Admin Panel: \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/React-61dbfb?style=flat\u0026logo=react\u0026logoColor=61dbfb\u0026labelColor=595959\u0026color=61dbfb\" height=\"18\"\u003e \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/TypeScript-2d79c7?style=flat\u0026logo=typescript\u0026logoColor=2d79c7\u0026labelColor=595959\u0026color=2d79c7\" height=\"18\"\u003e \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/Tailwind%20CSS-35bef8?style=flat\u0026logo=tailwindcss\u0026logoColor=35bef8\u0026labelColor=595959\u0026color=35bef8\" height=\"18\"\u003e\n- Database: \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/PostgreSQL-2f6792?style=flat\u0026logo=postgresql\u0026logoColor=2f6792\u0026labelColor=595959\u0026color=2f6792\" height=\"18\"\u003e\n- Real-time: \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/WebSocket-ff6600?style=flat\u0026logo=socket\u0026logoColor=ff6600\u0026labelColor=595959\u0026color=ff6600\" height=\"18\"\u003e\n- Authentication: \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/JWT-fb015c?style=flat\u0026logo=jsonwebtokens\u0026logoColor=fb015c\u0026labelColor=595959\u0026color=fb015c\" height=\"18\"\u003e \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/TOTP-00ac4f?style=flat\u0026logo=googleauthenticator\u0026logoColor=00ac4f\u0026labelColor=595959\u0026color=00ac4f\" height=\"18\"\u003e\n- Container: \u003cimg alt=\"Static Badge\" src=\"https://img.shields.io/badge/Docker-2496ed?style=flat\u0026logo=docker\u0026logoColor=2496ed\u0026labelColor=595959\u0026color=2496ed\" height=\"18\"\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanerxc%2Fdane.gg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanerxc%2Fdane.gg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanerxc%2Fdane.gg/lists"}