mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 18:19:43 +00:00
Add question types, nudge feature, and share modal
- Add new question card components (photo, audio, text, who-likely) - Add share preview modal for matches - Add nudge notification system with rate limiting - Add session-based notification improvements - Add match confetti celebration animation - Update onboarding flow with paywall tracking - Remove deprecated swipe card and tutorial components - Update GlassCard/GlassInput to use solid backgrounds - Fix routing issues after packs screen removal
This commit is contained in:
1 parent
8612b16b93
commit
1daf386765
114 files changed
+14877
-7911
No files matched your search
@@ -12,6 +12,10 @@ export interface Profile {
|
||||
public_key_jwk?: Record<string, unknown> | null;
|
||||
/** When true, packs marked as is_explicit will be hidden */
|
||||
hide_nsfw?: boolean;
|
||||
/** Whether onboarding flow has been completed */
|
||||
onboarding_completed?: boolean;
|
||||
/** Version of onboarding flow completed. 0 = never, 1+ = that version */
|
||||
onboarding_version?: number;
|
||||
}
|
||||
|
||||
// Couple pairing
|
||||
@@ -45,6 +49,10 @@ export interface Question {
|
||||
required_props?: string[] | null;
|
||||
/** References the primary question that this is an inverse of (e.g., give vs receive). NULL means this is a primary/standalone question. */
|
||||
inverse_of?: string | null;
|
||||
/** Type of question interaction (default: 'swipe') */
|
||||
question_type?: QuestionType;
|
||||
/** Configuration options for specific question types */
|
||||
config?: QuestionConfig | null;
|
||||
created_at: string;
|
||||
deleted_at?: string | null;
|
||||
}
|
||||
@@ -52,8 +60,23 @@ export interface Question {
|
||||
// User's answer type
|
||||
export type AnswerType = 'yes' | 'no' | 'maybe';
|
||||
|
||||
// Question type (default is 'swipe' for backwards compatibility)
|
||||
export type QuestionType = 'swipe' | 'text_answer' | 'audio' | 'photo' | 'who_likely';
|
||||
|
||||
// Question configuration options
|
||||
export interface QuestionConfig {
|
||||
max_duration_seconds?: number; // For audio questions (default: 60)
|
||||
}
|
||||
|
||||
// Response data for non-swipe question types
|
||||
export type ResponseData =
|
||||
| { type: 'text_answer'; text: string }
|
||||
| { type: 'audio'; media_path: string; duration_seconds: number }
|
||||
| { type: 'photo'; media_path: string }
|
||||
| { type: 'who_likely'; chosen_user_id: string };
|
||||
|
||||
// Match type when both partners agree
|
||||
export type MatchType = 'yes_yes' | 'yes_maybe' | 'maybe_maybe';
|
||||
export type MatchType = 'yes_yes' | 'yes_maybe' | 'maybe_maybe' | 'both_answered';
|
||||
|
||||
// User response to a question
|
||||
export interface Response {
|
||||
@@ -62,6 +85,8 @@ export interface Response {
|
||||
question_id: string;
|
||||
couple_id: string;
|
||||
answer: AnswerType;
|
||||
/** Additional response data for non-swipe question types */
|
||||
response_data?: ResponseData | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
@@ -72,6 +97,8 @@ export interface Match {
|
||||
question_id: string;
|
||||
match_type: MatchType;
|
||||
is_new: boolean;
|
||||
/** Summary of both partners' response data (keyed by user_id) for non-swipe questions */
|
||||
response_summary?: Record<string, ResponseData> | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -609,6 +609,7 @@ export type Database = {
|
||||
is_new: boolean | null
|
||||
match_type: Database["public"]["Enums"]["match_type"]
|
||||
question_id: string
|
||||
response_summary: Json | null
|
||||
}
|
||||
Insert: {
|
||||
couple_id: string
|
||||
@@ -617,6 +618,7 @@ export type Database = {
|
||||
is_new?: boolean | null
|
||||
match_type: Database["public"]["Enums"]["match_type"]
|
||||
question_id: string
|
||||
response_summary?: Json | null
|
||||
}
|
||||
Update: {
|
||||
couple_id?: string
|
||||
@@ -625,6 +627,7 @@ export type Database = {
|
||||
is_new?: boolean | null
|
||||
match_type?: Database["public"]["Enums"]["match_type"]
|
||||
question_id?: string
|
||||
response_summary?: Json | null
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
@@ -797,6 +800,53 @@ export type Database = {
|
||||
},
|
||||
]
|
||||
}
|
||||
notification_preferences: {
|
||||
Row: {
|
||||
user_id: string
|
||||
matches_enabled: boolean | null
|
||||
messages_enabled: boolean | null
|
||||
partner_activity_enabled: boolean | null
|
||||
nudges_enabled: boolean | null
|
||||
pack_changes_enabled: boolean | null
|
||||
new_packs_enabled: boolean | null
|
||||
streak_milestones_enabled: boolean | null
|
||||
created_at: string | null
|
||||
updated_at: string | null
|
||||
}
|
||||
Insert: {
|
||||
user_id: string
|
||||
matches_enabled?: boolean | null
|
||||
messages_enabled?: boolean | null
|
||||
partner_activity_enabled?: boolean | null
|
||||
nudges_enabled?: boolean | null
|
||||
pack_changes_enabled?: boolean | null
|
||||
new_packs_enabled?: boolean | null
|
||||
streak_milestones_enabled?: boolean | null
|
||||
created_at?: string | null
|
||||
updated_at?: string | null
|
||||
}
|
||||
Update: {
|
||||
user_id?: string
|
||||
matches_enabled?: boolean | null
|
||||
messages_enabled?: boolean | null
|
||||
partner_activity_enabled?: boolean | null
|
||||
nudges_enabled?: boolean | null
|
||||
pack_changes_enabled?: boolean | null
|
||||
new_packs_enabled?: boolean | null
|
||||
streak_milestones_enabled?: boolean | null
|
||||
created_at?: string | null
|
||||
updated_at?: string | null
|
||||
}
|
||||
Relationships: [
|
||||
{
|
||||
foreignKeyName: "notification_preferences_user_id_fkey"
|
||||
columns: ["user_id"]
|
||||
isOneToOne: true
|
||||
referencedRelation: "profiles"
|
||||
referencedColumns: ["id"]
|
||||
},
|
||||
]
|
||||
}
|
||||
pack_topics: {
|
||||
Row: {
|
||||
pack_id: string
|
||||
@@ -836,6 +886,7 @@ export type Database = {
|
||||
gender: string | null
|
||||
id: string
|
||||
is_premium: boolean | null
|
||||
last_nudge_sent_at: string | null
|
||||
max_intensity: number | null
|
||||
name: string | null
|
||||
onboarding_completed: boolean | null
|
||||
@@ -853,6 +904,7 @@ export type Database = {
|
||||
gender?: string | null
|
||||
id: string
|
||||
is_premium?: boolean | null
|
||||
last_nudge_sent_at?: string | null
|
||||
max_intensity?: number | null
|
||||
name?: string | null
|
||||
onboarding_completed?: boolean | null
|
||||
@@ -870,6 +922,7 @@ export type Database = {
|
||||
gender?: string | null
|
||||
id?: string
|
||||
is_premium?: boolean | null
|
||||
last_nudge_sent_at?: string | null
|
||||
max_intensity?: number | null
|
||||
name?: string | null
|
||||
onboarding_completed?: boolean | null
|
||||
@@ -948,31 +1001,37 @@ export type Database = {
|
||||
questions: {
|
||||
Row: {
|
||||
allowed_couple_genders: string[] | null
|
||||
config: Json | null
|
||||
created_at: string | null
|
||||
id: string
|
||||
intensity: number | null
|
||||
pack_id: string
|
||||
partner_text: string | null
|
||||
question_type: Database["public"]["Enums"]["question_type"]
|
||||
target_user_genders: string[] | null
|
||||
text: string
|
||||
}
|
||||
Insert: {
|
||||
allowed_couple_genders?: string[] | null
|
||||
config?: Json | null
|
||||
created_at?: string | null
|
||||
id?: string
|
||||
intensity?: number | null
|
||||
pack_id: string
|
||||
partner_text?: string | null
|
||||
question_type?: Database["public"]["Enums"]["question_type"]
|
||||
target_user_genders?: string[] | null
|
||||
text: string
|
||||
}
|
||||
Update: {
|
||||
allowed_couple_genders?: string[] | null
|
||||
config?: Json | null
|
||||
created_at?: string | null
|
||||
id?: string
|
||||
intensity?: number | null
|
||||
pack_id?: string
|
||||
partner_text?: string | null
|
||||
question_type?: Database["public"]["Enums"]["question_type"]
|
||||
target_user_genders?: string[] | null
|
||||
text?: string
|
||||
}
|
||||
@@ -1032,6 +1091,7 @@ export type Database = {
|
||||
created_at: string | null
|
||||
id: string
|
||||
question_id: string
|
||||
response_data: Json | null
|
||||
user_id: string
|
||||
}
|
||||
Insert: {
|
||||
@@ -1040,6 +1100,7 @@ export type Database = {
|
||||
created_at?: string | null
|
||||
id?: string
|
||||
question_id: string
|
||||
response_data?: Json | null
|
||||
user_id: string
|
||||
}
|
||||
Update: {
|
||||
@@ -1048,6 +1109,7 @@ export type Database = {
|
||||
created_at?: string | null
|
||||
id?: string
|
||||
question_id?: string
|
||||
response_data?: Json | null
|
||||
user_id?: string
|
||||
}
|
||||
Relationships: [
|
||||
@@ -1347,12 +1409,14 @@ export type Database = {
|
||||
Args: { target_pack_id?: string }
|
||||
Returns: {
|
||||
allowed_couple_genders: string[]
|
||||
config: Json
|
||||
id: string
|
||||
intensity: number
|
||||
is_two_part: boolean
|
||||
pack_id: string
|
||||
partner_answered: boolean
|
||||
partner_text: string
|
||||
question_type: Database["public"]["Enums"]["question_type"]
|
||||
target_user_genders: string[]
|
||||
text: string
|
||||
}[]
|
||||
@@ -1424,7 +1488,8 @@ export type Database = {
|
||||
| "resolved"
|
||||
| "closed"
|
||||
feedback_type: "bug" | "feature_request" | "general" | "question"
|
||||
match_type: "yes_yes" | "yes_maybe" | "maybe_maybe"
|
||||
match_type: "yes_yes" | "yes_maybe" | "maybe_maybe" | "both_answered"
|
||||
question_type: "swipe" | "text_answer" | "audio" | "photo" | "who_likely"
|
||||
report_reason: "harassment" | "spam" | "inappropriate_content" | "other"
|
||||
subscription_status:
|
||||
| "active"
|
||||
@@ -1572,7 +1637,8 @@ export const Constants = {
|
||||
],
|
||||
feedback_status: ["new", "reviewed", "in_progress", "resolved", "closed"],
|
||||
feedback_type: ["bug", "feature_request", "general", "question"],
|
||||
match_type: ["yes_yes", "yes_maybe", "maybe_maybe"],
|
||||
match_type: ["yes_yes", "yes_maybe", "maybe_maybe", "both_answered"],
|
||||
question_type: ["swipe", "text_answer", "audio", "photo", "who_likely"],
|
||||
report_reason: ["harassment", "spam", "inappropriate_content", "other"],
|
||||
subscription_status: [
|
||||
"active",
|
||||
|
||||
Reference in new issue
Block a user