From d302c19265838f55549599d5b2fc80c8035108bf Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 30 Sep 2025 16:38:27 -0700 Subject: [PATCH] A bunch of vocab, and (working in dev) page for adding vocab --- .../ds5hg5lwbpkp0pmwvq1r1khdj9dhgr68-source | 1 - .../piq8ffvrjw88nxj69ib64pfqg7vj19mp-source | 1 - ...e-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa | 2 +- ...5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc | 12 +- .gitignore | 4 + flake.nix | 34 +- hindki/.env.example | 14 + hindki/src/components/AddVocabForm.tsx | 500 ++++++++++++++++++ hindki/src/components/VocabWord.astro | 18 +- hindki/src/lib/storage.ts | 156 ++++++ hindki/src/pages/api/vocab.json.ts | 108 ++++ hindki/src/pages/edit/add-vocab.astro | 18 +- hindki/src/pages/vocabulary/[category].astro | 8 +- hindki/src/styles/custom.css | 1 + hindki/src/vocab_list.yaml | 326 +++++++++++- 15 files changed, 1151 insertions(+), 52 deletions(-) delete mode 120000 .direnv/flake-inputs/ds5hg5lwbpkp0pmwvq1r1khdj9dhgr68-source delete mode 120000 .direnv/flake-inputs/piq8ffvrjw88nxj69ib64pfqg7vj19mp-source create mode 100644 hindki/.env.example create mode 100644 hindki/src/components/AddVocabForm.tsx create mode 100644 hindki/src/lib/storage.ts create mode 100644 hindki/src/pages/api/vocab.json.ts mode change 120000 => 100644 hindki/src/vocab_list.yaml diff --git a/.direnv/flake-inputs/ds5hg5lwbpkp0pmwvq1r1khdj9dhgr68-source b/.direnv/flake-inputs/ds5hg5lwbpkp0pmwvq1r1khdj9dhgr68-source deleted file mode 120000 index 9ac5358..0000000 --- a/.direnv/flake-inputs/ds5hg5lwbpkp0pmwvq1r1khdj9dhgr68-source +++ /dev/null @@ -1 +0,0 @@ -/nix/store/ds5hg5lwbpkp0pmwvq1r1khdj9dhgr68-source \ No newline at end of file diff --git a/.direnv/flake-inputs/piq8ffvrjw88nxj69ib64pfqg7vj19mp-source b/.direnv/flake-inputs/piq8ffvrjw88nxj69ib64pfqg7vj19mp-source deleted file mode 120000 index c4889c8..0000000 --- a/.direnv/flake-inputs/piq8ffvrjw88nxj69ib64pfqg7vj19mp-source +++ /dev/null @@ -1 +0,0 @@ -/nix/store/piq8ffvrjw88nxj69ib64pfqg7vj19mp-source \ No newline at end of file diff --git a/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa index 28d23de..8b1a608 120000 --- a/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa +++ b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa @@ -1 +1 @@ -/nix/store/z7x7krys4bv786dsqsb015ancd5glyab-nix-shell-env \ No newline at end of file +/nix/store/2l63479bllklr4bzi4vscn7ndj6lg614-nix-shell-env \ No newline at end of file diff --git a/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc index 36bdd2f..0eb7027 100644 --- a/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc +++ b/.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc @@ -15,7 +15,7 @@ export CONFIG_SHELL CXX='g++' export CXX HOSTTYPE='x86_64' -HOST_PATH='/nix/store/ddx7976jyll30xjbasghv9jailswprcp-bash-interactive-5.3p3/bin:/nix/store/q1zaii9cirbfpmwr7d86hpppql3kjcpf-git-2.51.0/bin:/nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev/bin:/nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0/bin:/nix/store/967gn7p1p47ic924r2fx4rgbfp49fhsy-pnpm-10.15.1/bin:/nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev/bin:/nix/store/jq2kbdw6ljv9i47jz23pm072cfyxwpfj-postgresql-17.6/bin:/nix/store/n4lyyqirbz2j0igs12m2pyqrs7zyyvld-netlify-cli-19.0.2/bin:/nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0/bin:/nix/store/8ksax0a2mxglr5hlkj2dzl556jx7xqn5-coreutils-9.7/bin:/nix/store/l964krgbp613d5jxga2vy5qdssj7zfzj-findutils-4.10.0/bin:/nix/store/s2fvny566vls74p4qm9v3fdqd741fh3f-diffutils-3.12/bin:/nix/store/pmhkmqy0vxk47r6ndh0azybhf6gs6k25-gnused-4.9/bin:/nix/store/vlckk0vnmawq9wwh7ndkrwxlpv4h29yh-gnugrep-3.12/bin:/nix/store/03nvbw411p097h6yxjghc33rbcrjfb9d-gawk-5.3.2/bin:/nix/store/8av8pfs7bnyc6hqj764ns4z1fnr9bva1-gnutar-1.35/bin:/nix/store/8gsxxh82rf957ffbsk0q9670nhvl5lia-gzip-1.14/bin:/nix/store/6yjb3zdj448rm8qsmpiq3f67kvj5683a-bzip2-1.0.8-bin/bin:/nix/store/aqdvlkh0jdwkc22hh5vr9sl6qlw5ha74-gnumake-4.4.1/bin:/nix/store/q7sqwn7i6w2b67adw0bmix29pxg85x3w-bash-5.3p3/bin:/nix/store/856i1ajaci3kmmp15rifacfz3jvn5l3q-patch-2.8/bin:/nix/store/y9kgzp85ykrhd7l691w4djx121qygy68-xz-5.8.1-bin/bin:/nix/store/v40ijzz8p2fpk9ihjck3a1ncqaqfmn3c-file-5.45/bin' +HOST_PATH='/nix/store/ddx7976jyll30xjbasghv9jailswprcp-bash-interactive-5.3p3/bin:/nix/store/q1zaii9cirbfpmwr7d86hpppql3kjcpf-git-2.51.0/bin:/nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev/bin:/nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0/bin:/nix/store/967gn7p1p47ic924r2fx4rgbfp49fhsy-pnpm-10.15.1/bin:/nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev/bin:/nix/store/jq2kbdw6ljv9i47jz23pm072cfyxwpfj-postgresql-17.6/bin:/nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0/bin:/nix/store/1p5n2mzy33ayzc1scdnz82h53d192knh-claude-code-1.0.117/bin:/nix/store/8ksax0a2mxglr5hlkj2dzl556jx7xqn5-coreutils-9.7/bin:/nix/store/l964krgbp613d5jxga2vy5qdssj7zfzj-findutils-4.10.0/bin:/nix/store/s2fvny566vls74p4qm9v3fdqd741fh3f-diffutils-3.12/bin:/nix/store/pmhkmqy0vxk47r6ndh0azybhf6gs6k25-gnused-4.9/bin:/nix/store/vlckk0vnmawq9wwh7ndkrwxlpv4h29yh-gnugrep-3.12/bin:/nix/store/03nvbw411p097h6yxjghc33rbcrjfb9d-gawk-5.3.2/bin:/nix/store/8av8pfs7bnyc6hqj764ns4z1fnr9bva1-gnutar-1.35/bin:/nix/store/8gsxxh82rf957ffbsk0q9670nhvl5lia-gzip-1.14/bin:/nix/store/6yjb3zdj448rm8qsmpiq3f67kvj5683a-bzip2-1.0.8-bin/bin:/nix/store/aqdvlkh0jdwkc22hh5vr9sl6qlw5ha74-gnumake-4.4.1/bin:/nix/store/q7sqwn7i6w2b67adw0bmix29pxg85x3w-bash-5.3p3/bin:/nix/store/856i1ajaci3kmmp15rifacfz3jvn5l3q-patch-2.8/bin:/nix/store/y9kgzp85ykrhd7l691w4djx121qygy68-xz-5.8.1-bin/bin:/nix/store/v40ijzz8p2fpk9ihjck3a1ncqaqfmn3c-file-5.45/bin' export HOST_PATH IFS=' ' @@ -37,7 +37,7 @@ NIX_CC='/nix/store/95k9rsn1zsw1yvir8mj824ldhf90i4qw-gcc-wrapper-14.3.0' export NIX_CC NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu='1' export NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu -NIX_CFLAGS_COMPILE=' -frandom-seed=z7x7krys4b -isystem /nix/store/7zwa3r9agcyzf21d0792fvhrsl6gajiy-bash-interactive-5.3p3-dev/include -isystem /nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev/include -isystem /nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0/include -isystem /nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev/include -isystem /nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0/include -isystem /nix/store/7zwa3r9agcyzf21d0792fvhrsl6gajiy-bash-interactive-5.3p3-dev/include -isystem /nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev/include -isystem /nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0/include -isystem /nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev/include -isystem /nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0/include' +NIX_CFLAGS_COMPILE=' -frandom-seed=2l63479bll -isystem /nix/store/7zwa3r9agcyzf21d0792fvhrsl6gajiy-bash-interactive-5.3p3-dev/include -isystem /nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev/include -isystem /nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0/include -isystem /nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev/include -isystem /nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0/include -isystem /nix/store/7zwa3r9agcyzf21d0792fvhrsl6gajiy-bash-interactive-5.3p3-dev/include -isystem /nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev/include -isystem /nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0/include -isystem /nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev/include -isystem /nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0/include' export NIX_CFLAGS_COMPILE NIX_ENFORCE_NO_NATIVE='1' export NIX_ENFORCE_NO_NATIVE @@ -50,7 +50,7 @@ NIX_STORE='/nix/store' export NIX_STORE NM='nm' export NM -NODE_PATH='/nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0/lib/node_modules:/nix/store/n4lyyqirbz2j0igs12m2pyqrs7zyyvld-netlify-cli-19.0.2/lib/node_modules' +NODE_PATH='/nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0/lib/node_modules:/nix/store/1p5n2mzy33ayzc1scdnz82h53d192knh-claude-code-1.0.117/lib/node_modules' export NODE_PATH OBJCOPY='objcopy' export OBJCOPY @@ -60,7 +60,7 @@ OLDPWD='' export OLDPWD OPTERR='1' OSTYPE='linux-gnu' -PATH='/nix/store/gx2l0rnp3qcnysdddkg9dqnh2mz6w08k-patchelf-0.15.2/bin:/nix/store/95k9rsn1zsw1yvir8mj824ldhf90i4qw-gcc-wrapper-14.3.0/bin:/nix/store/82kmz7r96navanrc2fgckh2bamiqrgsw-gcc-14.3.0/bin:/nix/store/4jxivbjpr86wmsziqlf7iljlwjlxz8bh-glibc-2.40-66-bin/bin:/nix/store/8ksax0a2mxglr5hlkj2dzl556jx7xqn5-coreutils-9.7/bin:/nix/store/l19cddv64i52rhcwahif8sgyrd3mhiqb-binutils-wrapper-2.44/bin:/nix/store/c43ry7z24x3jhnjlj4gpay8a4g2p3x1h-binutils-2.44/bin:/nix/store/ddx7976jyll30xjbasghv9jailswprcp-bash-interactive-5.3p3/bin:/nix/store/q1zaii9cirbfpmwr7d86hpppql3kjcpf-git-2.51.0/bin:/nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev/bin:/nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0/bin:/nix/store/967gn7p1p47ic924r2fx4rgbfp49fhsy-pnpm-10.15.1/bin:/nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev/bin:/nix/store/jq2kbdw6ljv9i47jz23pm072cfyxwpfj-postgresql-17.6/bin:/nix/store/n4lyyqirbz2j0igs12m2pyqrs7zyyvld-netlify-cli-19.0.2/bin:/nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0/bin:/nix/store/8ksax0a2mxglr5hlkj2dzl556jx7xqn5-coreutils-9.7/bin:/nix/store/l964krgbp613d5jxga2vy5qdssj7zfzj-findutils-4.10.0/bin:/nix/store/s2fvny566vls74p4qm9v3fdqd741fh3f-diffutils-3.12/bin:/nix/store/pmhkmqy0vxk47r6ndh0azybhf6gs6k25-gnused-4.9/bin:/nix/store/vlckk0vnmawq9wwh7ndkrwxlpv4h29yh-gnugrep-3.12/bin:/nix/store/03nvbw411p097h6yxjghc33rbcrjfb9d-gawk-5.3.2/bin:/nix/store/8av8pfs7bnyc6hqj764ns4z1fnr9bva1-gnutar-1.35/bin:/nix/store/8gsxxh82rf957ffbsk0q9670nhvl5lia-gzip-1.14/bin:/nix/store/6yjb3zdj448rm8qsmpiq3f67kvj5683a-bzip2-1.0.8-bin/bin:/nix/store/aqdvlkh0jdwkc22hh5vr9sl6qlw5ha74-gnumake-4.4.1/bin:/nix/store/q7sqwn7i6w2b67adw0bmix29pxg85x3w-bash-5.3p3/bin:/nix/store/856i1ajaci3kmmp15rifacfz3jvn5l3q-patch-2.8/bin:/nix/store/y9kgzp85ykrhd7l691w4djx121qygy68-xz-5.8.1-bin/bin:/nix/store/v40ijzz8p2fpk9ihjck3a1ncqaqfmn3c-file-5.45/bin' +PATH='/nix/store/gx2l0rnp3qcnysdddkg9dqnh2mz6w08k-patchelf-0.15.2/bin:/nix/store/95k9rsn1zsw1yvir8mj824ldhf90i4qw-gcc-wrapper-14.3.0/bin:/nix/store/82kmz7r96navanrc2fgckh2bamiqrgsw-gcc-14.3.0/bin:/nix/store/4jxivbjpr86wmsziqlf7iljlwjlxz8bh-glibc-2.40-66-bin/bin:/nix/store/8ksax0a2mxglr5hlkj2dzl556jx7xqn5-coreutils-9.7/bin:/nix/store/l19cddv64i52rhcwahif8sgyrd3mhiqb-binutils-wrapper-2.44/bin:/nix/store/c43ry7z24x3jhnjlj4gpay8a4g2p3x1h-binutils-2.44/bin:/nix/store/ddx7976jyll30xjbasghv9jailswprcp-bash-interactive-5.3p3/bin:/nix/store/q1zaii9cirbfpmwr7d86hpppql3kjcpf-git-2.51.0/bin:/nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev/bin:/nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0/bin:/nix/store/967gn7p1p47ic924r2fx4rgbfp49fhsy-pnpm-10.15.1/bin:/nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev/bin:/nix/store/jq2kbdw6ljv9i47jz23pm072cfyxwpfj-postgresql-17.6/bin:/nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0/bin:/nix/store/1p5n2mzy33ayzc1scdnz82h53d192knh-claude-code-1.0.117/bin:/nix/store/8ksax0a2mxglr5hlkj2dzl556jx7xqn5-coreutils-9.7/bin:/nix/store/l964krgbp613d5jxga2vy5qdssj7zfzj-findutils-4.10.0/bin:/nix/store/s2fvny566vls74p4qm9v3fdqd741fh3f-diffutils-3.12/bin:/nix/store/pmhkmqy0vxk47r6ndh0azybhf6gs6k25-gnused-4.9/bin:/nix/store/vlckk0vnmawq9wwh7ndkrwxlpv4h29yh-gnugrep-3.12/bin:/nix/store/03nvbw411p097h6yxjghc33rbcrjfb9d-gawk-5.3.2/bin:/nix/store/8av8pfs7bnyc6hqj764ns4z1fnr9bva1-gnutar-1.35/bin:/nix/store/8gsxxh82rf957ffbsk0q9670nhvl5lia-gzip-1.14/bin:/nix/store/6yjb3zdj448rm8qsmpiq3f67kvj5683a-bzip2-1.0.8-bin/bin:/nix/store/aqdvlkh0jdwkc22hh5vr9sl6qlw5ha74-gnumake-4.4.1/bin:/nix/store/q7sqwn7i6w2b67adw0bmix29pxg85x3w-bash-5.3p3/bin:/nix/store/856i1ajaci3kmmp15rifacfz3jvn5l3q-patch-2.8/bin:/nix/store/y9kgzp85ykrhd7l691w4djx121qygy68-xz-5.8.1-bin/bin:/nix/store/v40ijzz8p2fpk9ihjck3a1ncqaqfmn3c-file-5.45/bin' export PATH PS4='+ ' RANLIB='ranlib' @@ -82,7 +82,7 @@ export XDG_DATA_DIRS __structuredAttrs='' export __structuredAttrs _substituteStream_has_warned_replace_deprecation='false' -buildInputs='/nix/store/7zwa3r9agcyzf21d0792fvhrsl6gajiy-bash-interactive-5.3p3-dev /nix/store/008h0z2m22alg2v8kcdcw4v0f7c39lmm-glibc-locales-2.40-66 /nix/store/q1zaii9cirbfpmwr7d86hpppql3kjcpf-git-2.51.0 /nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev /nix/store/967gn7p1p47ic924r2fx4rgbfp49fhsy-pnpm-10.15.1 /nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev /nix/store/n4lyyqirbz2j0igs12m2pyqrs7zyyvld-netlify-cli-19.0.2 /nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0' +buildInputs='/nix/store/7zwa3r9agcyzf21d0792fvhrsl6gajiy-bash-interactive-5.3p3-dev /nix/store/008h0z2m22alg2v8kcdcw4v0f7c39lmm-glibc-locales-2.40-66 /nix/store/q1zaii9cirbfpmwr7d86hpppql3kjcpf-git-2.51.0 /nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev /nix/store/967gn7p1p47ic924r2fx4rgbfp49fhsy-pnpm-10.15.1 /nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev /nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0 /nix/store/1p5n2mzy33ayzc1scdnz82h53d192knh-claude-code-1.0.117' export buildInputs buildPhase='{ echo "------------------------------------------------------------"; echo " WARNING: the existence of this path is not guaranteed."; @@ -161,7 +161,7 @@ declare -a pkgsBuildBuild=() declare -a pkgsBuildHost=('/nix/store/gx2l0rnp3qcnysdddkg9dqnh2mz6w08k-patchelf-0.15.2' '/nix/store/jwjq0fjgn7d00kswhaw2m8hbgws5vbi4-update-autotools-gnu-config-scripts-hook' '/nix/store/0y5xmdb7qfvimjwbq7ibg1xdgkgjwqng-no-broken-symlinks.sh' '/nix/store/cv1d7p48379km6a85h4zp6kr86brh32q-audit-tmpdir.sh' '/nix/store/85clx3b0xkdf58jn161iy80y5223ilbi-compress-man-pages.sh' '/nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh' '/nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh' '/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh' '/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh' '/nix/store/pag6l61paj1dc9sv15l7bm5c17xn5kyk-move-systemd-user-units.sh' '/nix/store/cmzya9irvxzlkh7lfy6i82gbp0saxqj3-multiple-outputs.sh' '/nix/store/x8c40nfigps493a07sdr2pm5s9j1cdc0-patch-shebangs.sh' '/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh' '/nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh' '/nix/store/z7k98578dfzi6l3hsvbivzm7hfqlk0zc-set-source-date-epoch-to-latest.sh' '/nix/store/pilsssjjdxvdphlg2h19p0bfx5q0jzkn-strip.sh' '/nix/store/95k9rsn1zsw1yvir8mj824ldhf90i4qw-gcc-wrapper-14.3.0' '/nix/store/l19cddv64i52rhcwahif8sgyrd3mhiqb-binutils-wrapper-2.44' ) declare -a pkgsBuildTarget=() declare -a pkgsHostHost=() -declare -a pkgsHostTarget=('/nix/store/7zwa3r9agcyzf21d0792fvhrsl6gajiy-bash-interactive-5.3p3-dev' '/nix/store/ddx7976jyll30xjbasghv9jailswprcp-bash-interactive-5.3p3' '/nix/store/008h0z2m22alg2v8kcdcw4v0f7c39lmm-glibc-locales-2.40-66' '/nix/store/q1zaii9cirbfpmwr7d86hpppql3kjcpf-git-2.51.0' '/nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev' '/nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0' '/nix/store/967gn7p1p47ic924r2fx4rgbfp49fhsy-pnpm-10.15.1' '/nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev' '/nix/store/msjxcqa4x2f52dyq10rbrbw6k0m0hi90-postgresql-17.6-lib' '/nix/store/jq2kbdw6ljv9i47jz23pm072cfyxwpfj-postgresql-17.6' '/nix/store/n4lyyqirbz2j0igs12m2pyqrs7zyyvld-netlify-cli-19.0.2' '/nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0' ) +declare -a pkgsHostTarget=('/nix/store/7zwa3r9agcyzf21d0792fvhrsl6gajiy-bash-interactive-5.3p3-dev' '/nix/store/ddx7976jyll30xjbasghv9jailswprcp-bash-interactive-5.3p3' '/nix/store/008h0z2m22alg2v8kcdcw4v0f7c39lmm-glibc-locales-2.40-66' '/nix/store/q1zaii9cirbfpmwr7d86hpppql3kjcpf-git-2.51.0' '/nix/store/a99hiwhamgzds70gxkfnb4cm8i926356-nodejs-22.19.0-dev' '/nix/store/r4557ald6zn4dzmvgh8na9vwnwzgrjgc-nodejs-22.19.0' '/nix/store/967gn7p1p47ic924r2fx4rgbfp49fhsy-pnpm-10.15.1' '/nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev' '/nix/store/msjxcqa4x2f52dyq10rbrbw6k0m0hi90-postgresql-17.6-lib' '/nix/store/jq2kbdw6ljv9i47jz23pm072cfyxwpfj-postgresql-17.6' '/nix/store/ks5kxqrg113jkv9bsvhgpavrq1z1ks4g-inotify-tools-4.23.9.0' '/nix/store/1p5n2mzy33ayzc1scdnz82h53d192knh-claude-code-1.0.117' ) declare -a pkgsTargetTarget=() declare -a postFixupHooks=('noBrokenSymlinksInAllOutputs' '_makeSymlinksRelativeInAllOutputs' '_multioutPropagateDev' ) declare -a postUnpackHooks=('_updateSourceDateEpochFromSourceRoot' ) diff --git a/.gitignore b/.gitignore index 6240da8..7c68307 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,7 @@ pnpm-debug.log* # macOS-specific files .DS_Store + +# Direnv junk +.direnv/* +*/.direnv/* \ No newline at end of file diff --git a/flake.nix b/flake.nix index ffc53ea..f467648 100644 --- a/flake.nix +++ b/flake.nix @@ -10,31 +10,25 @@ system: let inherit (pkgs.lib) optional optionals; - pkgs = import nixpkgs { inherit system; }; + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + }; in with pkgs; { devShell = pkgs.mkShell { - buildInputs = - [ - bashInteractive - glibcLocales - git - nodejs - pnpm - postgresql - netlify-cli - ] - ++ optional stdenv.isLinux inotify-tools - ++ optional stdenv.isDarwin terminal-notifier - ++ optionals stdenv.isDarwin ( - with darwin.apple_sdk.frameworks; - [ - CoreFoundation - CoreServices - ] - ); + buildInputs = [ + bashInteractive + glibcLocales + git + nodejs + pnpm + postgresql + inotify-tools + claude-code + ]; }; } ); diff --git a/hindki/.env.example b/hindki/.env.example new file mode 100644 index 0000000..96dfaf0 --- /dev/null +++ b/hindki/.env.example @@ -0,0 +1,14 @@ +# Storage configuration for vocabulary updates +# Options: filesystem (default), git + +# For local development (default) +VOCAB_STORAGE_TYPE=filesystem + +# For Gitea/GitHub storage in production +# VOCAB_STORAGE_TYPE=git +# GIT_API_URL=https://gitea.example.com # Your Gitea instance URL (omit for GitHub) +# GIT_OWNER=your-username +# GIT_REPO=hindki +# GIT_PATH=src/vocab_list.yaml +# GIT_BRANCH=main +# GIT_TOKEN=your-personal-access-token \ No newline at end of file diff --git a/hindki/src/components/AddVocabForm.tsx b/hindki/src/components/AddVocabForm.tsx new file mode 100644 index 0000000..d701031 --- /dev/null +++ b/hindki/src/components/AddVocabForm.tsx @@ -0,0 +1,500 @@ +import React, { useState, useEffect } from 'react'; + +interface VocabWord { + english: string; + hindi: string; + gender?: string; + type?: string; + note?: string; + examples?: Array<{ + english: string; + hindi: string; + note?: string; + }>; + see_also?: string[]; +} + +interface VocabCategory { + slug: string; + about: string; + words: VocabWord[]; +} + +export default function AddVocabForm() { + const [categories, setCategories] = useState([]); + const [selectedCategory, setSelectedCategory] = useState(''); + const [loading, setLoading] = useState(false); + const [categoriesLoading, setCategoriesLoading] = useState(true); + const [message, setMessage] = useState(''); + const [showNewCategory, setShowNewCategory] = useState(false); + const [newCategorySlug, setNewCategorySlug] = useState(''); + const [newCategoryAbout, setNewCategoryAbout] = useState(''); + const [formData, setFormData] = useState({ + english: '', + hindi: '', + gender: '', + type: 'noun', + note: '', + examples: [], + see_also: [], + }); + const englishInputRef = React.useRef(null); + + useEffect(() => { + // Get URL parameters + const urlParams = new URLSearchParams(window.location.search); + const catFromUrl = urlParams.get('cat'); + const typeFromUrl = urlParams.get('type'); + + setCategoriesLoading(true); + fetch('/api/vocab.json') + .then(res => { + if (!res.ok) { + throw new Error(`HTTP error! status: ${res.status}`); + } + return res.json(); + }) + .then(data => { + if (Array.isArray(data) && data.length > 0) { + setCategories(data); + + // Use category from URL if provided, otherwise first category + if (catFromUrl && data.some(cat => cat.slug === catFromUrl)) { + setSelectedCategory(catFromUrl); + } else if (!selectedCategory && data.length > 0) { + setSelectedCategory(data[0].slug); + } + + // Use type from URL if provided + if (typeFromUrl) { + setFormData(prev => ({ ...prev, type: typeFromUrl })); + } + } else { + setMessage('No categories found'); + } + }) + .catch(err => { + console.error('Failed to load categories:', err); + setMessage(`Failed to load categories: ${err.message}`); + }) + .finally(() => { + setCategoriesLoading(false); + }); + }, []); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setLoading(true); + setMessage(''); + + try { + // Build word object with only non-empty fields + const word: any = { + english: formData.english, + hindi: formData.hindi, + type: formData.type, + }; + + // Only add optional fields if they have values + if (formData.gender) { + word.gender = formData.gender; + } + if (formData.note && formData.note.trim()) { + word.note = formData.note; + } + if (formData.examples && formData.examples.length > 0) { + // Filter out empty examples + const validExamples = formData.examples.filter( + ex => ex.english.trim() || ex.hindi.trim() + ); + if (validExamples.length > 0) { + word.examples = validExamples; + } + } + + if (formData.see_also && formData.see_also.length > 0) { + // Filter out empty see_also fields + const validSeeAlsos = formData.see_also.filter( + ex => ex.trim() + ); + if (validSeeAlsos.length > 0) { + word.see_also = validSeeAlsos; + } + } + + // If creating a new category, use the new category details + const categoryToUse = showNewCategory ? newCategorySlug : selectedCategory; + + const requestBody: any = { + category: categoryToUse, + word: word, + }; + + // Include new category information if creating one + if (showNewCategory) { + requestBody.newCategory = { + slug: newCategorySlug, + about: newCategoryAbout, + }; + } + + const response = await fetch('/api/vocab.json', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(requestBody), + }); + + const result = await response.json(); + + if (response.ok) { + setMessage('Word added successfully!'); + + // Remember the current type and category for bulk entry + const currentType = formData.type; + const currentCategory = showNewCategory ? newCategorySlug : selectedCategory; + + // Update URL with current category and type to persist through reloads + const newUrl = `${window.location.pathname}?cat=${currentCategory}&type=${currentType}`; + window.history.replaceState({}, '', newUrl); + + // Reset form but keep the type + setFormData({ + english: '', + hindi: '', + gender: '', + type: currentType, // Keep the last used type + note: '', + examples: [], + see_also: [], + }); + + // Focus back on English input for quick bulk entry + setTimeout(() => { + englishInputRef.current?.focus(); + }, 100); + + // If we created a new category, refresh the categories list + if (showNewCategory) { + setShowNewCategory(false); + setNewCategorySlug(''); + setNewCategoryAbout(''); + + // Refresh categories and set the new category as selected + fetch('/api/vocab.json') + .then(res => res.json()) + .then(data => { + if (Array.isArray(data) && data.length > 0) { + setCategories(data); + // Set the newly created category as selected + setSelectedCategory(currentCategory); + } + }); + } else { + // For existing categories, just keep it selected + setSelectedCategory(currentCategory); + } + } else { + setMessage(`Error: ${result.error}`); + } + } catch (error) { + setMessage('Failed to add word'); + console.error('Error:', error); + } finally { + setLoading(false); + } + }; + + const addExample = () => { + setFormData({ + ...formData, + examples: [...(formData.examples || []), { english: '', hindi: '' }], + }); + }; + + const updateExample = (index: number, field: 'english' | 'hindi', value: string) => { + const newExamples = [...(formData.examples || [])]; + newExamples[index] = { ...newExamples[index], [field]: value }; + setFormData({ ...formData, examples: newExamples }); + }; + + const removeExample = (index: number) => { + const newExamples = (formData.examples || []).filter((_, i) => i !== index); + setFormData({ ...formData, examples: newExamples }); + }; + + // Same thing for see_also + const addSeeAlso = () => { + setFormData({ + ...formData, + see_also: [...(formData.see_also || []), ''], + }); + }; + + const updateSeeAlso = (index: number, value: string) => { + const newSeeAlso = [...(formData.see_also || [])]; + newSeeAlso[index] = value; + setFormData({ ...formData, see_also: newSeeAlso }); + } + + const removeSeeAlso = (index: number) => { + const newSeeAlso = (formData.see_also || []).filter((_, i) => i !== index); + setFormData({ ...formData, see_also: newSeeAlso }); + } + + return ( +
+
+
+ + +
+ + {showNewCategory && ( + <> +
+ + setNewCategorySlug(e.target.value.toLowerCase().replace(/\s+/g, '-'))} + placeholder="e.g., food-and-drink" + required={showNewCategory} + /> +
+
+ + setNewCategoryAbout(e.target.value)} + placeholder="e.g., Words related to food and beverages" + required={showNewCategory} + /> +
+ + )} + +
+ + setFormData({ ...formData, english: e.target.value })} + autoFocus + required + /> +
+ +
+ + setFormData({ ...formData, hindi: e.target.value })} + required + /> +
+ +
+ + +
+ +
+ + +
+ +
+ +