diff --git a/public/think_in_sync_assets/abyss.jpg b/public/think_in_sync_assets/abyss.jpg deleted file mode 100644 index 3123ce5ed49362c9e5d81e75b65668b65a6ca094..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/abyss.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/adventure.jpg b/public/think_in_sync_assets/adventure.jpg deleted file mode 100644 index b53dc1ff02ba1ffb8d6b4ea442b120657ddd1abe..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/adventure.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/aurora.jpg b/public/think_in_sync_assets/aurora.jpg deleted file mode 100644 index 5d5b800a9474b175911114b5016f48805940d450..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/aurora.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/balance.jpg b/public/think_in_sync_assets/balance.jpg deleted file mode 100644 index f236c7d4c26d2f4f4943b05ffa04ccffc53f709f..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/balance.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/bliss.jpg b/public/think_in_sync_assets/bliss.jpg deleted file mode 100644 index ee6f0429c48947291e1cdaabd18c8750f7f66a8c..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/bliss.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/breeze.jpg b/public/think_in_sync_assets/breeze.jpg deleted file mode 100644 index b625288df21d4a0bc3b38a61bbb3abaec00bbbb6..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/breeze.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/butterfly.jpg b/public/think_in_sync_assets/butterfly.jpg deleted file mode 100644 index 3a080d4f52c47790cebf2dc91a7a2dff9400129b..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/butterfly.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/calm.jpg b/public/think_in_sync_assets/calm.jpg deleted file mode 100644 index 458770f6257305ab9b7adc666e4fa9d061170458..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/calm.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/canyon.jpg b/public/think_in_sync_assets/canyon.jpg deleted file mode 100644 index 55f82fada2dbcc9e05f4c18ed470e08124434ad0..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/canyon.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/cascade.jpg b/public/think_in_sync_assets/cascade.jpg deleted file mode 100644 index 9f55e01220ff6d1d5aef86227fa661d49877ec35..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/cascade.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/citadel.jpg b/public/think_in_sync_assets/citadel.jpg deleted file mode 100644 index 195d3e3f4fa30cb8a7f58d263ee20e7f2ab41ccc..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/citadel.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/cloud.jpg b/public/think_in_sync_assets/cloud.jpg deleted file mode 100644 index fab8f9cecd5eb3a9bd4ca618302ccda6851e8152..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/cloud.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/comet.jpg b/public/think_in_sync_assets/comet.jpg deleted file mode 100644 index 0f3e1547f71e7e71d612ed580a1096ff09408d40..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/comet.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/crescent.jpg b/public/think_in_sync_assets/crescent.jpg deleted file mode 100644 index d2bb1784833533dac97ce527cc0132cf0ab5bb5e..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/crescent.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/cristal.jpg b/public/think_in_sync_assets/cristal.jpg deleted file mode 100644 index 52276376a3e85872930e2d23e83435bae59a3813..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/cristal.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/crystal.jpg b/public/think_in_sync_assets/crystal.jpg deleted file mode 100644 index ecba912708968dbe8c98a7a707f6e48ec146cce6..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/crystal.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/dawn.jpg b/public/think_in_sync_assets/dawn.jpg deleted file mode 100644 index 82d91a4cb298ebcbd8785ebaeae8943173c1a964..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/dawn.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/dazzle.jpg b/public/think_in_sync_assets/dazzle.jpg deleted file mode 100644 index d25026255bf6d598b82deb3ba9f1925df6cc967f..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/dazzle.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/diamond.jpg b/public/think_in_sync_assets/diamond.jpg deleted file mode 100644 index 83787e81ec38ee775d95664fb3422779e744f116..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/diamond.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/dream.jpg b/public/think_in_sync_assets/dream.jpg deleted file mode 100644 index 7644bb9dff517b7c6f5990e01698f6ad0f519cbc..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/dream.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/echo.jpg b/public/think_in_sync_assets/echo.jpg deleted file mode 100644 index 5b7abb8221c87370522576619463070493af7645..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/echo.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/eclipse.jpg b/public/think_in_sync_assets/eclipse.jpg deleted file mode 100644 index 5a0e5d2beeba078100827b9eb19c48f1e6724af8..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/eclipse.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/elephant.jpg b/public/think_in_sync_assets/elephant.jpg deleted file mode 100644 index facd7b6160a9f85d94be8c68c278046d87365624..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/elephant.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/embrace.jpg b/public/think_in_sync_assets/embrace.jpg deleted file mode 100644 index e5c36c726613ddc07cbab3292788ca5b660dd713..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/embrace.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/fantasy.jpg b/public/think_in_sync_assets/fantasy.jpg deleted file mode 100644 index 4f0e1176c4b11f0d6a6c0bc51e13d53e2390a3d3..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/fantasy.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/feather.jpg b/public/think_in_sync_assets/feather.jpg deleted file mode 100644 index a52249fa17ec58994495af650e7a63c5cbd9f427..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/feather.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/firelight.jpg b/public/think_in_sync_assets/firelight.jpg deleted file mode 100644 index 99ebf0752df25e4f91630e61cd2fe993a018615e..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/firelight.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/flicker.jpg b/public/think_in_sync_assets/flicker.jpg deleted file mode 100644 index c0119813faa91e13937ad8dd9e32514c0cb5a0da..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/flicker.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/flower.jpg b/public/think_in_sync_assets/flower.jpg deleted file mode 100644 index 3dc73a0cce234722cd2673fdc72c00f48da2c114..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/flower.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/forest.jpg b/public/think_in_sync_assets/forest.jpg deleted file mode 100644 index 2589cf15611c88ae45ae1379eedd17d2bfcade30..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/forest.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/freedom.jpg b/public/think_in_sync_assets/freedom.jpg deleted file mode 100644 index 82ffbf929abcf976a7d0065f09fb82ad3dc58d81..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/freedom.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/galaxy.jpg b/public/think_in_sync_assets/galaxy.jpg deleted file mode 100644 index 4b966abaee5ea2b8c7d870179655218ba32c44be..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/galaxy.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/garden.jpg b/public/think_in_sync_assets/garden.jpg deleted file mode 100644 index f2de1300c55b2c9077460401320c52665dd3d44f..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/garden.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/glimmer.jpg b/public/think_in_sync_assets/glimmer.jpg deleted file mode 100644 index dec23ed4fbce1a8bb4001857ef7a028c70e5f9c3..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/glimmer.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/glow.jpg b/public/think_in_sync_assets/glow.jpg deleted file mode 100644 index 6c184f0f3c87382d7d8b96113bc0f3c9bf644fb4..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/glow.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/halo.jpg b/public/think_in_sync_assets/halo.jpg deleted file mode 100644 index 1c4daf65c8299a7ddae13cc1d3c2914d14ddbff6..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/halo.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/harmony.jpg b/public/think_in_sync_assets/harmony.jpg deleted file mode 100644 index 2cbc70c03a13e0397ef29d6847d89ca26968ddda..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/harmony.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/haven.jpg b/public/think_in_sync_assets/haven.jpg deleted file mode 100644 index c922df6ba18e541f3d87f15a114c608282d848aa..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/haven.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/heartbeat.jpg b/public/think_in_sync_assets/heartbeat.jpg deleted file mode 100644 index b25cf94e2d229e4c70924b60c8f06faa6f253d0a..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/heartbeat.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/horizon.jpg b/public/think_in_sync_assets/horizon.jpg deleted file mode 100644 index 5adb39b658aec97f150d803a461b681ee204e0ee..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/horizon.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/illuminate.jpg b/public/think_in_sync_assets/illuminate.jpg deleted file mode 100644 index ef5280919ffd516cc837061f0e0e8d72bef95b72..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/illuminate.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/infinity.jpg b/public/think_in_sync_assets/infinity.jpg deleted file mode 100644 index 2866ededa461d2477b259b16637f4fecb56fa5f5..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/infinity.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/jewel.jpg b/public/think_in_sync_assets/jewel.jpg deleted file mode 100644 index 9c076f56efff8333f6ee4de74b90066ae45ce0d5..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/jewel.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/journey.jpg b/public/think_in_sync_assets/journey.jpg deleted file mode 100644 index 9142d111885520df05a255bf33fa1c0ef8748767..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/journey.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/jubilee.jpg b/public/think_in_sync_assets/jubilee.jpg deleted file mode 100644 index 71ebb0dcb913649ddc9890eb119df16cb072f3e4..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/jubilee.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/kaleidoscope.jpg b/public/think_in_sync_assets/kaleidoscope.jpg deleted file mode 100644 index 9cc46bd8e1ddde672e2b4259fbcd29084c2a440d..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/kaleidoscope.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/lantern.jpg b/public/think_in_sync_assets/lantern.jpg deleted file mode 100644 index 92f1be53c6d5b29b07be3bb22956d8e28a1a69b4..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/lantern.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/lightning.jpg b/public/think_in_sync_assets/lightning.jpg deleted file mode 100644 index 2a7b012a90956e43d8553fbb053959527f1211b2..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/lightning.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/lullaby.jpg b/public/think_in_sync_assets/lullaby.jpg deleted file mode 100644 index b1c9547bc770cc3d32e477b6bed02b6ff9b84caf..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/lullaby.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/luminous.jpg b/public/think_in_sync_assets/luminous.jpg deleted file mode 100644 index 4d8926cb10c6eb0d275296ddc565bdfff005bf63..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/luminous.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/marvel.jpg b/public/think_in_sync_assets/marvel.jpg deleted file mode 100644 index 085aca5c0e448bf32f4d634bda441f38e0cbdc9c..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/marvel.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/meadow.jpg b/public/think_in_sync_assets/meadow.jpg deleted file mode 100644 index 9306e2f2ef141b029275d21ae64f6a5d07249021..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/meadow.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/miracle.jpg b/public/think_in_sync_assets/miracle.jpg deleted file mode 100644 index 6d774fe53a4b6c502be96177b1b4dfee98d82f8d..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/miracle.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/moonlight.jpg b/public/think_in_sync_assets/moonlight.jpg deleted file mode 100644 index b7086f68442533440868615e9065b4301fd969f0..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/moonlight.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/mountain.jpg b/public/think_in_sync_assets/mountain.jpg deleted file mode 100644 index ccef8e9c8c5d1823bf5828af8c1ed796286e0cd2..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/mountain.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/mystic.jpg b/public/think_in_sync_assets/mystic.jpg deleted file mode 100644 index e56a9b85117d76d1f5da679ff27b80aa07430523..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/mystic.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/nebula.jpg b/public/think_in_sync_assets/nebula.jpg deleted file mode 100644 index b00846e0d2eb1aad428466853d0e219faf76cfbf..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/nebula.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/night.jpg b/public/think_in_sync_assets/night.jpg deleted file mode 100644 index 0f406080abf663424ff210be46200384cb6b9693..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/night.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/nightfall.jpg b/public/think_in_sync_assets/nightfall.jpg deleted file mode 100644 index 561d87ac44683f1807f6c1cdc4b9f72957958b31..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/nightfall.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/nirvana.jpg b/public/think_in_sync_assets/nirvana.jpg deleted file mode 100644 index 8a0a7ad56a980b576f2d2c2502b134261dfdc7c8..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/nirvana.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/oasis.jpg b/public/think_in_sync_assets/oasis.jpg deleted file mode 100644 index 6f6536699d79eafef1ee8d73ac559c7bc3caa83d..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/oasis.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/ocean.jpg b/public/think_in_sync_assets/ocean.jpg deleted file mode 100644 index 6573658e491952970ea3278c3f7c5b7e1992d8d1..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/ocean.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/opulence.jpg b/public/think_in_sync_assets/opulence.jpg deleted file mode 100644 index 60313fa5e557d8cea0be968d715f4fdc50238340..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/opulence.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/paradise.jpg b/public/think_in_sync_assets/paradise.jpg deleted file mode 100644 index 3fc1fbca9e15d3d8cc69c2737634117a00b7fc2e..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/paradise.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/peace.jpg b/public/think_in_sync_assets/peace.jpg deleted file mode 100644 index 141cf585bc4292bccffef1ff00973f169ca37cf1..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/peace.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/pebble.jpg b/public/think_in_sync_assets/pebble.jpg deleted file mode 100644 index 5b478fe88450ac56415c3b82c127678bdc6be944..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/pebble.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/quiet.jpg b/public/think_in_sync_assets/quiet.jpg deleted file mode 100644 index 517ca5c1aab93adceb1d74fa71b89004191b60ae..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/quiet.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/quietitude.jpg b/public/think_in_sync_assets/quietitude.jpg deleted file mode 100644 index 2f072332a703025d8fca87bcdfc4f64c756ded64..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/quietitude.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/radiance.jpg b/public/think_in_sync_assets/radiance.jpg deleted file mode 100644 index a785c25ace65a6d786827842eec25cb3951361ac..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/radiance.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/rainbow.jpg b/public/think_in_sync_assets/rainbow.jpg deleted file mode 100644 index 7c16657f95a4d3853398768ded013b36c4e58980..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/rainbow.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/rapture.jpg b/public/think_in_sync_assets/rapture.jpg deleted file mode 100644 index 08ce9daabf25cd706e8515f7f8905503a385e5cf..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/rapture.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/river.jpg b/public/think_in_sync_assets/river.jpg deleted file mode 100644 index f2d9b2cecc8b78b7f88857b8055106c1b9672f99..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/river.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/sanctuary.jpg b/public/think_in_sync_assets/sanctuary.jpg deleted file mode 100644 index 1f181a3b0e243a0ed7798ee2f14c0c27d56c78db..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/sanctuary.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/serene.jpg b/public/think_in_sync_assets/serene.jpg deleted file mode 100644 index 702ebb25709211bcbd98335169643d8950153929..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/serene.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/serenity.jpg b/public/think_in_sync_assets/serenity.jpg deleted file mode 100644 index e19ea161b579b10f2945a43acafbca850b156dd3..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/serenity.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/shadow.jpg b/public/think_in_sync_assets/shadow.jpg deleted file mode 100644 index c6de08c1a61a65e0f3a8a6875409020f6ceaf7c3..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/shadow.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/snowflake.jpg b/public/think_in_sync_assets/snowflake.jpg deleted file mode 100644 index fff07d09b03d2a668aa06c4dd5c7293d164bd6f0..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/snowflake.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/stardust.jpg b/public/think_in_sync_assets/stardust.jpg deleted file mode 100644 index 51b914cd6b661f9287c3cea42d0c89fa9a268b8f..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/stardust.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/starlight.jpg b/public/think_in_sync_assets/starlight.jpg deleted file mode 100644 index 3f9f4790dcdd341dd6342dd756543f7bfaaf4fd6..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/starlight.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/sunshine.jpg b/public/think_in_sync_assets/sunshine.jpg deleted file mode 100644 index ac9280e17b39fa638d3cc71d39f5d7e4f0454223..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/sunshine.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/thunder.jpg b/public/think_in_sync_assets/thunder.jpg deleted file mode 100644 index b23a7f2207ae1a445b954c0772f27642433008fc..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/thunder.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/tranquil.jpg b/public/think_in_sync_assets/tranquil.jpg deleted file mode 100644 index 27aa73f9fb78a44352469a78b2672f7d1c9b03e6..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/tranquil.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/tranquility.jpg b/public/think_in_sync_assets/tranquility.jpg deleted file mode 100644 index 5cdba447fc43cbce6ce1f0bf98bfc87b4c3dd34a..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/tranquility.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/treasure.jpg b/public/think_in_sync_assets/treasure.jpg deleted file mode 100644 index 7a4f0b4f86ff89142b55d7f8b9034a158131025d..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/treasure.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/twilight.jpg b/public/think_in_sync_assets/twilight.jpg deleted file mode 100644 index 4f5e0ac5d9daa679992962f1ceb9b01bfad4fd7d..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/twilight.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/unity.jpg b/public/think_in_sync_assets/unity.jpg deleted file mode 100644 index e2d050f7b3092fd2cd9d26067220ef4db1571773..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/unity.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/universe.jpg b/public/think_in_sync_assets/universe.jpg deleted file mode 100644 index e4957b62c845043134961da585ee953e847d15d7..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/universe.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/velvet.jpg b/public/think_in_sync_assets/velvet.jpg deleted file mode 100644 index 15016977615745a625b6e3265b37fafc376247cd..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/velvet.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/vision.jpg b/public/think_in_sync_assets/vision.jpg deleted file mode 100644 index 1fdd7eabd866ae91376d6b6e357caf606aa12e7c..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/vision.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/vista.jpg b/public/think_in_sync_assets/vista.jpg deleted file mode 100644 index bc07ca21c98cd59a0902a9e2f69145292be4a9a8..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/vista.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/wanderlust.jpg b/public/think_in_sync_assets/wanderlust.jpg deleted file mode 100644 index ce79ad1f3ea052f5cf02c263d27c31adf6b69c13..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/wanderlust.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/waterfall.jpg b/public/think_in_sync_assets/waterfall.jpg deleted file mode 100644 index 5875f7c88ca2e7190c11bade68b75da4ca3bf2be..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/waterfall.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/whisper.jpg b/public/think_in_sync_assets/whisper.jpg deleted file mode 100644 index e90d3d394b08d37214a360f2771d6b634b1b8457..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/whisper.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/wilderness.jpg b/public/think_in_sync_assets/wilderness.jpg deleted file mode 100644 index 63fef43868693bab5bfdba2f0a8cbdacf5c5456c..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/wilderness.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/wish.jpg b/public/think_in_sync_assets/wish.jpg deleted file mode 100644 index 7469c3121427153cecdfa8719aacfcf0cc32bd09..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/wish.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/wonder.jpg b/public/think_in_sync_assets/wonder.jpg deleted file mode 100644 index 344405d94537cf4152069f2536c038acb5a7d220..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/wonder.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/wonderland.jpg b/public/think_in_sync_assets/wonderland.jpg deleted file mode 100644 index 16641be6c6deb899b6eab738ee26867a581d469e..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/wonderland.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/wonderment.jpg b/public/think_in_sync_assets/wonderment.jpg deleted file mode 100644 index d1556e97afca0d0fb525e40ccd11589ffac8e8fc..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/wonderment.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/yearning.jpg b/public/think_in_sync_assets/yearning.jpg deleted file mode 100644 index 6e13f34493ac5417704179f7458cf386ce8bf162..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/yearning.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/yield.jpg b/public/think_in_sync_assets/yield.jpg deleted file mode 100644 index d08cd57cdf7b68954f83171e4513fd5ea9f04665..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/yield.jpg and /dev/null differ diff --git a/public/think_in_sync_assets/zeal.jpg b/public/think_in_sync_assets/zeal.jpg deleted file mode 100644 index 55489902047b2ab9dab9de889c9f6a62228c2edd..0000000000000000000000000000000000000000 Binary files a/public/think_in_sync_assets/zeal.jpg and /dev/null differ diff --git a/src/App.tsx b/src/App.tsx index f6f9a2aeb310f3ff8e7808c57431d106e02df087..28670644346806aa2cb4b1c8328deee7ca07995a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,27 +1,25 @@ +import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; +import Index from "@/pages/Index"; +import { AdminIndex } from "@/pages/admin/Index"; +import { AdminLogin } from "@/pages/admin/Login"; import { Toaster } from "@/components/ui/toaster"; -import { Toaster as Sonner } from "@/components/ui/sonner"; -import { TooltipProvider } from "@/components/ui/tooltip"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { BrowserRouter, Routes, Route } from "react-router-dom"; -import { LanguageProvider } from "./contexts/LanguageContext"; -import Index from "./pages/Index"; const queryClient = new QueryClient(); -const App = () => ( - - - +function App() { + return ( + + + + } /> + } /> + } /> + - - - - } /> - - - - - -); + + + ); +} export default App; \ No newline at end of file diff --git a/src/components/GameContainer.tsx b/src/components/GameContainer.tsx index 19ca556be7aadc0da6975734f3d3c33bf98060aa..3dcf806b3c8b67dc9bdabf310577f9c3fdc25aa0 100644 --- a/src/components/GameContainer.tsx +++ b/src/components/GameContainer.tsx @@ -284,6 +284,7 @@ export const GameContainer = () => { onInputChange={setPlayerInput} onSubmitWord={handlePlayerWord} onMakeGuess={handleMakeGuess} + normalizeWord={normalizeWord} onBack={handleBack} /> ) : ( diff --git a/src/components/HighScoreBoard.tsx b/src/components/HighScoreBoard.tsx index 98aea60545784691dd486670c88bf8d1154bea5e..ea4aaf7c5a91e9325e07091a46795fc668483dfd 100644 --- a/src/components/HighScoreBoard.tsx +++ b/src/components/HighScoreBoard.tsx @@ -31,6 +31,7 @@ interface HighScoreBoardProps { } const ITEMS_PER_PAGE = 5; +const STANDARD_THEMES = ['standard', 'sports', 'food']; export const HighScoreBoard = ({ currentScore = 0, @@ -58,13 +59,21 @@ export const HighScoreBoard = ({ queryKey: ["highScores", selectedTheme], queryFn: async () => { console.log("Fetching high scores for theme:", selectedTheme); - const { data, error } = await supabase + let query = supabase .from("high_scores") .select("*") - .eq('theme', selectedTheme) .order("score", { ascending: false }) .order("avg_words_per_round", { ascending: true }); + if (selectedTheme === 'custom') { + const filterValue = `(${STANDARD_THEMES.join(',')})`; + query = query.filter('theme', 'not.in', filterValue); + } else { + query = query.eq('theme', selectedTheme); + } + + const { data, error } = await query; + if (error) { console.error("Error fetching high scores:", error); throw error; @@ -185,6 +194,7 @@ export const HighScoreBoard = ({ { + const { data: highScores, isLoading } = useQuery({ + queryKey: ["adminHighScores"], + queryFn: async () => { + console.log("Fetching high scores..."); + // First fetch high scores + const { data: highScoresData, error: highScoresError } = await supabase + .from("high_scores") + .select("*") + .order("score", { ascending: false }); + + if (highScoresError) { + console.error("Error fetching high scores:", highScoresError); + throw highScoresError; + } + + // Then fetch game results for each high score + const highScoresWithGames = await Promise.all( + highScoresData.map(async (score) => { + const { data: gameResults, error: gameResultsError } = await supabase + .from("game_results") + .select("target_word, description, ai_guess, is_correct") + .eq("session_id", score.session_id); + + if (gameResultsError) { + console.error("Error fetching game results:", gameResultsError); + return { + ...score, + game_results: [], + }; + } + + return { + ...score, + game_results: gameResults || [], + }; + }) + ); + + console.log("Fetched high scores with game results:", highScoresWithGames); + return highScoresWithGames as HighScoreWithGames[]; + }, + }); + + if (isLoading) { + return
Loading...
; + } + + return ( +
+ + + + Player + Score + Avg Words/Round + Theme + Date + Details + + + + {highScores?.map((score) => ( + + {score.player_name} + {score.score} + {score.avg_words_per_round.toFixed(1)} + {score.theme} + + {new Date(score.created_at).toLocaleDateString()} + + + + + + + + + Game Details for {score.player_name} + + + + + + + ))} + +
+
+ ); +}; \ No newline at end of file diff --git a/src/components/admin/GameDetailsView.tsx b/src/components/admin/GameDetailsView.tsx new file mode 100644 index 0000000000000000000000000000000000000000..d5d4d7d984724f0c9814824b1a0ee9ed2691b08a --- /dev/null +++ b/src/components/admin/GameDetailsView.tsx @@ -0,0 +1,55 @@ +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { Check, X } from "lucide-react"; + +interface GameResult { + target_word: string; + description: string; + ai_guess: string; + is_correct: boolean; +} + +interface GameDetailsViewProps { + gameResults: GameResult[]; +} + +export const GameDetailsView = ({ gameResults }: GameDetailsViewProps) => { + return ( +
+ + + + Target Word + Description + AI Guess + Result + + + + {gameResults?.map((result, index) => ( + + {result.target_word} + + {result.description} + + {result.ai_guess} + + {result.is_correct ? ( + + ) : ( + + )} + + + ))} + +
+
+ ); +}; \ No newline at end of file diff --git a/src/components/game/LanguageSelector.tsx b/src/components/game/LanguageSelector.tsx index 1669ee0dbf1fc9a7111bf91c0da49b0c93e20012..7b346066403f6375a34711cbdc825487b85a2f0f 100644 --- a/src/components/game/LanguageSelector.tsx +++ b/src/components/game/LanguageSelector.tsx @@ -14,13 +14,20 @@ const languages: { code: Language; name: string; flag: string }[] = [ export const LanguageSelector = () => { const { language, setLanguage } = useContext(LanguageContext); + console.log('[LanguageSelector] Current language:', language); + + const handleLanguageChange = (code: Language) => { + console.log('[LanguageSelector] Language button clicked:', code); + setLanguage(code); + }; + return (
{languages.map(({ code, name, flag }) => ( diff --git a/src/components/game/welcome/ContestSection.tsx b/src/components/game/welcome/ContestSection.tsx index 7e6a967dc599a6cca3baa38d18cc2f23c7eac7f8..512cca0197e0022a9698114da635b3dda4bdb0e1 100644 --- a/src/components/game/welcome/ContestSection.tsx +++ b/src/components/game/welcome/ContestSection.tsx @@ -4,10 +4,10 @@ import { useTranslation } from "@/hooks/useTranslation"; export const ContestSection = () => { const t = useTranslation(); - + return (
-

🕹️ {t.welcome.contest.prize} 🤑

+

🕹️ {t.welcome.contest.prize} 🧑‍🍳

+
diff --git a/src/contexts/LanguageContext.tsx b/src/contexts/LanguageContext.tsx index 61f877f666aecef2582e102af93e66f454c9c08f..fd3d976e8e4da200d618f31f507af38aab4c5e34 100644 --- a/src/contexts/LanguageContext.tsx +++ b/src/contexts/LanguageContext.tsx @@ -20,14 +20,17 @@ export const LanguageProvider = ({ children }: LanguageProviderProps) => { useEffect(() => { const savedLang = localStorage.getItem('language') as Language; + console.log('[LanguageContext] Initial load - Saved language:', savedLang); if (savedLang && ['en', 'fr', 'de', 'it', 'es'].includes(savedLang)) { setLanguage(savedLang); } }, []); const handleSetLanguage = (lang: Language) => { + console.log('[LanguageContext] Setting new language:', lang); setLanguage(lang); localStorage.setItem('language', lang); + console.log('[LanguageContext] Updated localStorage:', localStorage.getItem('language')); }; return ( diff --git a/src/hooks/useTranslation.ts b/src/hooks/useTranslation.ts index d272510488431e2638583fb46e28f4a30e0021f4..f09571ba22fbff09f2ddd4e9c4d95875b3a18921 100644 --- a/src/hooks/useTranslation.ts +++ b/src/hooks/useTranslation.ts @@ -4,5 +4,6 @@ import { translations } from '@/i18n/translations'; export const useTranslation = () => { const { language } = useContext(LanguageContext); + console.log('[useTranslation] Getting translations for language:', language); return translations[language]; }; \ No newline at end of file diff --git a/src/i18n/translations/de.ts b/src/i18n/translations/de.ts index e216640c7d0924cbf0f61eb7addb8135c96ac5d8..2e0b1166be80f2d8fbe5683007b69b386a26f32c 100644 --- a/src/i18n/translations/de.ts +++ b/src/i18n/translations/de.ts @@ -1,128 +1,129 @@ export const de = { - game: { - title: "Think in Sync", - round: "Runde", - buildDescription: "Baut gemeinsam einen Satz", - buildSubtitle: "Fügt abwechselnd Wörter hinzu, um einen Satz zu bilden", - startSentence: "Beginne deinen Satz...", - inputPlaceholder: "Gib EIN Wort ein...", - addWord: "Wort hinzufügen", - makeGuess: "Raten", - aiThinking: "KI denkt nach...", - aiDelayed: "Die KI ist derzeit beschäftigt. Bitte versuche es gleich noch einmal.", - invalidWord: "Ungültiges Wort", - cantUseTargetWord: "Verwende nicht das geheime Wort", - lettersOnly: "Bitte nur Buchstaben verwenden", - singleWordOnly: "Bitte nur ein Wort eingeben", - leaveGameTitle: "Spiel verlassen?", - leaveGameDescription: "Dein aktueller Fortschritt geht verloren. Bist du sicher, dass du das Spiel verlassen möchtest?", - cancel: "Abbrechen", - confirm: "Bestätigen", - describeWord: "Dein Ziel ist es folgendes Wort zu beschreiben", - nextRound: "Nächste Runde", - playAgain: "Erneut spielen", - saveScore: "Punktzahl speichern" - }, - leaderboard: { - title: "Bestenliste", - yourScore: "Deine Punktzahl", - roundCount: "Runden", - wordsPerRound: "Wörter pro Runde", - enterName: "Gib deinen Namen ein", - submitting: "Wird übermittelt...", - submit: "Punktzahl einreichen", - rank: "Rang", - player: "Spieler", - roundsColumn: "Runden", - avgWords: "Durchschn. Wörter", - noScores: "Noch keine Punktzahlen", - previous: "Vorherige", - next: "Nächste", - success: "Punktzahl erfolgreich übermittelt!", - error: { - invalidName: "Bitte gib einen gültigen Namen ein", - noRounds: "Du musst mindestens eine Runde abschließen", - alreadySubmitted: "Punktzahl bereits eingereicht", - newHighScore: "Neuer Highscore!", - beatRecord: "Du hast deinen bisherigen Rekord von {score} geschlagen!", - notHigher: "Punktzahl von {current} nicht höher als dein Bester von {best}", - submitError: "Fehler beim Einreichen der Punktzahl" - } + game: { + title: "Think in Sync", + round: "Runde", + buildDescription: "Baut gemeinsam einen Satz", + buildSubtitle: "Fügt abwechselnd Wörter hinzu, um einen Satz zu bilden", + startSentence: "Beginne deinen Satz...", + inputPlaceholder: "Gib EIN Wort ein...", + addWord: "Wort hinzufügen", + makeGuess: "Raten", + aiThinking: "KI denkt nach...", + aiDelayed: "Die KI ist derzeit beschäftigt. Bitte versuche es gleich noch einmal.", + invalidWord: "Ungültiges Wort", + cantUseTargetWord: "Verwende nicht das geheime Wort", + lettersOnly: "Bitte nur Buchstaben verwenden", + singleWordOnly: "Bitte nur ein Wort eingeben", + leaveGameTitle: "Spiel verlassen?", + leaveGameDescription: "Dein aktueller Fortschritt geht verloren. Bist du sicher, dass du das Spiel verlassen möchtest?", + cancel: "Abbrechen", + confirm: "Bestätigen", + describeWord: "Dein Ziel ist es folgendes Wort zu beschreiben", + nextRound: "Nächste Runde", + playAgain: "Erneut spielen", + saveScore: "Punktzahl speichern" + }, + leaderboard: { + title: "Bestenliste", + yourScore: "Deine Punktzahl", + roundCount: "Runden", + wordsPerRound: "Wörter pro Runde", + enterName: "Gib deinen Namen ein", + submitting: "Wird übermittelt...", + submit: "Punktzahl einreichen", + rank: "Rang", + player: "Spieler", + roundsColumn: "Runden", + avgWords: "Durchschn. Wörter", + noScores: "Noch keine Punktzahlen", + previous: "Vorherige", + next: "Nächste", + success: "Punktzahl erfolgreich übermittelt!", + theme: "Thema", + error: { + invalidName: "Bitte gib einen gültigen Namen ein", + noRounds: "Du musst mindestens eine Runde abschließen", + alreadySubmitted: "Punktzahl bereits eingereicht", + newHighScore: "Neuer Highscore!", + beatRecord: "Du hast deinen bisherigen Rekord von {score} geschlagen!", + notHigher: "Punktzahl von {current} nicht höher als dein Bester von {best}", + submitError: "Fehler beim Einreichen der Punktzahl" + } + }, + guess: { + title: "KI-Vermutung", + goalDescription: "Dein Ziel war es folgendes Wort zu beschreiben", + providedDescription: "Du hast folgende Beschreibung gegeben", + aiGuessedDescription: "Basierend auf deiner Beschreibung hat die KI geraten", + correct: "Das ist richtig!", + incorrect: "Das ist falsch.", + nextRound: "Nächste Runde", + playAgain: "Erneut spielen", + viewLeaderboard: "In Bestenliste eintragen", + cheatingDetected: "Betrugsversuch erkannt!" + }, + themes: { + title: "Wähle ein Thema", + subtitle: "Wähle ein Thema für das Wort, das die KI erraten soll", + standard: "Standard", + technology: "Technologie", + sports: "Sport", + food: "Essen", + custom: "Eigenes Thema", + customPlaceholder: "Gib dein eigenes Thema ein...", + continue: "Weiter", + generating: "Wird generiert...", + pressKey: "Drücke", + playing: "Thema" + }, + welcome: { + title: "Think in Sync", + subtitle: "Arbeite mit KI zusammen, um einen Hinweis zu erstellen und lass eine andere KI dein geheimes Wort erraten!", + startButton: "Spiel starten", + howToPlay: "Spielanleitung", + leaderboard: "Bestenliste", + credits: "Erstellt während des", + likeGameText: "Wenn du dieses Spiel unterstützen möchtest", + contest: { + prize: "Wir kochen etwas...", + terms: "Erfahre mehr", + howTo: "So bereitest du dich vor:", + conditions: [ + "Spiele Think in Sync mit der Standard-Wortliste", + "Setze deinen Bestenlisten-Namen gleich deinem Hugging Face Benutzernamen", + "Like unser Projekt auf Hugging Face" + ], + deadline: "Wir werden die Details bald hier bekannt geben", + prizes: { + title: "Kämpfe um die Top 5 Plätze und gewinne:", + list: [ + "🥇 1. Platz: 50€", + "🥈 2. Platz: 20€", + "🥉 3. Platz: 10€", + "🎖️ 4. & 5. Platz: je 10€" + ] + }, + fairPlay: "🚨 Faires Spielen wird überwacht. Betrug führt zur Disqualifikation!" }, - guess: { - title: "KI-Vermutung", - goalDescription: "Dein Ziel war es folgendes Wort zu beschreiben", - providedDescription: "Du hast folgende Beschreibung gegeben", - aiGuessedDescription: "Basierend auf deiner Beschreibung hat die KI geraten", - correct: "Das ist richtig!", - incorrect: "Das ist falsch.", - nextRound: "Nächste Runde", - playAgain: "Erneut spielen", - viewLeaderboard: "In Bestenliste eintragen", - cheatingDetected: "Betrugsversuch erkannt!" + likeOnHuggingface: "Auf Hugging Face liken" + }, + howToPlay: { + setup: { + title: "Vorbereitung", + description: "Wähle ein Thema und erhalte ein geheimes Wort, das die KI erraten soll." }, - themes: { - title: "Wähle ein Thema", - subtitle: "Wähle ein Thema für das Wort, das die KI erraten soll", - standard: "Standard", - technology: "Technologie", - sports: "Sport", - food: "Essen", - custom: "Eigenes Thema", - customPlaceholder: "Gib dein eigenes Thema ein...", - continue: "Weiter", - generating: "Wird generiert...", - pressKey: "Drücke", - playing: "Thema" + goal: { + title: "Ziel", + description: "Baue gemeinsam mit der KI Sätze, die dein Wort beschreiben, ohne es direkt zu verwenden." }, - welcome: { - title: "Think in Sync", - subtitle: "Arbeite mit KI zusammen, um einen Hinweis zu erstellen und lass eine andere KI dein geheimes Wort erraten!", - startButton: "Spiel starten", - howToPlay: "Spielanleitung", - leaderboard: "Bestenliste", - credits: "Erstellt während des", - likeGameText: "Wenn dir das Spiel gefällt, dann", - contest: { - prize: "Spiele und gewinne bis zu 50€!", - terms: "Bedingungen ansehen", - howTo: "So nimmst du teil:", - conditions: [ - "Spiele Think in Sync mit der Standard-Wortliste", - "Setze deinen Bestenlisten-Namen gleich deinem Hugging Face Benutzernamen", - "Like unser Projekt auf Hugging Face" - ], - deadline: "Ende: 5. Februar, 10:00 Uhr", - prizes: { - title: "Kämpfe um die Top 5 Plätze und gewinne:", - list: [ - "🥇 1. Platz: 50€", - "🥈 2. Platz: 20€", - "🥉 3. Platz: 10€", - "🎖️ 4. & 5. Platz: je 10€" - ] - }, - fairPlay: "🚨 Faires Spielen wird überwacht. Betrug führt zur Disqualifikation!" - }, - likeOnHuggingface: "Auf Hugging Face liken" - }, - howToPlay: { - setup: { - title: "Vorbereitung", - description: "Wähle ein Thema und erhalte ein geheimes Wort, das die KI erraten soll." - }, - goal: { - title: "Ziel", - description: "Baue gemeinsam mit der KI Sätze, die dein Wort beschreiben, ohne es direkt zu verwenden." - }, - rules: { - title: "Regeln", - items: [ - "Füge abwechselnd Wörter hinzu, um beschreibende Sätze zu bilden", - "Verwende nicht das geheime Wort oder seine Variationen", - "Sei kreativ und beschreibend", - "Die KI wird nach jedem Satz versuchen, dein Wort zu erraten" - ] - } + rules: { + title: "Regeln", + items: [ + "Füge abwechselnd Wörter hinzu, um beschreibende Sätze zu bilden", + "Verwende nicht das geheime Wort oder seine Variationen", + "Sei kreativ und beschreibend", + "Die KI wird nach jedem Satz versuchen, dein Wort zu erraten" + ] } + } }; diff --git a/src/i18n/translations/en.ts b/src/i18n/translations/en.ts index f5822dd80a655942e95f0df9bd3f25aad53797ea..8dfa8dab120db6d6aba03161a46ef34eb34e4d02 100644 --- a/src/i18n/translations/en.ts +++ b/src/i18n/translations/en.ts @@ -1,128 +1,130 @@ export const en = { - game: { - title: "Think in Sync", - round: "Round", - buildDescription: "Build a sentence together", - buildSubtitle: "Take turns adding words to create a sentence", - startSentence: "Start building your sentence...", - inputPlaceholder: "Enter a SINGLE word...", - addWord: "Add Word", - makeGuess: "Make Guess", - aiThinking: "AI is thinking...", - aiDelayed: "The AI is currently busy. Please try again in a moment.", - invalidWord: "Invalid Word", - cantUseTargetWord: "Do not use the secret word", - lettersOnly: "Please use letters only", - singleWordOnly: "Please enter only one word", - leaveGameTitle: "Leave Game?", - leaveGameDescription: "Your current progress will be lost. Are you sure you want to leave?", - cancel: "Cancel", - confirm: "Confirm", - describeWord: "Your goal is to describe the word", - nextRound: "Next Round", - playAgain: "Play Again", - saveScore: "Save Score" - }, - leaderboard: { - title: "High Scores", - yourScore: "Your Score", - roundCount: "rounds", - wordsPerRound: "words per round", - enterName: "Enter your name", - submitting: "Submitting...", - submit: "Submit Score", - rank: "Rank", - player: "Player", - roundsColumn: "Rounds", - avgWords: "Avg. Words", - noScores: "No scores yet", - previous: "Previous", - next: "Next", - success: "Score submitted successfully!", - error: { - invalidName: "Please enter a valid name", - noRounds: "You need to complete at least one round", - alreadySubmitted: "Score already submitted", - newHighScore: "New High Score!", - beatRecord: "You beat your previous record of {score}!", - notHigher: "Score of {current} not higher than your best of {best}", - submitError: "Error submitting score" - } + game: { + title: "Think in Sync", + round: "Round", + buildDescription: "Build a sentence together", + buildSubtitle: "Take turns adding words to create a sentence", + startSentence: "Start building your sentence...", + inputPlaceholder: "Enter a SINGLE word...", + addWord: "Add Word", + makeGuess: "Make Guess", + aiThinking: "AI is thinking...", + aiDelayed: "The AI is currently busy. Please try again in a moment.", + invalidWord: "Invalid Word", + cantUseTargetWord: "Do not use the secret word", + shorterWord: "Use a shorter word", + lettersOnly: "Please use letters only", + singleWordOnly: "Please enter only one word", + leaveGameTitle: "Leave Game?", + leaveGameDescription: "Your current progress will be lost. Are you sure you want to leave?", + cancel: "Cancel", + confirm: "Confirm", + describeWord: "Your goal is to describe the word", + nextRound: "Next Round", + playAgain: "Play Again", + saveScore: "Save Score" + }, + leaderboard: { + title: "High Scores", + yourScore: "Your Score", + roundCount: "rounds", + wordsPerRound: "words per round", + enterName: "Enter your name", + submitting: "Submitting...", + submit: "Submit Score", + rank: "Rank", + player: "Player", + roundsColumn: "Rounds", + avgWords: "Avg. Words", + noScores: "No scores yet", + previous: "Previous", + next: "Next", + success: "Score submitted successfully!", + theme: "Theme", + error: { + invalidName: "Please enter a valid name", + noRounds: "You need to complete at least one round", + alreadySubmitted: "Score already submitted", + newHighScore: "New High Score!", + beatRecord: "You beat your previous record of {score}!", + notHigher: "Score of {current} not higher than your best of {best}", + submitError: "Error submitting score" + } + }, + guess: { + title: "AI's Guess", + goalDescription: "Your goal was to describe the word", + providedDescription: "You provided the description", + aiGuessedDescription: "Based on your description, the AI guessed", + correct: "This is right!", + incorrect: "This is wrong.", + nextRound: "Next Round", + playAgain: "Play Again", + viewLeaderboard: "Save your score", + cheatingDetected: "Cheating detected!" + }, + themes: { + title: "Choose a Theme", + subtitle: "Select a theme for the word that the AI will try to guess", + standard: "Standard", + technology: "Technology", + sports: "Sports", + food: "Food", + custom: "Custom Theme", + customPlaceholder: "Enter your custom theme...", + continue: "Continue", + generating: "Generating...", + pressKey: "Press", + playing: "Theme" + }, + welcome: { + title: "Think in Sync", + subtitle: "Team up with AI to craft a clue and have a different AI guess your secret word!", + startButton: "Start Game", + howToPlay: "How to Play", + leaderboard: "Leaderboard", + credits: "Created during the", + likeGameText: "If you want to support this game", + contest: { + prize: "We are cooking something...", + terms: "Find out more", + howTo: "To get a head start:", + conditions: [ + "Play Think in Sync using the Standard wordlist", + "Set your leaderboard name to match your Hugging Face username", + "Like our project on Hugging Face" + ], + deadline: "We're gonna announce the details soon here", + prizes: { + title: "Compete for the top 5 spots and win:", + list: [ + "🥇 1st: 50€", + "🥈 2nd: 20€", + "🥉 3rd: 10€", + "🎖️ 4th & 5th: 10€ each" + ] + }, + fairPlay: "🚨 Fair play is monitored. Any cheating will result in disqualification!" }, - guess: { - title: "AI's Guess", - goalDescription: "Your goal was to describe the word", - providedDescription: "You provided the description", - aiGuessedDescription: "Based on your description, the AI guessed", - correct: "This is right!", - incorrect: "This is wrong.", - nextRound: "Next Round", - playAgain: "Play Again", - viewLeaderboard: "Save your score", - cheatingDetected: "Cheating detected!" + likeOnHuggingface: "Like on Hugging Face" + }, + howToPlay: { + setup: { + title: "Setup", + description: "Choose a theme and get a secret word that the AI will try to guess." }, - themes: { - title: "Choose a Theme", - subtitle: "Select a theme for the word that the AI will try to guess", - standard: "Standard", - technology: "Technology", - sports: "Sports", - food: "Food", - custom: "Custom Theme", - customPlaceholder: "Enter your custom theme...", - continue: "Continue", - generating: "Generating...", - pressKey: "Press", - playing: "Theme" + goal: { + title: "Goal", + description: "Build sentences together with the AI that describe your word without using it directly." }, - welcome: { - title: "Think in Sync", - subtitle: "Team up with AI to craft a clue and have a different AI guess your secret word!", - startButton: "Start Game", - howToPlay: "How to Play", - leaderboard: "Leaderboard", - credits: "Created during the", - likeGameText: "If you want to show you like this game, please", - contest: { - prize: "Play to win up to 50€!", - terms: "See Terms", - howTo: "How to participate:", - conditions: [ - "Play Think in Sync using the Standard wordlist", - "Set your leaderboard name to match your Hugging Face username", - "Like our project on Hugging Face" - ], - deadline: "Ends: February 5, 10:00 AM", - prizes: { - title: "Compete for the top 5 spots and win:", - list: [ - "🥇 1st: 50€", - "🥈 2nd: 20€", - "🥉 3rd: 10€", - "🎖️ 4th & 5th: 10€ each" - ] - }, - fairPlay: "🚨 Fair play is monitored. Any cheating will result in disqualification!" - }, - likeOnHuggingface: "Like on Hugging Face" - }, - howToPlay: { - setup: { - title: "Setup", - description: "Choose a theme and get a secret word that the AI will try to guess." - }, - goal: { - title: "Goal", - description: "Build sentences together with the AI that describe your word without using it directly." - }, - rules: { - title: "Rules", - items: [ - "Take turns adding words to build descriptive sentences", - "Don't use the secret word or its variations", - "Try to be creative and descriptive", - "The AI will try to guess your word after each sentence" - ] - } + rules: { + title: "Rules", + items: [ + "Take turns adding words to build descriptive sentences", + "Don't use the secret word or its variations", + "Try to be creative and descriptive", + "The AI will try to guess your word after each sentence" + ] } + } }; diff --git a/src/i18n/translations/es.ts b/src/i18n/translations/es.ts index d18eb49f8273e9f29c2bf2f12ea372a5099b81d6..7a5c284b598252da1314a30c799968e4ada43f58 100644 --- a/src/i18n/translations/es.ts +++ b/src/i18n/translations/es.ts @@ -1,128 +1,129 @@ export const es = { - game: { - title: "Think in Sync", - round: "Ronda", - buildDescription: "Construyan una frase juntos", - buildSubtitle: "Añadan palabras por turnos para crear una frase", - startSentence: "Empieza a construir tu frase...", - inputPlaceholder: "Ingresa UNA palabra...", - addWord: "Añadir palabra", - makeGuess: "Adivinar", - aiThinking: "La IA está pensando...", - aiDelayed: "La IA está ocupada en este momento. Por favor, inténtalo de nuevo en un momento.", - invalidWord: "Palabra inválida", - cantUseTargetWord: "No uses la palabra secreta", - lettersOnly: "Por favor, usa solo letras", - singleWordOnly: "Por favor, ingresa solo una palabra", - leaveGameTitle: "¿Salir del juego?", - leaveGameDescription: "Tu progreso actual se perderá. ¿Estás seguro de que quieres salir?", - cancel: "Cancelar", - confirm: "Confirmar", - describeWord: "Tu objetivo es describir la palabra", - nextRound: "Siguiente Ronda", - playAgain: "Jugar de Nuevo", - saveScore: "Guardar Puntuación" - }, - leaderboard: { - title: "Puntuaciones Más Altas", - yourScore: "Tu Puntuación", - roundCount: "rondas", - wordsPerRound: "palabras por ronda", - enterName: "Ingresa tu nombre", - submitting: "Enviando...", - submit: "Enviar Puntuación", - rank: "Posición", - player: "Jugador", - roundsColumn: "Rondas", - avgWords: "Prom. Palabras", - noScores: "Aún no hay puntuaciones", - previous: "Anterior", - next: "Siguiente", - success: "¡Puntuación enviada con éxito!", - error: { - invalidName: "Por favor, ingresa un nombre válido", - noRounds: "Debes completar al menos una ronda", - alreadySubmitted: "Puntuación ya enviada", - newHighScore: "¡Nueva Puntuación Más Alta!", - beatRecord: "¡Has superado tu récord anterior de {score}!", - notHigher: "Puntuación de {current} no superior a tu mejor de {best}", - submitError: "Error al enviar la puntuación" - } + game: { + title: "Think in Sync", + round: "Ronda", + buildDescription: "Construyan una frase juntos", + buildSubtitle: "Añadan palabras por turnos para crear una frase", + startSentence: "Empieza a construir tu frase...", + inputPlaceholder: "Ingresa UNA palabra...", + addWord: "Añadir palabra", + makeGuess: "Adivinar", + aiThinking: "La IA está pensando...", + aiDelayed: "La IA está ocupada en este momento. Por favor, inténtalo de nuevo en un momento.", + invalidWord: "Palabra inválida", + cantUseTargetWord: "No uses la palabra secreta", + lettersOnly: "Por favor, usa solo letras", + singleWordOnly: "Por favor, ingresa solo una palabra", + leaveGameTitle: "¿Salir del juego?", + leaveGameDescription: "Tu progreso actual se perderá. ¿Estás seguro de que quieres salir?", + cancel: "Cancelar", + confirm: "Confirmar", + describeWord: "Tu objetivo es describir la palabra", + nextRound: "Siguiente Ronda", + playAgain: "Jugar de Nuevo", + saveScore: "Guardar Puntuación" + }, + leaderboard: { + title: "Puntuaciones Más Altas", + yourScore: "Tu Puntuación", + roundCount: "rondas", + wordsPerRound: "palabras por ronda", + enterName: "Ingresa tu nombre", + submitting: "Enviando...", + submit: "Enviar Puntuación", + rank: "Posición", + player: "Jugador", + roundsColumn: "Rondas", + avgWords: "Prom. Palabras", + noScores: "Aún no hay puntuaciones", + previous: "Anterior", + next: "Siguiente", + success: "¡Puntuación enviada con éxito!", + theme: "Tema", + error: { + invalidName: "Por favor, ingresa un nombre válido", + noRounds: "Debes completar al menos una ronda", + alreadySubmitted: "Puntuación ya enviada", + newHighScore: "¡Nueva Puntuación Más Alta!", + beatRecord: "¡Has superado tu récord anterior de {score}!", + notHigher: "Puntuación de {current} no superior a tu mejor de {best}", + submitError: "Error al enviar la puntuación" + } + }, + guess: { + title: "Suposición de la IA", + goalDescription: "Tu objetivo era describir la palabra", + providedDescription: "Proporcionaste la descripción", + aiGuessedDescription: "Basado en tu descripción, la IA adivinó", + correct: "¡Esto es correcto!", + incorrect: "Esto es incorrecto.", + nextRound: "Siguiente Ronda", + playAgain: "Jugar de Nuevo", + viewLeaderboard: "Ver Clasificación", + cheatingDetected: "¡Trampa detectada!" + }, + themes: { + title: "Elige un Tema", + subtitle: "Selecciona un tema para la palabra que la IA intentará adivinar", + standard: "Estándar", + technology: "Tecnología", + sports: "Deportes", + food: "Comida", + custom: "Tema Personalizado", + customPlaceholder: "Ingresa tu tema personalizado...", + continue: "Continuar", + generating: "Generando...", + pressKey: "Presiona", + playing: "Tema" + }, + welcome: { + title: "Think in Sync", + subtitle: "¡Forma equipo con la IA para crear una pista y deja que otra IA adivine tu palabra secreta!", + startButton: "Comenzar juego", + howToPlay: "Cómo jugar", + leaderboard: "Clasificación", + credits: "Creado durante el", + likeGameText: "Si quieres apoyar este juego", + contest: { + prize: "Estamos cocinando algo...", + terms: "Descubre más", + howTo: "Para adelantarte a lo que planeamos:", + conditions: [ + "Juega Think in Sync usando la lista de palabras estándar", + "Establece tu nombre en la tabla de clasificación igual a tu nombre de usuario de Hugging Face", + "Dale me gusta a nuestro proyecto en Hugging Face" + ], + deadline: "Pronto anunciaremos los detalles aquí", + prizes: { + title: "Compite por los 5 primeros puestos y gana:", + list: [ + "🥇 1º: 50€", + "🥈 2º: 20€", + "🥉 3º: 10€", + "🎖️ 4º y 5º: 10€ cada uno" + ] + }, + fairPlay: "🚨 El juego limpio está monitoreado. ¡Cualquier trampa resultará en descalificación!" }, - guess: { - title: "Suposición de la IA", - goalDescription: "Tu objetivo era describir la palabra", - providedDescription: "Proporcionaste la descripción", - aiGuessedDescription: "Basado en tu descripción, la IA adivinó", - correct: "¡Esto es correcto!", - incorrect: "Esto es incorrecto.", - nextRound: "Siguiente Ronda", - playAgain: "Jugar de Nuevo", - viewLeaderboard: "Ver Clasificación", - cheatingDetected: "¡Trampa detectada!" + likeOnHuggingface: "Me gusta en Hugging Face" + }, + howToPlay: { + setup: { + title: "Preparación", + description: "Elige un tema y obtén una palabra secreta que la IA intentará adivinar." }, - themes: { - title: "Elige un Tema", - subtitle: "Selecciona un tema para la palabra que la IA intentará adivinar", - standard: "Estándar", - technology: "Tecnología", - sports: "Deportes", - food: "Comida", - custom: "Tema Personalizado", - customPlaceholder: "Ingresa tu tema personalizado...", - continue: "Continuar", - generating: "Generando...", - pressKey: "Presiona", - playing: "Tema" + goal: { + title: "Objetivo", + description: "Construye frases junto con la IA que describan tu palabra sin usarla directamente." }, - welcome: { - title: "Think in Sync", - subtitle: "¡Forma equipo con la IA para crear una pista y deja que otra IA adivine tu palabra secreta!", - startButton: "Comenzar juego", - howToPlay: "Cómo jugar", - leaderboard: "Tabla de clasificación", - credits: "Creado durante el", - likeGameText: "Si quieres mostrar que te gusta este juego,", - contest: { - prize: "¡Juega para ganar hasta 50€!", - terms: "Ver términos", - howTo: "Cómo participar:", - conditions: [ - "Juega Think in Sync usando la lista de palabras estándar", - "Establece tu nombre en la tabla de clasificación igual a tu nombre de usuario de Hugging Face", - "Dale me gusta a nuestro proyecto en Hugging Face" - ], - deadline: "Finaliza: 5 de febrero, 10:00 AM", - prizes: { - title: "Compite por los 5 primeros puestos y gana:", - list: [ - "🥇 1º: 50€", - "🥈 2º: 20€", - "🥉 3º: 10€", - "🎖️ 4º y 5º: 10€ cada uno" - ] - }, - fairPlay: "🚨 El juego limpio está monitoreado. ¡Cualquier trampa resultará en descalificación!" - }, - likeOnHuggingface: "Me gusta en Hugging Face" - }, - howToPlay: { - setup: { - title: "Preparación", - description: "Elige un tema y obtén una palabra secreta que la IA intentará adivinar." - }, - goal: { - title: "Objetivo", - description: "Construye frases junto con la IA que describan tu palabra sin usarla directamente." - }, - rules: { - title: "Reglas", - items: [ - "Añade palabras por turnos para construir frases descriptivas", - "No uses la palabra secreta o sus variaciones", - "Sé creativo y descriptivo", - "La IA intentará adivinar tu palabra después de cada frase" - ] - } + rules: { + title: "Reglas", + items: [ + "Añade palabras por turnos para construir frases descriptivas", + "No uses la palabra secreta o sus variaciones", + "Sé creativo y descriptivo", + "La IA intentará adivinar tu palabra después de cada frase" + ] } + } }; diff --git a/src/i18n/translations/fr.ts b/src/i18n/translations/fr.ts index 91f51da9a332fe5080a17065b4e18804c5641a26..7c69dca487005604e19fb4fa7b0e0cfacf97b7b8 100644 --- a/src/i18n/translations/fr.ts +++ b/src/i18n/translations/fr.ts @@ -1,127 +1,128 @@ export const fr = { - game: { - title: "Think in Sync", - round: "Tour", - buildDescription: "Construisez une phrase ensemble", - startSentence: "Commencez à construire votre phrase...", - inputPlaceholder: "Entrez UN mot...", - addWord: "Ajouter un mot", - makeGuess: "Deviner", - aiThinking: "L'IA réfléchit...", - aiDelayed: "L'IA est actuellement occupée. Veuillez réessayer dans un moment.", - invalidWord: "Mot invalide", - cantUseTargetWord: "N'utilisez pas le mot secret", - lettersOnly: "Veuillez utiliser uniquement des lettres", - singleWordOnly: "Veuillez entrer un seul mot", - leaveGameTitle: "Quitter le jeu ?", - leaveGameDescription: "Votre progression actuelle sera perdue. Êtes-vous sûr de vouloir quitter ?", - cancel: "Annuler", - confirm: "Confirmer", - describeWord: "Votre objectif est de décrire le mot", - nextRound: "Tour Suivant", - playAgain: "Rejouer", - saveScore: "Sauvegarder le Score" - }, - leaderboard: { - title: "Meilleurs Scores", - yourScore: "Votre Score", - roundCount: "tours", - wordsPerRound: "mots par tour", - enterName: "Entrez votre nom", - submitting: "Envoi en cours...", - submit: "Soumettre le Score", - rank: "Rang", - player: "Joueur", - roundsColumn: "Tours", - avgWords: "Moy. Mots", - noScores: "Pas encore de scores", - previous: "Précédent", - next: "Suivant", - success: "Score soumis avec succès !", - error: { - invalidName: "Veuillez entrer un nom valide", - noRounds: "Vous devez compléter au moins un tour", - alreadySubmitted: "Score déjà soumis", - newHighScore: "Nouveau Record !", - beatRecord: "Vous avez battu votre record précédent de {score} !", - notHigher: "Score de {current} pas plus élevé que votre meilleur de {best}", - submitError: "Erreur lors de la soumission du score" - } + game: { + title: "Think in Sync", + round: "Tour", + buildDescription: "Construisez une phrase ensemble", + startSentence: "Commencez à construire votre phrase...", + inputPlaceholder: "Entrez UN mot...", + addWord: "Ajouter un mot", + makeGuess: "Deviner", + aiThinking: "L'IA réfléchit...", + aiDelayed: "L'IA est actuellement occupée. Veuillez réessayer dans un moment.", + invalidWord: "Mot invalide", + cantUseTargetWord: "N'utilisez pas le mot secret", + lettersOnly: "Veuillez utiliser uniquement des lettres", + singleWordOnly: "Veuillez entrer un seul mot", + leaveGameTitle: "Quitter le jeu ?", + leaveGameDescription: "Votre progression actuelle sera perdue. Êtes-vous sûr de vouloir quitter ?", + cancel: "Annuler", + confirm: "Confirmer", + describeWord: "Votre objectif est de décrire le mot", + nextRound: "Tour Suivant", + playAgain: "Rejouer", + saveScore: "Sauvegarder le Score" + }, + leaderboard: { + title: "Meilleurs Scores", + yourScore: "Votre Score", + roundCount: "tours", + wordsPerRound: "mots par tour", + enterName: "Entrez votre nom", + submitting: "Envoi en cours...", + submit: "Soumettre le Score", + rank: "Rang", + player: "Joueur", + roundsColumn: "Tours", + avgWords: "Moy. Mots", + noScores: "Pas encore de scores", + previous: "Précédent", + next: "Suivant", + success: "Score soumis avec succès !", + theme: "Thème", + error: { + invalidName: "Veuillez entrer un nom valide", + noRounds: "Vous devez compléter au moins un tour", + alreadySubmitted: "Score déjà soumis", + newHighScore: "Nouveau Record !", + beatRecord: "Vous avez battu votre record précédent de {score} !", + notHigher: "Score de {current} pas plus élevé que votre meilleur de {best}", + submitError: "Erreur lors de la soumission du score" + } + }, + guess: { + title: "Devinette de l'IA", + goalDescription: "Votre objectif était de décrire le mot", + providedDescription: "Vous avez fourni la description", + aiGuessedDescription: "Basé sur votre description, l'IA a deviné", + correct: "C'est correct !", + incorrect: "C'est incorrect.", + nextRound: "Tour Suivant", + playAgain: "Rejouer", + viewLeaderboard: "Voir les Scores", + cheatingDetected: "Tentative de triche détectée !" + }, + themes: { + title: "Choisissez un Thème", + subtitle: "Sélectionnez un thème pour le mot que l'IA essaiera de deviner", + standard: "Standard", + technology: "Technologie", + sports: "Sports", + food: "Nourriture", + custom: "Thème Personnalisé", + customPlaceholder: "Entrez votre thème personnalisé...", + continue: "Continuer", + generating: "Génération...", + pressKey: "Appuyez sur", + playing: "Thème" + }, + welcome: { + title: "Think in Sync", + subtitle: "Faites équipe avec une IA pour créer un indice et laissez une autre IA deviner votre mot secret !", + startButton: "Commencer", + howToPlay: "Comment Jouer", + leaderboard: "Classement", + credits: "Créé pendant le", + likeGameText: "Si vous voulez soutenir ce jeu,", + contest: { + prize: "Nous préparons quelque chose...", + terms: "En savoir plus", + howTo: "Pour prendre de l'avance sur nos plans :", + conditions: [ + "Jouez à Think in Sync avec la liste de mots standard", + "Utilisez votre nom d'utilisateur Hugging Face dans le classement", + "Aimez notre projet sur Hugging Face" + ], + deadline: "Nous annoncerons bientôt les détails ici", + prizes: { + title: "Participez pour les 5 premières places et gagnez :", + list: [ + "🥇 1er : 50€", + "🥈 2ème : 20€", + "🥉 3ème : 10€", + "🎖️ 4ème & 5ème : 10€ chacun" + ] + }, + fairPlay: "🚨 Le fair-play est surveillé. Toute triche entraînera une disqualification !" }, - guess: { - title: "Devinette de l'IA", - goalDescription: "Votre objectif était de décrire le mot", - providedDescription: "Vous avez fourni la description", - aiGuessedDescription: "Basé sur votre description, l'IA a deviné", - correct: "C'est correct !", - incorrect: "C'est incorrect.", - nextRound: "Tour Suivant", - playAgain: "Rejouer", - viewLeaderboard: "Voir les Scores", - cheatingDetected: "Tentative de triche détectée !" + likeOnHuggingface: "Aimer sur Hugging Face" + }, + howToPlay: { + setup: { + title: "Mise en place", + description: "Choisissez un thème et obtenez un mot secret que l'IA essaiera de deviner." }, - themes: { - title: "Choisissez un Thème", - subtitle: "Sélectionnez un thème pour le mot que l'IA essaiera de deviner", - standard: "Standard", - technology: "Technologie", - sports: "Sports", - food: "Nourriture", - custom: "Thème Personnalisé", - customPlaceholder: "Entrez votre thème personnalisé...", - continue: "Continuer", - generating: "Génération...", - pressKey: "Appuyez sur", - playing: "Thème" + goal: { + title: "Objectif", + description: "Construisez des phrases avec l'IA qui décrivent votre mot sans l'utiliser directement." }, - welcome: { - title: "Think in Sync", - subtitle: "Faites équipe avec une IA pour créer un indice et laissez une autre IA deviner votre mot secret !", - startButton: "Commencer", - howToPlay: "Comment Jouer", - leaderboard: "Classement", - credits: "Créé pendant le", - likeGameText: "Si vous souhaitez montrer que vous aimez ce jeu,", - contest: { - prize: "Jouez pour gagner jusqu'à 50€ !", - terms: "Voir conditions", - howTo: "Comment participer :", - conditions: [ - "Jouez à Think in Sync avec la liste de mots standard", - "Utilisez votre nom d'utilisateur Hugging Face dans le classement", - "Aimez notre projet sur Hugging Face" - ], - deadline: "Fin : 5 février, 10h00", - prizes: { - title: "Participez pour les 5 premières places et gagnez :", - list: [ - "🥇 1er : 50€", - "🥈 2ème : 20€", - "🥉 3ème : 10€", - "🎖️ 4ème & 5ème : 10€ chacun" - ] - }, - fairPlay: "🚨 Le fair-play est surveillé. Toute triche entraînera une disqualification !" - }, - likeOnHuggingface: "Aimer sur Hugging Face" - }, - howToPlay: { - setup: { - title: "Mise en place", - description: "Choisissez un thème et obtenez un mot secret que l'IA essaiera de deviner." - }, - goal: { - title: "Objectif", - description: "Construisez des phrases avec l'IA qui décrivent votre mot sans l'utiliser directement." - }, - rules: { - title: "Règles", - items: [ - "Ajoutez des mots à tour de rôle pour construire des phrases descriptives", - "N'utilisez pas le mot secret ou ses variations", - "Soyez créatif et descriptif", - "L'IA essaiera de deviner votre mot après chaque phrase" - ] - } + rules: { + title: "Règles", + items: [ + "Ajoutez des mots à tour de rôle pour construire des phrases descriptives", + "N'utilisez pas le mot secret ou ses variations", + "Soyez créatif et descriptif", + "L'IA essaiera de deviner votre mot après chaque phrase" + ] } + } }; diff --git a/src/i18n/translations/it.ts b/src/i18n/translations/it.ts index 1ef432dcaf7d37a0150883830effd4dff5dd09a0..6056489320ee4b029137f57c752983535a509475 100644 --- a/src/i18n/translations/it.ts +++ b/src/i18n/translations/it.ts @@ -1,130 +1,131 @@ export const it = { - game: { - title: "Think in Sync", - round: "Turno", - buildDescription: "Costruite una frase insieme", - buildSubtitle: "Aggiungete parole a turno per creare una frase", - startSentence: "Inizia a costruire la tua frase...", - inputPlaceholder: "Inserisci UNA parola...", - addWord: "Aggiungi parola", - makeGuess: "Indovina", - aiThinking: "L'IA sta pensando...", - aiDelayed: "L'IA è attualmente occupata. Riprova tra un momento.", - invalidWord: "Parola non valida", - cantUseTargetWord: "Non usare la parola segreta", - lettersOnly: "Usa solo lettere", - singleWordOnly: "Inserisci una sola parola", - leaveGameTitle: "Lasciare il gioco?", - leaveGameDescription: "I tuoi progressi attuali andranno persi. Sei sicuro di voler uscire?", - cancel: "Annulla", - confirm: "Conferma", - describeWord: "Il tuo obiettivo è descrivere la parola", - nextRound: "Prossimo Turno", - playAgain: "Gioca Ancora", - saveScore: "Salva Punteggio" - }, - leaderboard: { - title: "Punteggi Migliori", - yourScore: "Il Tuo Punteggio", - roundCount: "turni", - wordsPerRound: "parole per turno", - enterName: "Inserisci il tuo nome", - submitting: "Invio in corso...", - submit: "Invia Punteggio", - rank: "Posizione", - player: "Giocatore", - roundsColumn: "Turni", - avgWords: "Media Parole", - noScores: "Ancora nessun punteggio", - previous: "Precedente", - next: "Successivo", - success: "Punteggio inviato con successo!", - error: { - invalidName: "Inserisci un nome valido", - noRounds: "Devi completare almeno un turno", - alreadySubmitted: "Punteggio già inviato", - newHighScore: "Nuovo Record!", - beatRecord: "Hai battuto il tuo record precedente di {score}!", - notHigher: "Punteggio di {current} non superiore al tuo migliore di {best}", - submitError: "Errore nell'invio del punteggio" - } + game: { + title: "Think in Sync", + round: "Turno", + buildDescription: "Costruite una frase insieme", + buildSubtitle: "Aggiungete parole a turno per creare una frase", + startSentence: "Inizia a costruire la tua frase...", + inputPlaceholder: "Inserisci UNA parola...", + addWord: "Aggiungi parola", + makeGuess: "Indovina", + aiThinking: "L'IA sta pensando...", + aiDelayed: "L'IA è attualmente occupata. Riprova tra un momento.", + invalidWord: "Parola non valida", + cantUseTargetWord: "Non usare la parola segreta", + lettersOnly: "Usa solo lettere", + singleWordOnly: "Inserisci una sola parola", + leaveGameTitle: "Lasciare il gioco?", + leaveGameDescription: "I tuoi progressi attuali andranno persi. Sei sicuro di voler uscire?", + cancel: "Annulla", + confirm: "Conferma", + describeWord: "Il tuo obiettivo è descrivere la parola", + nextRound: "Prossimo Turno", + playAgain: "Gioca Ancora", + saveScore: "Salva Punteggio" + }, + leaderboard: { + title: "Punteggi Migliori", + yourScore: "Il Tuo Punteggio", + roundCount: "turni", + wordsPerRound: "parole per turno", + enterName: "Inserisci il tuo nome", + submitting: "Invio in corso...", + submit: "Invia Punteggio", + rank: "Posizione", + player: "Giocatore", + roundsColumn: "Turni", + avgWords: "Media Parole", + noScores: "Ancora nessun punteggio", + previous: "Precedente", + next: "Successivo", + success: "Punteggio inviato con successo!", + theme: "Tema", + error: { + invalidName: "Inserisci un nome valido", + noRounds: "Devi completare almeno un turno", + alreadySubmitted: "Punteggio già inviato", + newHighScore: "Nuovo Record!", + beatRecord: "Hai battuto il tuo record precedente di {score}!", + notHigher: "Punteggio di {current} non superiore al tuo migliore di {best}", + submitError: "Errore nell'invio del punteggio" + } + }, + guess: { + title: "Ipotesi dell'IA", + sentence: "La tua frase", + aiGuessed: "L'IA ha indovinato", + goalDescription: "Il tuo obiettivo era descrivere la parola", + providedDescription: "Hai fornito la descrizione", + aiGuessedDescription: "Basandosi sulla tua descrizione, l'IA ha indovinato", + correct: "Corretto! L'IA ha indovinato la parola!", + incorrect: "Sbagliato. Riprova!", + nextRound: "Prossimo Turno", + playAgain: "Gioca Ancora", + viewLeaderboard: "Vedi Classifica", + cheatingDetected: "Tentativo di imbroglio rilevato!" + }, + themes: { + title: "Scegli un Tema", + subtitle: "Seleziona un tema per la parola che l'IA cercherà di indovinare", + standard: "Standard", + technology: "Tecnologia", + sports: "Sport", + food: "Cibo", + custom: "Tema Personalizzato", + customPlaceholder: "Inserisci il tuo tema personalizzato...", + continue: "Continua", + generating: "Generazione...", + pressKey: "Premi", + playing: "Tema" + }, + welcome: { + title: "Think in Sync", + subtitle: "Fai squadra con l'IA per creare un indizio e lascia che un'altra IA indovini la tua parola segreta!", + startButton: "Inizia gioco", + howToPlay: "Come giocare", + leaderboard: "Classifica", + credits: "Creato durante il", + likeGameText: "Se vuoi supportare questo gioco", + contest: { + prize: "Stiamo preparando qualcosa...", + terms: "Scopri di più", + howTo: "Per anticipare i nostri piani:", + conditions: [ + "Gioca a Think in Sync usando la lista di parole standard", + "Imposta il tuo nome in classifica uguale al tuo nome utente Hugging Face", + "Metti mi piace al nostro progetto su Hugging Face" + ], + deadline: "Annunceremo presto i dettagli qui", + prizes: { + title: "Competi per i primi 5 posti e vinci:", + list: [ + "🥇 1°: 50€", + "🥈 2°: 20€", + "🥉 3°: 10€", + "🎖️ 4° e 5°: 10€ ciascuno" + ] + }, + fairPlay: "🚨 Il fair play è monitorato. Qualsiasi imbroglio porterà alla squalifica!" }, - guess: { - title: "Ipotesi dell'IA", - sentence: "La tua frase", - aiGuessed: "L'IA ha indovinato", - goalDescription: "Il tuo obiettivo era descrivere la parola", - providedDescription: "Hai fornito la descrizione", - aiGuessedDescription: "Basandosi sulla tua descrizione, l'IA ha indovinato", - correct: "Corretto! L'IA ha indovinato la parola!", - incorrect: "Sbagliato. Riprova!", - nextRound: "Prossimo Turno", - playAgain: "Gioca Ancora", - viewLeaderboard: "Vedi Classifica", - cheatingDetected: "Tentativo di imbroglio rilevato!" + likeOnHuggingface: "Mi piace su Hugging Face" + }, + howToPlay: { + setup: { + title: "Preparazione", + description: "Scegli un tema e ottieni una parola segreta che l'IA cercherà di indovinare." }, - themes: { - title: "Scegli un Tema", - subtitle: "Seleziona un tema per la parola che l'IA cercherà di indovinare", - standard: "Standard", - technology: "Tecnologia", - sports: "Sport", - food: "Cibo", - custom: "Tema Personalizzato", - customPlaceholder: "Inserisci il tuo tema personalizzato...", - continue: "Continua", - generating: "Generazione...", - pressKey: "Premi", - playing: "Tema" + goal: { + title: "Obiettivo", + description: "Costruisci frasi insieme all'IA che descrivono la tua parola senza usarla direttamente." }, - welcome: { - title: "Think in Sync", - subtitle: "Fai squadra con l'IA per creare un indizio e lascia che un'altra IA indovini la tua parola segreta!", - startButton: "Inizia gioco", - howToPlay: "Come giocare", - leaderboard: "Classifica", - credits: "Creato durante il", - likeGameText: "Se vuoi mostrare che ti piace questo gioco,", - contest: { - prize: "Gioca per vincere fino a 50€!", - terms: "Vedi termini", - howTo: "Come partecipare:", - conditions: [ - "Gioca a Think in Sync usando la lista di parole standard", - "Imposta il tuo nome in classifica uguale al tuo nome utente Hugging Face", - "Metti mi piace al nostro progetto su Hugging Face" - ], - deadline: "Termina: 5 febbraio, 10:00", - prizes: { - title: "Competi per i primi 5 posti e vinci:", - list: [ - "🥇 1°: 50€", - "🥈 2°: 20€", - "🥉 3°: 10€", - "🎖️ 4° e 5°: 10€ ciascuno" - ] - }, - fairPlay: "🚨 Il fair play è monitorato. Qualsiasi imbroglio porterà alla squalifica!" - }, - likeOnHuggingface: "Mi piace su Hugging Face" - }, - howToPlay: { - setup: { - title: "Preparazione", - description: "Scegli un tema e ottieni una parola segreta che l'IA cercherà di indovinare." - }, - goal: { - title: "Obiettivo", - description: "Costruisci frasi insieme all'IA che descrivono la tua parola senza usarla direttamente." - }, - rules: { - title: "Regole", - items: [ - "Aggiungi parole a turno per costruire frasi descrittive", - "Non usare la parola segreta o le sue variazioni", - "Sii creativo e descrittivo", - "L'IA cercherà di indovinare la tua parola dopo ogni frase" - ] - } + rules: { + title: "Regole", + items: [ + "Aggiungi parole a turno per costruire frasi descrittive", + "Non usare la parola segreta o le sue variazioni", + "Sii creativo e descrittivo", + "L'IA cercherà di indovinare la tua parola dopo ogni frase" + ] } + } }; diff --git a/src/integrations/supabase/types.ts b/src/integrations/supabase/types.ts index b5cf4c7d571b833f2ca0b7d78cdc382e59a327ca..da53158f3f89a6cf3a2f9d66e9f640fdb20eb8b9 100644 --- a/src/integrations/supabase/types.ts +++ b/src/integrations/supabase/types.ts @@ -69,6 +69,27 @@ export type Database = { } Relationships: [] } + user_roles: { + Row: { + created_at: string + id: string + role: Database["public"]["Enums"]["app_role"] + user_id: string + } + Insert: { + created_at?: string + id?: string + role?: Database["public"]["Enums"]["app_role"] + user_id: string + } + Update: { + created_at?: string + id?: string + role?: Database["public"]["Enums"]["app_role"] + user_id?: string + } + Relationships: [] + } } Views: { [_ in never]: never @@ -84,9 +105,15 @@ export type Database = { } Returns: boolean } + is_admin: { + Args: { + user_id: string + } + Returns: boolean + } } Enums: { - [_ in never]: never + app_role: "admin" | "user" } CompositeTypes: { [_ in never]: never diff --git a/src/main.tsx b/src/main.tsx index 719464e3da4bc77d3adebed4b6c12d3327f5b89f..cd7084e04b68398a55e695584fc9851bc7549946 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,5 +1,10 @@ import { createRoot } from 'react-dom/client' import App from './App.tsx' import './index.css' +import { LanguageProvider } from './contexts/LanguageContext.tsx' -createRoot(document.getElementById("root")!).render(); +createRoot(document.getElementById("root")!).render( + + + +); \ No newline at end of file diff --git a/src/pages/admin/Index.tsx b/src/pages/admin/Index.tsx new file mode 100644 index 0000000000000000000000000000000000000000..9134cfa97fec1abc9a0a1578489c973de3c22eff --- /dev/null +++ b/src/pages/admin/Index.tsx @@ -0,0 +1,37 @@ +import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { supabase } from "@/integrations/supabase/client"; +import { useQuery } from "@tanstack/react-query"; +import { AdminHighScoresTable } from "@/components/admin/AdminHighScoresTable"; + +export const AdminIndex = () => { + const navigate = useNavigate(); + + useEffect(() => { + const checkAdmin = async () => { + const { data: { user } } = await supabase.auth.getUser(); + if (!user) { + navigate("/admin/login"); + return; + } + + const { data: isAdmin, error } = await supabase.rpc('is_admin', { + user_id: user.id + }); + + if (error || !isAdmin) { + console.error("Not an admin or error checking admin status:", error); + navigate("/admin/login"); + } + }; + + checkAdmin(); + }, [navigate]); + + return ( +
+

Admin Dashboard

+ +
+ ); +}; \ No newline at end of file diff --git a/src/pages/admin/Login.tsx b/src/pages/admin/Login.tsx new file mode 100644 index 0000000000000000000000000000000000000000..853d31cc5330d6941ca62e09782a96fdad30f095 --- /dev/null +++ b/src/pages/admin/Login.tsx @@ -0,0 +1,91 @@ +import { useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { supabase } from "@/integrations/supabase/client"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { useToast } from "@/components/ui/use-toast"; + +export const AdminLogin = () => { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [isLoading, setIsLoading] = useState(false); + const navigate = useNavigate(); + const { toast } = useToast(); + + const handleLogin = async (e: React.FormEvent) => { + e.preventDefault(); + setIsLoading(true); + + try { + const { data: { user }, error } = await supabase.auth.signInWithPassword({ + email, + password, + }); + + if (error) throw error; + + if (user) { + const { data: isAdmin, error: adminError } = await supabase.rpc('is_admin', { + user_id: user.id + }); + + if (adminError || !isAdmin) { + throw new Error("Not authorized as admin"); + } + + toast({ + title: "Login successful", + description: "Welcome to the admin area", + }); + + navigate("/admin"); + } + } catch (error) { + console.error("Login error:", error); + toast({ + title: "Login failed", + description: "Please check your credentials and try again", + variant: "destructive", + }); + } finally { + setIsLoading(false); + } + }; + + return ( +
+
+
+

Admin Login

+
+ +
+ setEmail(e.target.value)} + required + /> +
+
+ setPassword(e.target.value)} + required + /> +
+ + +
+
+ ); +}; \ No newline at end of file diff --git a/supabase/functions/guess-word/index.ts b/supabase/functions/guess-word/index.ts index f88e3dfb458771afc102864386f96aaec22b00a4..ee5dd407e618b59dbe03114a420c1aee1161b7ee 100644 --- a/supabase/functions/guess-word/index.ts +++ b/supabase/functions/guess-word/index.ts @@ -8,23 +8,23 @@ const corsHeaders = { const languagePrompts = { en: { - systemPrompt: "You are helping in a word guessing game. Given a description, guess what single word is being described.", + systemPrompt: "You are helping in a word guessing game. Given a description, guess what single word is being described. The described word itself was not allowed in the description, so do not expect it to appear.", instruction: "Based on this description" }, fr: { - systemPrompt: "Vous aidez dans un jeu de devinettes. À partir d'une description, devinez le mot unique qui est décrit.", + systemPrompt: "Vous aidez dans un jeu de devinettes. À partir d'une description, devinez le mot unique qui est décrit. Le mot décrit n'était pas autorisé dans la description, ne vous attendez donc pas à le voir apparaître.", instruction: "D'après cette description" }, de: { - systemPrompt: "Sie helfen bei einem Worträtsel. Erraten Sie anhand einer Beschreibung, welches einzelne Wort beschrieben wird.", + systemPrompt: "Sie helfen bei einem Worträtsel. Erraten Sie anhand einer Beschreibung, welches einzelne Wort beschrieben wird. Das beschriebene Wort durfte nicht in der Beschreibung verwendet werden, also erwarten Sie es nicht.", instruction: "Basierend auf dieser Beschreibung" }, it: { - systemPrompt: "Stai aiutando in un gioco di indovinelli. Data una descrizione, indovina quale singola parola viene descritta.", + systemPrompt: "Stai aiutando in un gioco di indovinelli. Data una descrizione, indovina quale singola parola viene descritta. La parola descritta non era permessa nella descrizione, quindi non aspettarti di trovarla.", instruction: "Basandoti su questa descrizione" }, es: { - systemPrompt: "Estás ayudando en un juego de adivinanzas. Dada una descripción, adivina qué palabra única se está describiendo.", + systemPrompt: "Estás ayudando en un juego de adivinanzas. Dada una descripción, adivina qué palabra única se está describiendo. La palabra descrita no estaba permitida en la descripción, así que no esperes verla.", instruction: "Basándote en esta descripción" } }; diff --git a/supabase/functions/submit-high-score/index.ts b/supabase/functions/submit-high-score/index.ts index 563b23cf7db061f6f0b2e7e0eaf073b148b2711e..b5b5c2c1e8bd462737a20ad0a9305a9741380241 100644 --- a/supabase/functions/submit-high-score/index.ts +++ b/supabase/functions/submit-high-score/index.ts @@ -27,7 +27,42 @@ Deno.serve(async (req) => { } ) - console.log('Submitting score:', { playerName, score, avgWordsPerRound, sessionId, theme }) + console.log('Verifying game results for session:', sessionId) + + // First verify that the claimed score matches actual game results + const { data: gameResults, error: gameError } = await supabaseClient + .from('game_results') + .select('is_correct') + .eq('session_id', sessionId) + + if (gameError) { + throw new Error('Failed to verify game results') + } + + // Count successful rounds + const successfulRounds = gameResults?.filter(result => result.is_correct).length ?? 0 + + console.log('Verified game results:', { + sessionId, + claimedScore: score, + actualSuccessfulRounds: successfulRounds + }) + + // Verify that claimed score matches actual successful rounds + if (score !== successfulRounds) { + return new Response( + JSON.stringify({ + error: 'Score verification failed', + message: 'Submitted score does not match game results' + }), + { + headers: { ...corsHeaders, 'Content-Type': 'application/json' }, + status: 400, + }, + ) + } + + console.log('Submitting verified score:', { playerName, score, avgWordsPerRound, sessionId, theme }) const { data, error } = await supabaseClient.rpc('check_and_update_high_score', { p_player_name: playerName,