Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ build
coverage

app/frontend/routes
app/frontend/serializers
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ GEM
railties (>= 7.1.0)
turbo_power (0.7.0)
turbo-rails (>= 1.3.0)
typelizer (0.4.1)
typelizer (0.4.2)
railties (>= 6.0.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
Expand Down
2 changes: 1 addition & 1 deletion app/frontend/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { usePage } from "@inertiajs/react";
import { Menu, X } from "lucide-react";
import { useState } from "react";

import type { User } from "../serializers";
import type { User } from "@/serializers";

import { Logo } from "./Logo";

Expand Down
2 changes: 1 addition & 1 deletion app/frontend/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { usePage } from "@inertiajs/react";

import type { User } from "../serializers";
import type { User } from "@/serializers";

import { Footer } from "./Footer";
import { Header } from "./Header";
Expand Down
4 changes: 1 addition & 3 deletions app/frontend/components/ReviewScores.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type React from "react";

interface ReviewScoresProps {
scores: Record<string, number> | undefined;
}
Expand All @@ -19,7 +17,7 @@ const scoreClass = (value: number) => {
}
};

const ReviewScores: React.FC<ReviewScoresProps> = ({ scores }) => {
const ReviewScores = ({ scores }: ReviewScoresProps) => {
if (!scores || Object.keys(scores).length === 0) {
return null;
}
Expand Down
8 changes: 4 additions & 4 deletions app/frontend/components/Select.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type React from "react";
import type { ChangeEvent } from "react";

interface SelectOption {
value: string;
Expand All @@ -8,20 +8,20 @@ interface SelectOption {
interface SelectProps {
id: string;
value: string;
onChange: (e: React.ChangeEvent<HTMLSelectElement>) => void;
onChange: (e: ChangeEvent<HTMLSelectElement>) => void;
options: SelectOption[];
required?: boolean;
placeholder?: string;
}

const Select: React.FC<SelectProps> = ({
const Select = ({
id,
value,
onChange,
options,
required,
placeholder,
}) => {
}: SelectProps) => {
return (
<div className="relative">
<select
Expand Down
5 changes: 2 additions & 3 deletions app/frontend/components/StarRating.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Star } from "lucide-react";
import type React from "react";
import { useState } from "react";

interface StarRatingProps {
Expand All @@ -11,14 +10,14 @@ interface StarRatingProps {
readonly?: boolean;
}

const StarRating: React.FC<StarRatingProps> = ({
const StarRating = ({
value,
name,
onChange,
label,
required,
readonly,
}) => {
}: StarRatingProps) => {
const [hoverRating, setHoverRating] = useState(0);

const handleStarClick = (rating: number) => {
Expand Down
4 changes: 1 addition & 3 deletions app/frontend/components/StatusBadge.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type React from "react";

type ProposalStatus =
| "draft"
| "submitted"
Expand All @@ -14,7 +12,7 @@ interface StatusBadgeProps {
status: ProposalStatus;
}

const StatusBadge: React.FC<StatusBadgeProps> = ({ status }) => {
const StatusBadge = ({ status }: StatusBadgeProps) => {
let badgeClasses = "badge ";
let statusText = "";

Expand Down
8 changes: 4 additions & 4 deletions app/frontend/components/TextAreaWithCounter.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type React from "react";
import type { ChangeEvent } from "react";

interface TextAreaWithCounterProps {
id: string;
Expand All @@ -9,21 +9,21 @@ interface TextAreaWithCounterProps {
required?: boolean;
}

const TextAreaWithCounter: React.FC<TextAreaWithCounterProps> = ({
const TextAreaWithCounter = ({
id,
value,
onChange,
maxLength,
placeholder,
required,
}) => {
}: TextAreaWithCounterProps) => {
// Count line breaks as \r\n (2 characters) to match Ruby/Rails backend
const lineBreaks = (value.match(/\n/g) ?? []).length;
const characterCount = value.length + lineBreaks;
const isNearLimit = characterCount >= maxLength * 0.8;
const isAtLimit = characterCount >= maxLength;

const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
const newValue = e.target.value;
const newLineBreaks = (newValue.match(/\n/g) ?? []).length;
const newCharacterCount = newValue.length + newLineBreaks;
Expand Down
6 changes: 1 addition & 5 deletions app/frontend/icons/Google.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import type React from "react";

const GoogleIcon: React.FC<{ className?: string }> = ({
className = "h-5 w-5",
}) => (
const GoogleIcon = ({ className = "h-5 w-5" }: { className?: string }) => (
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
<path
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
Expand Down
6 changes: 3 additions & 3 deletions app/frontend/pages/evaluations/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { router, usePage } from "@inertiajs/react";

import Layout from "../../components/Layout";
import type { Evaluation } from "../../serializers";
import { formatDeadline } from "../../utils/dateHelpers";
import Layout from "@/components/Layout";
import type { Evaluation } from "@/serializers";
import { formatDeadline } from "@/utils/dateHelpers";

interface IndexProps {
evaluations: Evaluation[];
Expand Down
12 changes: 4 additions & 8 deletions app/frontend/pages/evaluations/results/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,10 @@ import {
import type { FormEvent } from "react";
import { useState } from "react";

import Layout from "../../../components/Layout";
import ReviewScores from "../../../components/ReviewScores";
import StatusBadge from "../../../components/StatusBadge";
import type {
Evaluation,
EvaluationsProposal,
Review,
} from "../../../serializers";
import Layout from "@/components/Layout";
import ReviewScores from "@/components/ReviewScores";
import StatusBadge from "@/components/StatusBadge";
import type { Evaluation, EvaluationsProposal, Review } from "@/serializers";

interface IndexProps {
evaluation: Evaluation;
Expand Down
4 changes: 2 additions & 2 deletions app/frontend/pages/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import {
UsersIcon,
} from "lucide-react";

import Layout from "../../components/Layout";
import { OAuthButtons } from "../../components/OAuthButtons";
import Layout from "@/components/Layout";
import { OAuthButtons } from "@/components/OAuthButtons";

interface IndexProps {
oauth_providers: string[];
Expand Down
14 changes: 7 additions & 7 deletions app/frontend/pages/proposals/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { AlertCircle, Save, SendIcon, Upload } from "lucide-react";
import type { FormEvent } from "react";
import { useRef, useState } from "react";

import Select from "../../components/Select";
import TextAreaWithCounter from "../../components/TextAreaWithCounter";
import type { CFP, Proposal, SpeakerProfile } from "../../serializers";
import type { AppPageProps } from "../../types/global";
import Select from "@/components/Select";
import TextAreaWithCounter from "@/components/TextAreaWithCounter";
import type { CFP, Proposal, SpeakerProfile } from "@/serializers";
import type { AppPageProps } from "@/types/global";

interface FormProps {
proposal: Proposal;
Expand Down Expand Up @@ -130,9 +130,9 @@ export default function Form({ proposal, speaker, cfp }: FormProps) {
onChange={(e) => setData("proposal.track", e.target.value)}
required={!canSaveDraft}
placeholder="Select a track"
options={Object.keys(cfp.tracks).map((track) => ({
value: track,
label: cfp.tracks[track],
options={Object.entries(cfp.tracks).map(([value, label]) => ({
value,
label,
}))}
/>
{formErrors.track && (
Expand Down
4 changes: 2 additions & 2 deletions app/frontend/pages/proposals/edit.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Link, usePage } from "@inertiajs/react";
import { ArrowLeftIcon } from "lucide-react";

import Layout from "../../components/Layout";
import type { CFP, Proposal, SpeakerProfile } from "../../serializers";
import Layout from "@/components/Layout";
import type { CFP, Proposal, SpeakerProfile } from "@/serializers";

import Form from "./Form";

Expand Down
6 changes: 3 additions & 3 deletions app/frontend/pages/proposals/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Head, Link, router, usePage } from "@inertiajs/react";
import { ArrowLeftIcon, PlusIcon } from "lucide-react";

import Layout from "../../components/Layout";
import StatusBadge from "../../components/StatusBadge";
import type { Proposal } from "../../serializers";
import Layout from "@/components/Layout";
import StatusBadge from "@/components/StatusBadge";
import type { Proposal } from "@/serializers";

interface IndexProps {
proposals: Proposal[];
Expand Down
4 changes: 2 additions & 2 deletions app/frontend/pages/proposals/new.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Link, usePage } from "@inertiajs/react";
import { ArrowLeftIcon } from "lucide-react";

import Layout from "../../components/Layout";
import type { CFP, Proposal, SpeakerProfile } from "../../serializers";
import Layout from "@/components/Layout";
import type { CFP, Proposal, SpeakerProfile } from "@/serializers";

import Form from "./Form";

Expand Down
6 changes: 3 additions & 3 deletions app/frontend/pages/proposals/show.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Link, router, usePage } from "@inertiajs/react";
import { ArrowLeftIcon, PencilIcon, TrashIcon, UserIcon } from "lucide-react";

import Layout from "../../components/Layout";
import StatusBadge from "../../components/StatusBadge";
import type { CFP, Proposal, SpeakerProfile } from "../../serializers";
import Layout from "@/components/Layout";
import StatusBadge from "@/components/StatusBadge";
import type { CFP, Proposal, SpeakerProfile } from "@/serializers";

interface ShowProps {
proposal: Proposal;
Expand Down
10 changes: 5 additions & 5 deletions app/frontend/pages/reviews/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Link, router, usePage } from "@inertiajs/react";
import { AlertCircleIcon, ExternalLinkIcon } from "lucide-react";

import Layout from "../../components/Layout";
import ReviewScores from "../../components/ReviewScores";
import StatusBadge from "../../components/StatusBadge";
import type { Evaluation, Review } from "../../serializers";
import { formatDeadline } from "../../utils/dateHelpers";
import Layout from "@/components/Layout";
import ReviewScores from "@/components/ReviewScores";
import StatusBadge from "@/components/StatusBadge";
import type { Evaluation, Review } from "@/serializers";
import { formatDeadline } from "@/utils/dateHelpers";

interface IndexProps {
evaluation: Evaluation;
Expand Down
8 changes: 4 additions & 4 deletions app/frontend/pages/reviews/show.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { AlertCircleIcon, ArrowLeftIcon, UserIcon } from "lucide-react";
import type { FormEvent } from "react";
import { useState } from "react";

import Layout from "../../components/Layout";
import StarRating from "../../components/StarRating";
import TextAreaWithCounter from "../../components/TextAreaWithCounter";
import type { Review } from "../../serializers";
import Layout from "@/components/Layout";
import StarRating from "@/components/StarRating";
import TextAreaWithCounter from "@/components/TextAreaWithCounter";
import type { Review } from "@/serializers";

interface ShowProps {
review: Review;
Expand Down
9 changes: 5 additions & 4 deletions app/frontend/serializers/CFP.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Typelizer digest 35e85a86127d6efc1f4ff9955655a470
// Typelizer digest 09b9a241cd6a6ab84c4bb9627df62a71
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {Proposal} from "@/serializers"

interface CFP {
type CFP = {
id: string;
tracks: Record<string, string>;
field_names: Record<string, string> | undefined;
tracks: Record<Exclude<Proposal["track"], null>,string>;
field_names: Record<string,string> | undefined;
is_closed: boolean;
}

Expand Down
7 changes: 4 additions & 3 deletions app/frontend/serializers/Evaluation.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Typelizer digest e9d5ef2cb9143459364b0747400c38e7
// Typelizer digest f92f72437c59ca1bd3dc435237c17bac
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {Proposal} from "@/serializers"

interface Evaluation {
type Evaluation = {
id: number;
name: string;
tracks: ("oss" | "scale" | "general" | "workshop")[];
tracks: Exclude<Proposal["track"], null>[];
criteria: string[];
blind: boolean;
personal: boolean;
Expand Down
13 changes: 3 additions & 10 deletions app/frontend/serializers/EvaluationsProposal.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
// Typelizer digest 04b5629f2a3adfb2cd1236089c2e83bc
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type { SpeakerProfile } from "../serializers";
import type {SpeakerProfile} from "@/serializers"

interface EvaluationsProposal {
type EvaluationsProposal = {
id: string;
title: string | null;
details: string | null;
abstract: string | null;
pitch: string | null;
track: "oss" | "scale" | "general" | "workshop" | null;
status:
| "draft"
| "submitted"
| "accepted"
| "rejected"
| "waitlisted"
| "confirmed"
| "declined";
status: "draft" | "submitted" | "accepted" | "rejected" | "waitlisted" | "confirmed" | "declined";
submitted_at: string | null;
score: number;
reviews_count: number;
Expand Down
11 changes: 2 additions & 9 deletions app/frontend/serializers/Proposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,15 @@
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.

interface Proposal {
type Proposal = {
id: string;
cfp_id: string | null;
title: string | null;
details: string | null;
abstract: string | null;
pitch: string | null;
track: "oss" | "scale" | "general" | "workshop" | null;
status:
| "draft"
| "submitted"
| "accepted"
| "rejected"
| "waitlisted"
| "confirmed"
| "declined";
status: "draft" | "submitted" | "accepted" | "rejected" | "waitlisted" | "confirmed" | "declined";
submitted_at: string | null;
can_edit: boolean;
}
Expand Down
Loading