Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 1x 1x 75x 75x 75x 1x 63x 63x 1x 148x 148x 148x 148x 148x 148x 148x 1x 148x 148x 148x 148x 148x 148x 148x 148x 148x 148x 148x 148x 148x 148x 1x 148x 148x 148x 148x 148x 148x 148x | import {
FeedbackFlowView,
FeedbackRating,
FeedbackVisibility,
Sentiment,
} from '@/types';
// User's local comment input being edited — not yet persisted to server
export type FeedbackDraft = {
comment: string;
isAnonymous: boolean;
};
// Persisted feedback from server — the official state
export type FeedbackDisplay = {
feedback: string;
visibility: FeedbackVisibility;
time: string;
sentiment: string | null | undefined; // AI-inferred sentiment (positive/negative)
commentId: string | undefined;
};
// UI state — controls view transitions and modal visibility
export type FeedbackUi = {
view: FeedbackFlowView; // Read (display) or Compose (create/edit)
isLoading: boolean; // API call in progress
showDeleteConfirm: boolean; // Delete confirmation modal visibility
isComposeOpen: boolean; // Overlay (compose/edit form) visibility
};
/**
* Convert AI sentiment prediction to visual rating badge
* @param s - Sentiment string from AI model (positive/negative) or null
* @returns FeedbackRating.GOOD for positive, GOOD for negative, null otherwise
*/
export const sentimentToRating = (s?: string | null): FeedbackRating | null => {
if (s == null) return null;
return s === Sentiment.POSITIVE ? FeedbackRating.GOOD : FeedbackRating.BAD;
};
/**
* Convert anonymous toggle to visibility enum
* @param isAnonymous - Whether feedback should be anonymous
* @returns FeedbackVisibility.Anonymous or FeedbackVisibility.Public
*/
export const toVisibility = (isAnonymous: boolean): FeedbackVisibility => {
return isAnonymous ? FeedbackVisibility.Anonymous : FeedbackVisibility.Public;
};
/**
* Initialize empty draft state respecting existing visibility setting
* @param initialVisibility - Current visibility mode to preserve
* @returns Empty draft with visibility mode preserved
*/
export const getInitialDraft = (
initialVisibility: FeedbackVisibility,
): FeedbackDraft => {
return {
comment: '',
isAnonymous: initialVisibility === FeedbackVisibility.Anonymous,
};
};
/**
* Initialize display state from server data
* @param initialFeedback - Existing feedback text
* @param initialVisibility - Existing visibility setting
* @param feedbackSentiment - AI-inferred sentiment
* @param commentId - Server-side comment ID
* @param createdTime - When comment was created
* @returns Display state representing persisted feedback
*/
export const getInitialDisplay = (
initialFeedback: string,
initialVisibility: FeedbackVisibility,
feedbackSentiment: string | null | undefined,
commentId: string | undefined,
createdTime: string,
): FeedbackDisplay => {
return {
feedback: initialFeedback,
visibility: initialVisibility,
time: createdTime,
sentiment: feedbackSentiment,
commentId,
};
};
/**
* Initialize UI state based on entry point
* @param isComment - true if viewing existing feedback, false if composing new
* @returns UI state with appropriate view and closed modals
*/
export const getInitialUiState = (isComment: boolean): FeedbackUi => {
return {
view: isComment ? FeedbackFlowView.Read : FeedbackFlowView.Compose,
isLoading: false,
showDeleteConfirm: false,
isComposeOpen: false,
};
};
|