Full Cycle Next.js App
View Live Project
- Game Search
- Game Information
- Resource Submission
- Submission Voting
- Submission Reporting
- Submission Moderation
- Admin Dashboard
- Auth & RBAC
- Theme toggle
Users can search for and access game pages, which also contain user-submitted resources.
- Users can use the search bar or direct URL to access game pages.
- Game information is retrieved from IGDB's API according to tailored request body.
- For the search function, matching games are displayed as a list.
- For the game page, information for the matching game slug is displayed on the page.
- Additionally, all user submitted resources matching the game ID are retrieved from the database then displayed accordingly.
Users can submit resources for each game page and section
- Clicking [+] ADD unrolls a submission form.
- Title, URL and Description can be filled in then submitted.
- Upon submission, it will be added to the database if it passes the following checks:
- User is authorized.
- User is not rate limited.
- Form input passes validation.
- revalidatePath() to refresh from the server action.
Users can vote on submissions: Upvote, downvote, cancel vote.
- If the user is logged in, their current vote for each submission is loaded and displayed.
- The user can add a new vote, change their vote or cancel their vote by clicking the arrows.
- Votes are checked against auth, ratelimit and validation.
- After passing those checks, the following occurs:
- Check for existence of submission and current vote.
- Add vote if there is no prior vote.
- If existing vote is the same, delete the vote.
- If existing vote is different, modify the vote.
- Adjust the submission's score as a transaction to reflect vote.
Users can submit reports against submissions they believe break the platform's rules.
- Clicking the caution button will open a report form modal.
- Information on the submission to be reported is displayed along with the form.
- The user can select a report reason option, along with an optional "Additional Information" field.
- Upon confirmation, the report will be added to the database if it passes the following checks:
- User is authorized.
- User is not rate limited.
- Form input passes validation.
- User has not already reported the submission.
From there, the report will be marked as "pending" and visible on the administrator dashboard.
Pending reports are displayed in the administrator dashboard along with all necessary information. Administrators can choose to "Approve" or "Deny" these reports.
Upon approval (and passing Auth+RBAC & validation checks), the following occurs as a transaction:
- Verification that the report still exists, and still in "pending" status.
- On success, soft-delete the submission with sql
now()
at deleted_at. - Update the current report's status to "approved".
- Finally, set all other reports' status against the submission to "collateral". This indicates that these reports were batch-accepted due to the acceptance of another repord, which avoids possible confusion if:
- All accepted: You lose context on responsible report - non-sensical reports would also get accepted.
- All denied: Sensical reports marked as denied.
- All deleted: You lose historical statistical tracking for reports submitted.
- As such, the best option I found was to introduce a new status type called "collateral".
- revalidatePath() to refresh from the server action.
Upon denial (and passing Auth+RBAC & validation checks), the following occurs as a transaction:
- Verification that the report still exists, and still in "pending" status.
- On success, update the current report's status to "denied".
- revalidatePath() to refresh from server action.
- Based on T3 Stack
- Next.js 15.0.0-rc.0
- React 19.0.0-rc-19bd26be-20240815
- TypeScript 5.5.3
- Drizzle (PostgreSQL)
- Clerk (Auth)
- Upstash (Ratelimit)
- Zod 3.23.8 (Validation)
- Next-themes (Trigger)
- Sonner
- Vercel Hosting
- Cyberpunk 2077 (Inspiration for UI design)
MGSimard - [email protected]
@MGSimard on X
For more info, view my portfolio at mgsimard.github.io. Resume attached.
- Feature planning
- Establish design guidelines
- Build mock layouts for index & game pages
- Create placeholder images for card and thumbnail (When unavailable)
- Make a decision on DB seeding (No)
- Create api/search?query= endpoint
- Create api/gamedata?query= endpoint
- Set up request bodies
- Build searchbar component
- Move searchbar to nav while in game page
- Plug searchbar into search API
- Make searchbar expand on click to show ~max 10 matching results
- Make a submit searchbar query button
- Make a clear searchbar query button
- Skeleton loading component for game page
- Add websites to game page button links
- Migrate to T3 Stack
- Deploy to vercel for testing, add env variables
- Start setting up database
- Create DB for submissions, scoring & voter tracking
- Implement auth
- Fix grid blowout when long word
- Rework submission cards, need better visual separation
- Implement item submission functionality (links in cards) (server actions)
- Conditionally ignore currentUser in query if currentUser is null (don't need to get initialVotes)
- Use currentuser initial vote match to conditionally render active arrow color or something
- USE RETURNING UPDATE TO GET BACK INSTEAD OF DOING ANOTHER QUERY
- Limit character input within the actual fields themselves
- Implement voting functionality (server actions) https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#server-side-form-validation
- Think about potentially adding current character count above inputs
- On submission add an upvote from the submitter (somehow avoid triggering trigger - unless I start posts at 0pts)
- Fix submission highlighting on hover being larger than the actual click zone
- Introduce rate-limiting for both submissions and votes
- Maybe make submissions single cards like equipped gun design do the notch
- Add visual link for submissions so users don't have to hover or click to tell if it's a good link
- Error handling
- Collapse "add submission" section back into "Add" after successful submit
- Show top 8 submissions, see all shows all of them
- Find Steam svg icon outline for steam button
- Light mode
- Implement admin dashboard
- Find some stuff to show on admin dashboard
- Implement Moderation (Report abuse, receive reports in admin dashboard)
- Total Submissions stat
- Total Votes stat
- Total Reports/Accepted/Denied stat
- Add the actual report function (button next to each submission)
- Show standing reports in reports card under
- Edit initialRss to only include null deletedAt
- Edit voting to only allow voting on null deletedAt
- Edit report to utilize formData action
- Build report form
- CREATE MODAL FOR REPORT FORM
- Spend time ordering all my imports by hierarchy
- Touch up my types into interfaces to avoid the annoying linebreaks
- Style form
- Maybe display info on what they're reporting so they don't have to refresh their mind after clicking report
- Make report form action send data properly to server action
- Approve report done, do deny report next
- Fix column order in db for report table
- Close modal on ESC or clicking backdrop?
- Make up mind regarding list of report reasons
- Edit report to only allow voting on null deletedAt
- Style pending report items
- Look into submissions clearing the text field, but the charcount above not getting affected by onChange (guess deletion on submission doesn't trigger onChange)
- Maybe look into toasts for refreshed type alerts like admin moderation or error on ratelimit
- Replace error returns for error throws into error toasts() for SUBMISSIONS, VOTING and MODERATION
- Rework errors overall across the board with one specific return format
- Finish styling the custom toast component
- On opening form scroll to its anchor
- Change word-wrap behaviour to prioritize words for headings
- Remove "any" everywhere, make typescript happy to pass build without config cheatcode
- Rework returns across entire app
- Make decision on displayed storefront links
- Finalize websites
- Fix report button not appearing on see all details
- Maybe make button styles like gun button design
- Metadata
- Accessibility concerns for aria and button NAMING - run lighthouse
- Look for potential ideas regarding sanitizing links against malicious attempts or adult content etc