Skip to content
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

Lucasbentoskl/eng 238 feature profile page #206

Open
wants to merge 31 commits into
base: staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9d8cee4
merge
Lucas-Bento-D Dec 26, 2024
ca9ff5a
feat: add verification with server side
Lucas-Bento-D Dec 13, 2024
76724a9
refactor: improvment on types
Lucas-Bento-D Dec 13, 2024
37da341
Refactor: structure captcha
Lucas-Bento-D Dec 13, 2024
fa8505c
merge
Lucas-Bento-D Dec 26, 2024
f4c30e3
Merge branch 'detrash:staging' into staging
Lucas-Bento-D Dec 26, 2024
de4e416
Style: improvement style on profile settings
Lucas-Bento-D Dec 28, 2024
97f08c4
Feature: add radioBox component
Lucas-Bento-D Dec 30, 2024
bf7341f
feature: add correct types
Lucas-Bento-D Dec 30, 2024
9aa51d1
Feature: add success, focus and error styles on inputs
Lucas-Bento-D Dec 30, 2024
6a99976
feature: add styles for inputs
Lucas-Bento-D Dec 30, 2024
b6b4456
feature: styles for radiobox check
Lucas-Bento-D Dec 30, 2024
cb43dc7
Style: improvement style on profile settings
Lucas-Bento-D Dec 28, 2024
81adb75
Feature: add radioBox component
Lucas-Bento-D Dec 30, 2024
5d0af9a
feature: add correct types
Lucas-Bento-D Dec 30, 2024
127301c
Feature: add success, focus and error styles on inputs
Lucas-Bento-D Dec 30, 2024
54e9d27
feature: add styles for inputs
Lucas-Bento-D Dec 30, 2024
85eeba4
feature: styles for radiobox check
Lucas-Bento-D Dec 30, 2024
6a151f7
feat; create audit and report modals
yurimutti Dec 28, 2024
25fbd1a
feat: add status on audits
yurimutti Dec 29, 2024
12e0338
feat: create onboarding modal
yurimutti Dec 30, 2024
6a9079a
feat: add roles and remove hradcoded ids
yurimutti Jan 1, 2025
1349875
feat: remove cors validate
yurimutti Jan 2, 2025
0ae0642
Feature: add radioBox component
Lucas-Bento-D Dec 30, 2024
232e952
Refactor: remove unnecessary import
Lucas-Bento-D Jan 2, 2025
aff4ac2
merge
Lucas-Bento-D Jan 2, 2025
3817400
Merge pull request #207 from detrash/staging
yurimutti Jan 2, 2025
eba5615
Feat: change radiobox struct
Lucas-Bento-D Jan 7, 2025
3bdc83b
Merge branch 'detrash:main' into lucasbentoskl/eng-238-feature-profil…
Lucas-Bento-D Jan 8, 2025
d09a434
Merge branch 'staging' into lucasbentoskl/eng-238-feature-profile-page
Lucas-Bento-D Jan 8, 2025
8dad8b5
Feat: add options on zod type
Lucas-Bento-D Jan 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 13 additions & 15 deletions apps/web-mobile/src/components/ui/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,19 @@ import { cn } from '@/utils/cn';

export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}

const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
ref={ref}
{...props}
/>
);
},
);
const Input = React.forwardRef<HTMLInputElement, InputProps>(({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
'border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-10 w-full rounded-md border px-3 py-2 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}
{...props}
/>
);
});
Input.displayName = 'Input';

export { Input };
42 changes: 42 additions & 0 deletions apps/web-mobile/src/components/ui/radioBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Label } from '@/components/ui/label';

import { Card, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';

type cssmapType = {
[id: string]: string;
};
const cssmap: cssmapType = {
'option-hodler': 'option-hodler',
'option-recycler': 'option-recycler',
'option-waste': 'option-waste',
};
Comment on lines +10 to +14
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, we will keep the component pure without rules (recycler etc)

https://ui.shadcn.com/docs/components/radio-group

interface Props {
beforeText?: string;
id: string;
name: string;
}
export const RadioBox = ({ beforeText, id, name }: Props) => {
return (
<>
<FormItem key={`${id}-box`}>
<FormLabel className="[&:has([data-state=checked])>div]:border-primary [&:has([data-state=checked])>div>.checked-box-symbol]:block">
<FormControl>
<RadioGroupItem value={id} className="sr-only" />
</FormControl>
<Card className="hover:border-primary [&:has([data-state=checked])]:border-primary relative flex h-28 cursor-pointer flex-col justify-center border-2 p-4 transition-colors duration-200 ease-in-out">
<div className="p0">
{/* <Icon icon={role.icon} className="text-primary mx-auto h-12 w-12" /> */}
{beforeText && <span className="">{beforeText}</span>}
<CardTitle className="mt-px pr-6 text-left text-base font-bold">{name}</CardTitle>
</div>
<span className="checked-box-symbol absolute right-6 top-6 hidden h-5 w-5 rounded-full bg-blue-500 text-center text-sm text-white [&:has([data-state=checked])]:block">
&#x2713;
</span>
</Card>
</FormLabel>
</FormItem>
</>
);
};
2 changes: 0 additions & 2 deletions apps/web-mobile/src/layouts/header/menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ export function Menu() {
const isAuditsRoute = item.route === ROUTES.PRIVATE.AUDITS();
const isUnauthorized = !hasAuditorRole && !hasAdminPrivileges;

console.log('user', user);

if (isAuditsRoute && isUnauthorized) return null;

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Separator } from '@/components/ui/separator';
import { toast } from '@/components/ui/use-toast';
import { Turnstile } from '@marsidev/react-turnstile';
import { useState } from 'react';
import { RadioBox } from '@/components/ui/radioBox';
import { useAuth } from '@/hooks/auth';

const profileFormSchema = z.object({
Expand All @@ -33,10 +34,21 @@ const profileFormSchema = z.object({
.max(30, {
message: 'Username must not be longer than 30 characters.',
}),
role: z.string().min(1, 'You must select a role to display.'),
});

type ProfileFormValues = z.infer<typeof profileFormSchema>;

type cssmapType = {
[id: string]: string;
};

const cssmap: cssmapType = {
'option-hodler-box': 'option-hodler-box',
'option-recycler-box': 'option-recycler-box',
'option-waste-box': 'option-waste-box',
};

export default function ProfileForm() {
const { user } = useAuth();
const [turnstileToken, setTurnstileToken] = useState<string>();
Expand All @@ -47,7 +59,8 @@ export default function ProfileForm() {
resolver: zodResolver(profileFormSchema),
});

function onSubmit(data: ProfileFormValues) {
function onSubmit(data: any) {
console.log({ data });
toast({
description: (
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
Expand All @@ -60,22 +73,31 @@ export default function ProfileForm() {

return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<div className="flex flex-col gap-2">
<h2 className="text-base">Basic Info</h2>
<h2 className="text-base font-bold uppercase">Basic Info:</h2>
<Separator />
</div>

<div className="flex flex-col gap-4">
<div className="grid grid-cols-6 gap-3">
<div className="grid grid-cols-6 gap-3 max-md:grid-cols-2">
<FormField
control={form.control}
name="preferred_name"
render={({ field }) => (
<FormItem>
<FormLabel>Preferred Name</FormLabel>
<FormLabel>
Preferred Name
<span className="text-base font-extrabold text-red-600"> *</span>
</FormLabel>
<FormControl>
<Input {...field} />
<Input
{...field}
className="empty:border-input border invalid:border-red-500 focus-visible:border-blue-500 focus-visible:ring-0 focus-visible:ring-offset-0 [&:not(:placeholder-shown)(:invalid)]:valid:border-green-500"
placeholder=""
type="text"
minLength={2}
/>
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -87,9 +109,17 @@ export default function ProfileForm() {
name="phone"
render={({ field }) => (
<FormItem>
<FormLabel>Phone number</FormLabel>
<FormLabel>
Phone number
<span className="text-base font-extrabold text-red-600"> *</span>
</FormLabel>
<FormControl>
<Input {...field} />
<Input
{...field}
type="tel"
className="empty:border-input border invalid:border-red-500 focus-visible:border-blue-500 focus-visible:ring-0 focus-visible:ring-offset-0 [&:not(:placeholder-shown)(:invalid)]:valid:border-green-500"
placeholder=""
/>
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -101,10 +131,15 @@ export default function ProfileForm() {
control={form.control}
name="email"
render={({ field }) => (
<FormItem className="">
<FormItem className="max-w-xs max-md:max-w-full">
<FormLabel>Email</FormLabel>
<FormControl>
<Input {...field} />
<Input
{...field}
type="email"
className="border invalid:border-red-500 focus-visible:border-blue-500 focus-visible:ring-0 focus-visible:ring-offset-0 [&:not(:placeholder-shown)(:invalid)]:valid:border-green-500"
placeholder=""
/>
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -114,7 +149,7 @@ export default function ProfileForm() {
<Label>Foto</Label>
<Avatar>
<AvatarImage
className="ring-neutral h-12 w-12 rounded-full ring-[1px]"
className="ring-neutral w-12 rounded-full border-2 border-black ring-[1px]"
src={user?.picture ?? ''}
alt="User profile"
/>
Expand All @@ -123,26 +158,30 @@ export default function ProfileForm() {
</div>

<div className="flex flex-col gap-2">
<h2 className="text-base">Profile Type</h2>
<h2 className="text-base font-bold uppercase">Profile Type:</h2>
<Separator />
</div>
<FormField
control={form.control}
name="role"
render={({ field }) => (
<FormControl>
<RadioGroup
onValueChange={field.onChange}
defaultValue={field.value || ''}
className={`grid grid-cols-6`}
>
<RadioBox beforeText="I'M" id="partner" name="Partner" />

<RadioGroup defaultValue="option-one">
<div className="flex items-center space-x-2">
<RadioGroupItem value="option-hodler" id="option-hodler" />
<Label htmlFor="option-hodler">Hodler</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option-recycler" id="option-recycler" />
<Label htmlFor="option-recycler">Recycler</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="option-waste" id="option-waste" />
<Label htmlFor="option-waste">Waste Generator</Label>
</div>
</RadioGroup>
<RadioBox beforeText="I'M" id="recycler" name="Sustainable treatment agent" />

<RadioBox beforeText="I'M" id="waste-generator" name="Waste Generator" />
</RadioGroup>
</FormControl>
)}
/>

<Turnstile siteKey={import.meta.env.VITE_TURNSTILE_SITE_KEY} onSuccess={setTurnstileToken} />
{/* <Turnstile siteKey={import.meta.env.VITE_TURNSTILE_SITE_KEY} onSuccess={setTurnstileToken} /> */}
<Button type="submit">Save Changes</Button>
</form>
</Form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import ProfileForm from '@/modules/settings/components/profile/profile-form';

export default function SettingsMainScreen() {
return (
<div className="container space-y-6">
<h3 className="text-lg font-medium">Profile settings</h3>
<div className="container my-10 space-y-6 rounded-md border py-8 shadow-xl">
<h3 className="mb-10 text-3xl font-bold">Profile settings</h3>
<ProfileForm />
</div>
);
Expand Down
Loading