diff --git a/.envrc b/.envrc
new file mode 100644
index 0000000..8392d15
--- /dev/null
+++ b/.envrc
@@ -0,0 +1 @@
+use flake
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 4b9d835..8388ebf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,5 @@ backend/bin/
.vscode
*.pem
.env
+.direnv
+.envrc.local
diff --git a/Makefile b/Makefile
index 530d298..cf411df 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ help:
## backend: Build and run the backend from source
backend:
- @cd backend && go run .
+ @cd backend && CGO_ENABLED=0 go run .
.PHONY: backend
## frontend: Build and run the frontend from source
diff --git a/backend/go.mod b/backend/go.mod
index 4e0f414..c34b7a0 100644
--- a/backend/go.mod
+++ b/backend/go.mod
@@ -1,6 +1,6 @@
module github.com/davegallant/rfd-fyi
-go 1.18
+go 1.26
require (
github.com/dlclark/regexp2 v1.11.5
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000..43f833f
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,61 @@
+{
+ "nodes": {
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1731533236,
+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1771008912,
+ "narHash": "sha256-gf2AmWVTs8lEq7z/3ZAsgnZDhWIckkb+ZnAo5RzSxJg=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "a82ccc39b39b621151d6732718e3e250109076fa",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "flake-utils": "flake-utils",
+ "nixpkgs": "nixpkgs"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000..28de54f
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,51 @@
+{
+ description = "rfd-fyi development environment";
+
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+ flake-utils.url = "github:numtide/flake-utils";
+ };
+
+ outputs = { self, nixpkgs, flake-utils }:
+ flake-utils.lib.eachDefaultSystem (system:
+ let
+ pkgs = nixpkgs.legacyPackages.${system};
+ in
+ {
+ devShells.default = pkgs.mkShell {
+ buildInputs = with pkgs; [
+ # Node.js LTS with npm
+ nodejs_20
+
+ # Go for backend
+ go
+
+ # Build tools
+ pkg-config
+
+ # Development utilities
+ git
+ curl
+ jq
+
+ # Optional: for better development experience
+ gnumake
+ ];
+
+ shellHook = ''
+ echo "🚀 rfd-fyi development environment loaded"
+ echo "Available commands:"
+ echo " Frontend: npm install, npm run build, npm run serve"
+ echo " Backend: cd backend && CGO_ENABLED=0 go run ."
+ echo ""
+ echo "Node version: $(node --version)"
+ echo "npm version: $(npm --version)"
+ echo "Go version: $(go version)"
+ echo ""
+ echo "Tip: Run 'npm install' to install frontend dependencies"
+ echo "Tip: Vite is available via 'npx vite' or 'npm run build'"
+ '';
+ };
+ }
+ );
+}
diff --git a/index.html b/index.html
index 289a1a1..ade4a06 100644
--- a/index.html
+++ b/index.html
@@ -1,17 +1,39 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
rfd-fyi - An overlay of hot deals
+
+
-
diff --git a/package-lock.json b/package-lock.json
index 44b3541..ad11596 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,10 +15,8 @@
"axios": "^1.12.0",
"core-js": "^3.32.1",
"cssnano": "^7.0.0",
- "jquery": "^4.0.0",
- "moment": "^2.29.4",
+ "dayjs": "^1.11.10",
"vue": "^3.5.17",
- "vue-github-button": "^3.0.3",
"vue-loading-overlay": "^6.0.3",
"vue-router": "^5.0.0",
"vuetify": "^3.9.6"
@@ -34,7 +32,6 @@
"eslint-plugin-vue": "^9.17.0",
"postcss-cli": "^11.0.0",
"sass-embedded": "^1.89.2",
- "unplugin-fonts": "^1.3.1",
"unplugin-vue-components": "^31.0.0",
"vite": "^6.3.6",
"vite-plugin-vuetify": "^2.1.1"
@@ -7252,6 +7249,12 @@
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
"license": "MIT"
},
+ "node_modules/dayjs": {
+ "version": "1.11.19",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
+ "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
+ "license": "MIT"
+ },
"node_modules/debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
@@ -8983,12 +8986,6 @@
"node": ">=6"
}
},
- "node_modules/github-buttons": {
- "version": "2.29.1",
- "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.29.1.tgz",
- "integrity": "sha512-TV3YgAKda5hPz75n7QXmGCsSzgVya1vvmBieebg3EB5ScmashTZ0FldViG1aU2d4V5rcAGrtQ7k5uAaCo0A4PA==",
- "license": "BSD-2-Clause"
- },
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -9870,12 +9867,6 @@
"@sideway/pinpoint": "^2.0.0"
}
},
- "node_modules/jquery": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jquery/-/jquery-4.0.0.tgz",
- "integrity": "sha512-TXCHVR3Lb6TZdtw1l3RTLf8RBWVGexdxL6AC8/e0xZKEpBflBsjh9/8LXw+dkNFuOyW9B7iB3O1sP7hS0Kiacg==",
- "license": "MIT"
- },
"node_modules/js-message": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
@@ -10737,15 +10728,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/moment": {
- "version": "2.30.1",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
- "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
"node_modules/mrmime": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz",
@@ -14809,41 +14791,6 @@
"node": ">= 0.8"
}
},
- "node_modules/unplugin": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.5.tgz",
- "integrity": "sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.14.1",
- "picomatch": "^4.0.2",
- "webpack-virtual-modules": "^0.6.2"
- },
- "engines": {
- "node": ">=18.12.0"
- }
- },
- "node_modules/unplugin-fonts": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/unplugin-fonts/-/unplugin-fonts-1.4.0.tgz",
- "integrity": "sha512-TIJqr5rSlK/+3oL5nnrrEJ+Ty2taQ/bTJY1C5abYnksl553Q3HoHVqS4pnRLDkwpZq8AYqywib3kEVvHH+CtRQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-glob": "^3.3.3",
- "unplugin": "2.3.5"
- },
- "peerDependencies": {
- "@nuxt/kit": "^3.0.0 || ^4.0.0",
- "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
- },
- "peerDependenciesMeta": {
- "@nuxt/kit": {
- "optional": true
- }
- }
- },
"node_modules/unplugin-utils": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.1.tgz",
@@ -14971,26 +14918,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/unplugin/node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/unplugin/node_modules/webpack-virtual-modules": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
- "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/upath": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz",
@@ -15328,15 +15255,6 @@
"node": ">=10"
}
},
- "node_modules/vue-github-button": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/vue-github-button/-/vue-github-button-3.1.3.tgz",
- "integrity": "sha512-ZdOnUuYJL/wUsxISsC96TARzCdf1twaWooZoI14+g4RHsJltPY+Agw6Ox6pjuMqMX0uhSK1JOMFUFNCQGlcZGA==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "github-buttons": "^2.22.0"
- }
- },
"node_modules/vue-hot-reload-api": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
diff --git a/package.json b/package.json
index d29dce5..3ec789f 100644
--- a/package.json
+++ b/package.json
@@ -16,10 +16,8 @@
"axios": "^1.12.0",
"core-js": "^3.32.1",
"cssnano": "^7.0.0",
- "jquery": "^4.0.0",
- "moment": "^2.29.4",
+ "dayjs": "^1.11.10",
"vue": "^3.5.17",
- "vue-github-button": "^3.0.3",
"vue-loading-overlay": "^6.0.3",
"vue-router": "^5.0.0",
"vuetify": "^3.9.6"
@@ -35,7 +33,6 @@
"eslint-plugin-vue": "^9.17.0",
"postcss-cli": "^11.0.0",
"sass-embedded": "^1.89.2",
- "unplugin-fonts": "^1.3.1",
"unplugin-vue-components": "^31.0.0",
"vite": "^6.3.6",
"vite-plugin-vuetify": "^2.1.1"
diff --git a/src/App.vue b/src/App.vue
index 3c2d757..f53d481 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,6 +1,6 @@