Conversation
src/App.jsx
Outdated
| event.preventDefault() | ||
|
|
||
| if (!newMessage.trim()) return | ||
| if (newMessage.length < 5 || newMessage.length > 140) return |
There was a problem hiding this comment.
I'm not sure, but it looks to me that user won't get any feedback from the app here if he is trying to send an empty, too short or too long message? That might be a bit confusing to the user, so maybe would be good to return some kind of feedback or error here?
There was a problem hiding this comment.
Good observation! The user does get feedback, the character counter turns red and shows error text, plus the submit button is disabled when invalid. But you're right, making it more obvious could improve UX! 👍
src/App.jsx
Outdated
| // Function to like a thought (UPDATE in Supabase) | ||
| const handleLikeThought = async (thoughtId) => { | ||
| // Find current hearts count | ||
| const thought = thoughts.find(t => t.id === thoughtId) |
There was a problem hiding this comment.
I don't really understand this part, but it's probably because you use your own backend? Anyway, I would love to learn the reasoning behind it!
There was a problem hiding this comment.
Good question! The original Technigo API had a dedicated /thoughts/:id/like endpoint that automatically incremented the hearts count on the server.
Since I built my own backend with Supabase, I'm using a simple database table with just UPDATE operations. So I need to first Find the current hearts count from local state then add 1 to it then send the new value to Supabase
An alternative would be to use Supabase's RPC (Remote Procedure Call) to increment on the server it wasn't easy so i used this easier simpler approach which works just fine for this project! 😊
src/components/ThoughtCard.jsx
Outdated
| return `${days} days ago` | ||
| } | ||
|
|
||
| export const ThoughtCard = ({ id, message, hearts, createdAt, onLike }) => { |
There was a problem hiding this comment.
Good usage of named attributes instead of just props here! Keep it up:)
src/components/ThoughtCard.jsx
Outdated
| <HeartButton | ||
| onClick={() => onLike(id)} | ||
| $isLiked={isLiked} | ||
| aria-label={`Like this thought, currently ${hearts} likes`} |
There was a problem hiding this comment.
Really great that you added aria-label here, way to go!
src/components/ThoughtForm.jsx
Outdated
| /> | ||
| <CharacterCount $count={charCount} aria-live="polite"> | ||
| {charCount}/140 | ||
| {charCount < 5 && charCount > 0 && ' (min 5 characters)'} |
There was a problem hiding this comment.
Great user experience here with the feedback to users and not letting them press the button!
There was a problem hiding this comment.
Thank you! You always have a good eye for details 😊👍
src/supabase.js
Outdated
| import { createClient } from '@supabase/supabase-js' | ||
|
|
||
| const supabaseUrl = 'https://qoxtdfojwnokjnmuwazc.supabase.co' | ||
| const supabaseKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InFveHRkZm9qd25va2pubXV3YXpjIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjU2MDM3ODUsImV4cCI6MjA4MTE3OTc4NX0.BrH7Sj5ALhX8ka2ZwUKEA--ey3gKtYImZjpI3i2a4wc' |
There was a problem hiding this comment.
I'm not sure it is a good idea to leave the key open here? But it's beyond the code point anyway:)
There was a problem hiding this comment.
Good point! But this anon key is safe to expose. It's designed for frontend use. Supabase protects the database with Row Level Security (RLS) policies, so this key can only read/write what I explicitly allow.
There was a problem hiding this comment.
There are updates to the keys that one get from Supabase, check out the transition over to publishable and secret keys from anon and service_role keys here: https://github.com/orgs/supabase/discussions/29260 :)
src/components/ThoughtForm.jsx
Outdated
| margin: 8px 0 0 0; | ||
| color: ${props => { | ||
| if (props.$count < 5) return '#e74c3c' | ||
| if (props.$count > 140) return '#e74c3c' |
There was a problem hiding this comment.
Try keeping reused numbers like this in one place as constants. That way it's a lot easier to change!
There was a problem hiding this comment.
Thanks ! I updated the code and put the repeated numbers (5, 140, 120) as constants at the top of the file. Now it's much easier if I want to change the limits - I just update one place instead of searching everywhere.
|
Good work! Nice solution with the disabled state an that you set up your own supabase to handle the api. But it's not working and I receive errors. |
|
Hi! Thanks for taking the time to review my code and for the helpful feedback! 😊 You're absolutely right. I checked my Supabase project and it was indeed "sleeping" due to inactivity. I visited the dashboard and the REST endpoint to wake it up, and now everything is working smoothly! I also read through the GitHub discussion you shared about the upcoming API key changes. Just to clarify - that discussion is about a future migration from legacy JWT keys to the new sb_publishable_ / sb_secret_ format, which won't be required until late 2026. My current issue was simply that free-tier Supabase projects pause after a week of inactivity, not related to the API key migration. Regarding localStorage I've added localStorage to track liked thoughts. Now when you like a thought, it saves to localStorage, persists after refresh, and prevents duplicate likes. Also refactored the hardcoded numbers (5, 140, 120) into constants as suggested! Everything's working now! Should I push these updates in a new commit? |
|
Thank you for waking it up, it works fine now! https://supabase.com/docs/guides/api/api-keys
Yes, please push the new changes :) |
|
Thanks! I’m starting to understand it better now. that’s a really good point about the new keys. 😊 |
Live Demo
The original Technigo API was down (503 Service Unavailable) during development, so I built my own backend using Supabase.