diff --git a/backend/internal/dto/requests.go b/backend/internal/dto/requests.go index ae5b863..48d1772 100755 --- a/backend/internal/dto/requests.go +++ b/backend/internal/dto/requests.go @@ -8,7 +8,7 @@ type CreateJobRequest struct { SalaryMin *float64 `json:"salaryMin,omitempty"` SalaryMax *float64 `json:"salaryMax,omitempty"` SalaryType *string `json:"salaryType,omitempty" validate:"omitempty,oneof=hourly daily weekly monthly yearly"` - Currency *string `json:"currency,omitempty" validate:"omitempty,oneof=BRL USD EUR GBP JPY"` + Currency *string `json:"currency,omitempty" validate:"omitempty,oneof=BRL USD EUR GBP JPY CNY AED CAD AUD CHF"` SalaryNegotiable bool `json:"salaryNegotiable"` EmploymentType *string `json:"employmentType,omitempty" validate:"omitempty,oneof=full-time part-time dispatch contract temporary training voluntary permanent"` WorkingHours *string `json:"workingHours,omitempty"` @@ -29,7 +29,7 @@ type UpdateJobRequest struct { SalaryMin *float64 `json:"salaryMin,omitempty"` SalaryMax *float64 `json:"salaryMax,omitempty"` SalaryType *string `json:"salaryType,omitempty" validate:"omitempty,oneof=hourly daily weekly monthly yearly"` - Currency *string `json:"currency,omitempty" validate:"omitempty,oneof=BRL USD EUR GBP JPY"` + Currency *string `json:"currency,omitempty" validate:"omitempty,oneof=BRL USD EUR GBP JPY CNY AED CAD AUD CHF"` SalaryNegotiable *bool `json:"salaryNegotiable,omitempty"` EmploymentType *string `json:"employmentType,omitempty" validate:"omitempty,oneof=full-time part-time dispatch contract temporary training voluntary permanent"` WorkingHours *string `json:"workingHours,omitempty"` diff --git a/backend/internal/services/job_service.go b/backend/internal/services/job_service.go index 2756d81..6b526ba 100644 --- a/backend/internal/services/job_service.go +++ b/backend/internal/services/job_service.go @@ -24,10 +24,10 @@ func (s *JobService) CreateJob(req dto.CreateJobRequest, createdBy string) (*mod query := ` INSERT INTO jobs ( - company_id, created_by, title, description, salary_min, salary_max, salary_type, + company_id, created_by, title, description, salary_min, salary_max, salary_type, currency, employment_type, working_hours, location, region_id, city_id, requirements, benefits, visa_support, language_level, status, created_at, updated_at, salary_negotiable - ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20) + ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21) RETURNING id, created_at, updated_at ` @@ -39,6 +39,7 @@ func (s *JobService) CreateJob(req dto.CreateJobRequest, createdBy string) (*mod SalaryMin: req.SalaryMin, SalaryMax: req.SalaryMax, SalaryType: req.SalaryType, + Currency: req.Currency, SalaryNegotiable: req.SalaryNegotiable, EmploymentType: req.EmploymentType, WorkingHours: req.WorkingHours, @@ -59,7 +60,7 @@ func (s *JobService) CreateJob(req dto.CreateJobRequest, createdBy string) (*mod err := s.DB.QueryRow( query, - job.CompanyID, job.CreatedBy, job.Title, job.Description, job.SalaryMin, job.SalaryMax, job.SalaryType, + job.CompanyID, job.CreatedBy, job.Title, job.Description, job.SalaryMin, job.SalaryMax, job.SalaryType, job.Currency, job.EmploymentType, job.WorkingHours, job.Location, job.RegionID, job.CityID, job.Requirements, job.Benefits, job.VisaSupport, job.LanguageLevel, job.Status, job.CreatedAt, job.UpdatedAt, job.SalaryNegotiable, ).Scan(&job.ID, &job.CreatedAt, &job.UpdatedAt) diff --git a/frontend/src/app/post-job/page.tsx b/frontend/src/app/post-job/page.tsx index cc3b2d2..ab588a6 100644 --- a/frontend/src/app/post-job/page.tsx +++ b/frontend/src/app/post-job/page.tsx @@ -15,6 +15,7 @@ import { Eye, EyeOff, Globe } from "lucide-react"; import { LocationPicker } from "@/components/location-picker"; +import { RichTextEditor } from "@/components/rich-text-editor"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; // Common Country Codes @@ -37,6 +38,24 @@ const COUNTRY_CODES = [ { code: "+51", country: "Peru (PE)" }, ].sort((a, b) => a.country.localeCompare(b.country)); +// Currency symbol helper +const getCurrencySymbol = (code: string): string => { + const symbols: Record = { + 'BRL': 'R$', 'USD': '$', 'EUR': '€', 'JPY': '¥', 'GBP': '£', + 'CNY': '¥', 'AED': 'د.إ', 'CAD': 'C$', 'AUD': 'A$', 'CHF': 'Fr' + }; + return symbols[code] || code; +}; + +// Salary period label helper +const getSalaryPeriodLabel = (type: string): string => { + const labels: Record = { + 'hourly': '/hora', 'daily': '/dia', 'weekly': '/semana', + 'monthly': '/mês', 'yearly': '/ano' + }; + return labels[type] || ''; +}; + export default function PostJobPage() { const router = useRouter(); const [step, setStep] = useState<1 | 2 | 3>(1); @@ -63,6 +82,8 @@ export default function PostJobPage() { salaryMin: "", salaryMax: "", salaryFixed: "", // For fixed salary mode + currency: "BRL", // Default currency + salaryType: "monthly", // Default salary period employmentType: "", workMode: "remote", workingHours: "", @@ -144,6 +165,8 @@ export default function PostJobPage() { // Salary logic: if negotiable, send null values salaryMin: job.salaryNegotiable ? null : (salaryMode === 'fixed' ? (job.salaryFixed ? parseInt(job.salaryFixed) : null) : (job.salaryMin ? parseInt(job.salaryMin) : null)), salaryMax: job.salaryNegotiable ? null : (salaryMode === 'fixed' ? (job.salaryFixed ? parseInt(job.salaryFixed) : null) : (job.salaryMax ? parseInt(job.salaryMax) : null)), + salaryType: job.salaryNegotiable ? null : job.salaryType, + currency: job.salaryNegotiable ? null : job.currency, salaryNegotiable: job.salaryNegotiable, employmentType: job.employmentType || null, workingHours: job.workingHours || null, @@ -348,12 +371,12 @@ export default function PostJobPage() {
- -