-
Notifications
You must be signed in to change notification settings - Fork 0
Auth layout & UI update #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,9 +1,58 @@ | ||||||||||||||||||||||||||||||||
| import React from 'react' | ||||||||||||||||||||||||||||||||
| 'use client'; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const SignInPage = () => { | ||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||
| <div>SignInPage</div> | ||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| import { useForm } from 'react-hook-form'; | ||||||||||||||||||||||||||||||||
| import { Button } from '@/components/ui/button'; | ||||||||||||||||||||||||||||||||
| import InputField from '@/components/forms/InputField'; | ||||||||||||||||||||||||||||||||
| import FooterLink from '@/components/forms/FooterLink'; | ||||||||||||||||||||||||||||||||
| import {useRouter} from "next/navigation"; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| export default SignInPage | ||||||||||||||||||||||||||||||||
| const SignIn = () => { | ||||||||||||||||||||||||||||||||
| const router = useRouter() | ||||||||||||||||||||||||||||||||
| const { | ||||||||||||||||||||||||||||||||
| register, | ||||||||||||||||||||||||||||||||
| handleSubmit, | ||||||||||||||||||||||||||||||||
| formState: { errors, isSubmitting }, | ||||||||||||||||||||||||||||||||
| } = useForm<SignInFormData>({ | ||||||||||||||||||||||||||||||||
| defaultValues: { | ||||||||||||||||||||||||||||||||
| email: '', | ||||||||||||||||||||||||||||||||
| password: '', | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| mode: 'onBlur', | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||
| <h1 className="mt-12 lg:mt-24 mb-5 lg:mb-10 font-bold text-2xl">Welcome back</h1> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <form onSubmit={handleSubmit(onsubmit)} className="space-y-5"> | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: There is no 🐛 Suggested fix+ const onSubmit = async (data: SignInFormData) => {
+ try {
+ console.log(data)
+ // TODO: integrate sign-in (e.g., next-auth)
+ } catch (error) {
+ console.error('Error during sign in:', error)
+ }
+ };
+
return (
<>
<h1 className="mt-12 lg:mt-24 mb-5 lg:mb-10 font-bold text-2xl">Welcome back</h1>
- <form onSubmit={handleSubmit(onsubmit)} className="space-y-5">
+ <form onSubmit={handleSubmit(onSubmit)} className="space-y-5">📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
| <InputField | ||||||||||||||||||||||||||||||||
| name="email" | ||||||||||||||||||||||||||||||||
| label="Email" | ||||||||||||||||||||||||||||||||
| placeholder="contact@jsmastery.com" | ||||||||||||||||||||||||||||||||
| register={register} | ||||||||||||||||||||||||||||||||
| error={errors.email} | ||||||||||||||||||||||||||||||||
| validation={{ required: 'Email is required', pattern: /^\w+@\w+\.\w+$/ }} | ||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validation rules are missing
🛠️ Suggested fix- validation={{ required: 'Email is required', pattern: /^\w+@\w+\.\w+$/ }}
+ validation={{
+ required: 'Email is required',
+ pattern: { value: /^\S+@\S+\.\S+$/i, message: 'Invalid email address' },
+ }}
...
- validation={{ required: 'Password is required', minLength: 8 }}
+ validation={{
+ required: 'Password is required',
+ minLength: { value: 8, message: 'Password must be at least 8 characters' },
+ }}Also applies to: 46-46 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <InputField | ||||||||||||||||||||||||||||||||
| name="password" | ||||||||||||||||||||||||||||||||
| label="Password" | ||||||||||||||||||||||||||||||||
| placeholder="Enter your password" | ||||||||||||||||||||||||||||||||
| type="password" | ||||||||||||||||||||||||||||||||
| register={register} | ||||||||||||||||||||||||||||||||
| error={errors.password} | ||||||||||||||||||||||||||||||||
| validation={{ required: 'Password is required', minLength: 8 }} | ||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <Button type="submit" disabled={isSubmitting} className="yellow-btn w-full mt-5"> | ||||||||||||||||||||||||||||||||
| {isSubmitting ? 'Signing In' : 'Sign In'} | ||||||||||||||||||||||||||||||||
| </Button> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <FooterLink text="Don't have an account?" linkText="Create an account" href="/sign-up" /> | ||||||||||||||||||||||||||||||||
| </form> | ||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
| export default SignIn; | ||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,8 +1,85 @@ | ||||||||||||||||||||||||||||||||
| import React from 'react' | ||||||||||||||||||||||||||||||||
| "use client" | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| import {CountrySelectField} from '@/components/forms/CountrySelectField' | ||||||||||||||||||||||||||||||||
| import FooterLink from '@/components/forms/FooterLink' | ||||||||||||||||||||||||||||||||
| import InputField from '@/components/forms/InputField' | ||||||||||||||||||||||||||||||||
| import { Button } from '@/components/ui/button' | ||||||||||||||||||||||||||||||||
| import { useForm } from 'react-hook-form' | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const SignUpPage = () => { | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const { | ||||||||||||||||||||||||||||||||
| register, | ||||||||||||||||||||||||||||||||
| handleSubmit, | ||||||||||||||||||||||||||||||||
| control, | ||||||||||||||||||||||||||||||||
| formState: { errors, isSubmitting }, | ||||||||||||||||||||||||||||||||
| } = useForm<SignUpFormData>({ | ||||||||||||||||||||||||||||||||
| defaultValues: { | ||||||||||||||||||||||||||||||||
| fullName: '', | ||||||||||||||||||||||||||||||||
| email: '', | ||||||||||||||||||||||||||||||||
| password: '', | ||||||||||||||||||||||||||||||||
| country: 'MW', | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| mode: 'onBlur' | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||
|
Comment on lines
+16
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
| const onSubmit = async (data: SignUpFormData) => { | ||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||
| console.log(data) | ||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||
| console.error('Error during sign up:', error) | ||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||
|
Comment on lines
+26
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid logging the full submitted payload (it contains the user's password).
🛡️ Suggested fix- const onSubmit = async (data: SignUpFormData) => {
- try {
- console.log(data)
- } catch (error) {
- console.error('Error during sign up:', error)
- }}
+ const onSubmit = async (data: SignUpFormData) => {
+ try {
+ const { password: _pw, ...safe } = data;
+ console.log('sign-up submission', safe);
+ // TODO: integrate sign-up call
+ } catch (error) {
+ console.error('Error during sign up:', error);
+ }
+ };📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||
| <div>SignUpPage</div> | ||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||
| <h1 className='font-bold text-xl mb-4 mt-12 lg:mt-18'>Sign Up</h1> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <form onSubmit={handleSubmit(onSubmit)} className='space-y-5'> | ||||||||||||||||||||||||||||||||
| {/* INPUT */} | ||||||||||||||||||||||||||||||||
| <InputField | ||||||||||||||||||||||||||||||||
| name = 'fullName' | ||||||||||||||||||||||||||||||||
| label = 'Full Name' | ||||||||||||||||||||||||||||||||
| placeholder ="Jon Doe" | ||||||||||||||||||||||||||||||||
| register={register} | ||||||||||||||||||||||||||||||||
| error={errors.fullName} | ||||||||||||||||||||||||||||||||
| validation={{ required: 'Full name is required', minLength: 2 }} | ||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <InputField | ||||||||||||||||||||||||||||||||
| name = 'email' | ||||||||||||||||||||||||||||||||
| label = 'Email' | ||||||||||||||||||||||||||||||||
| placeholder ="contact@dali.com" | ||||||||||||||||||||||||||||||||
| register={register} | ||||||||||||||||||||||||||||||||
| error={errors.email} | ||||||||||||||||||||||||||||||||
| validation={{ required: 'Email is required', pattern: { value: /^\S+@\S+$/i, message: 'Invalid email address' } }} | ||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| {/* */} | ||||||||||||||||||||||||||||||||
| <CountrySelectField | ||||||||||||||||||||||||||||||||
| name="country" | ||||||||||||||||||||||||||||||||
| label="Country" | ||||||||||||||||||||||||||||||||
| control={control} | ||||||||||||||||||||||||||||||||
| error={errors.country} | ||||||||||||||||||||||||||||||||
| required | ||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <InputField | ||||||||||||||||||||||||||||||||
| name = 'password' | ||||||||||||||||||||||||||||||||
| label = 'Password' | ||||||||||||||||||||||||||||||||
| placeholder ="Enter a strong password" | ||||||||||||||||||||||||||||||||
| register={register} | ||||||||||||||||||||||||||||||||
| type='password' | ||||||||||||||||||||||||||||||||
| error={errors.password} | ||||||||||||||||||||||||||||||||
| validation={{ required: 'Password is required', minLength: 8 }} | ||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <Button type='submit' disabled={isSubmitting} className='yellow-btn w-full lg:mt-5'> | ||||||||||||||||||||||||||||||||
| {isSubmitting ? 'Creating Your Account' : 'Start Your Journaling Today'} | ||||||||||||||||||||||||||||||||
| </Button> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <FooterLink text='Already have an account?' linkText='Sign In' href='/sign-in' /> | ||||||||||||||||||||||||||||||||
| </form> | ||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -84,7 +84,7 @@ | |||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| .dark { | ||||||||||||||||||
| --background: oklch(0.09693 0.00001 271.152); | ||||||||||||||||||
| --background: oklch(0.145 0 0); | ||||||||||||||||||
| --foreground: oklch(0.985 0 0); | ||||||||||||||||||
| --card: oklch(0.205 0 0); | ||||||||||||||||||
| --card-foreground: oklch(0.985 0 0); | ||||||||||||||||||
|
|
@@ -145,6 +145,28 @@ | |||||||||||||||||
| @apply bg-background text-foreground; | ||||||||||||||||||
| } | ||||||||||||||||||
| html { | ||||||||||||||||||
| @apply font-sans; | ||||||||||||||||||
| @apply font-sans; | ||||||||||||||||||
| scroll-behavior: smooth; | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| @layer components { | ||||||||||||||||||
| .card-hover { | ||||||||||||||||||
| transition: box-shadow 0.3s ease; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| .card-hover:hover { | ||||||||||||||||||
| box-shadow: 0 0 30px rgba(253, 212, 88, 0.3); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| @layer utilities { | ||||||||||||||||||
| .form-input { | ||||||||||||||||||
| @apply h-12 lg:w-[450px] px-2 py-2 text-white text-base placeholder:text-gray-500 border-gray-600 bg-gray-800 rounded-lg focus:!border-yellow-500 focus:ring-0; | ||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+165
to
+168
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, check if the file exists and read the relevant lines
if [ -f "app/globals.css" ]; then
echo "=== Lines 165-168 of app/globals.css ==="
sed -n '165,168p' app/globals.css
echo ""
echo "=== Context around those lines (160-175) ==="
sed -n '160,175p' app/globals.css
else
echo "File app/globals.css not found"
find . -name "globals.css" -type f
fiRepository: Dali11/JournalFX Length of output: 737 🏁 Script executed: # Check Tailwind version in package.json
if [ -f "package.json" ]; then
echo "=== Tailwind version from package.json ==="
grep -A 2 -B 2 "tailwindcss" package.json
fiRepository: Dali11/JournalFX Length of output: 329 🏁 Script executed: # Search for focus:! patterns in CSS files to see if this is a widespread issue
echo "=== Searching for focus:! patterns in CSS ==="
rg 'focus:!' --type cssRepository: Dali11/JournalFX Length of output: 286 🌐 Web query:
💡 Result: In Tailwind CSS v4, the important modifier (!) is placed at the end of the utility class name, after any variants. For example, use bg-red-500! instead of the v3 prefix syntax !bg-red-500. With variants, it remains at the end: hover:bg-red-500!. The prefix syntax is deprecated but supported for backward compatibility. Tailwind's upgrade guide explicitly states this change, and official GitHub discussions from Tailwind team members (including collaborators) confirm the postfix syntax is the new standard for consistency, especially with variants like hover:!bg-red-500 becoming hover:bg-red-500!. Citations:
🌐 Web query:
💡 Result: Tailwind CSS v4 introduces breaking changes to the prefix, important modifier, and related syntax like focus:!. Prefix: No longer a simple string prefix like "tw-" appended to classes (e.g., tw-bg-red-500). Now configured via Citations:
Tailwind v4 breaking change:
♻️ Proposed fix .form-input {
- `@apply` h-12 lg:w-[450px] px-2 py-2 text-white text-base placeholder:text-gray-500 border-gray-600 bg-gray-800 rounded-lg focus:!border-yellow-500 focus:ring-0;
+ `@apply` h-12 lg:w-[450px] px-2 py-2 text-white text-base placeholder:text-gray-500 border-gray-600 bg-gray-800 rounded-lg focus:border-yellow-500! focus:ring-0;
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| .yellow-btn { | ||||||||||||||||||
| @apply inline-flex bg-yellow-500 text-gray-900 font-medium px-8 py-5 rounded-lg cursor-pointer hover:bg-yellow-600 transition-colors duration-300 ; | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { HOME_CARDS } from "@/lib/constants" | ||
| import Image from 'next/image' | ||
|
|
||
| const About = () => { | ||
| return ( | ||
| <main className="sm:mt-24 mt-12 mx-2 lg:mx-0"> | ||
| <section className="flex flex-col gap-2"> | ||
| <h1 className="text-4xl font-bold text-center">Everything You Need to Trade Smarter</h1> | ||
| <p className="text-center text-gray-500">Our comprehensive trading journal gives you all the tools to improve your trading results</p> | ||
| </section> | ||
|
|
||
| {/* CARDS */} | ||
|
|
||
| <section className="mt-8"> | ||
| <ul className="flex flex-col sm:flex-row gap-2 lg:gap-4"> | ||
| {HOME_CARDS.map(({image, title, text}) => ( | ||
| <li key={title} className="card-hover flex flex-col gap-3 bg-gray-700 border border-gray-600 text-white p-4 lg:p-6 rounded-xl cursor-poiter shadow-lg shadow-black/50 flex-1"> | ||
| <div className="bg-yellow-600 p-2 rounded-lg w-fit"> | ||
| <Image src={image} alt={title} width={28} height={28} /> | ||
| </div> | ||
| <h2 className="font-bold text-lg text-white min-h-[56px]">{title}</h2> | ||
| <p className="text-gray-400 text-sm leading-relaxed pb-4">{text}</p> | ||
| </li> | ||
| ))} | ||
| </ul> | ||
| </section> | ||
| </main> | ||
| ) | ||
| } | ||
|
|
||
| export default About |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import { ArrowRight } from "lucide-react" | ||
| import Link from "next/link" | ||
|
|
||
|
|
||
| const ContactUs = () => { | ||
| return ( | ||
| <div className=" flex flex-col justify-center items-center gap-10 text-white mx-2 lg:mx-0 mt-8 sm:mt-24 text-center"> | ||
| <div className="content"> | ||
| <h1 className="font-bold text-4xl">Start Journaling Your Trade Today</h1> | ||
| <p className="text-center mt-3 text-gray-500 sm:w-150">Join thousands of trades who are already improving their results with JournalFX. Create your free account and take controlof your tradiing journey.</p> | ||
| </div> | ||
|
|
||
| <div className="mb-10"> | ||
| <Link href="/sign-in" className='group flex justify-center bg-yellow-500 font-bold text-black p-2 px-10 sm:px-10 rounded-md cursor-pointer'> | ||
| Create Free Account | ||
| <ArrowRight className="ml-1 transition-transform duration-300 group-hover:translate-x-1"/> | ||
| </Link> | ||
|
|
||
| <p className="text-gray-500 text-sm mt-2"> | ||
| No credit card required. Free forever for basic features. | ||
| </p> | ||
| </div> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| export default ContactUs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: Dali11/JournalFX
Length of output: 103
Logo
srcis missing the leading/—next/imagerequires a root-relative path for static public assets."asset/images/logo.svg"is interpreted as relative to the current route, causing it to resolve to/sign-in/asset/images/logo.svgon the/sign-inpage and fail with a 404. Thenext/imagecomponent enforces absolute paths for static public assets.🐛 Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents