Hamdast1/QUICK_REFERENCE.md
2026-05-20 12:31:48 +03:30

7.4 KiB
Raw Blame History

Quick Reference - SubmitChallengePage Refactoring

🎯 At a Glance

Item Value
Main File /src/app/components/SubmitChallengePage.tsx
Config File /src/config/topicConfig.ts
Forms Directory /src/app/components/submit-forms/
Shared Components /src/app/components/submit-forms/shared/

📁 New Files Created

✅ /src/app/components/submit-forms/ImageForm.tsx
✅ /src/app/components/submit-forms/ImageVideoForm.tsx
✅ /src/app/components/submit-forms/shared/MediaUploadBox.tsx
✅ /src/app/components/submit-forms/shared/TeammatesSection.tsx
✅ /src/app/components/submit-forms/shared/FormInput.tsx
✅ /REFACTORING.md
✅ /REFACTORING_SUMMARY.md
✅ /MIGRATION_GUIDE.md
✅ /ARCHITECTURE_DIAGRAM.md

Quick Actions

Add New Topic (Image Only)

// In topicConfig.ts
"10": {
  id: "10",
  title: "New Topic",
  mediaType: "image",
  requiresTeammates: false,
  formComponent: ImageForm,
  // ... rest
}

Add New Topic (Image + Video)

"10": {
  mediaType: "both",
  requiresTeammates: true,
  formComponent: ImageVideoForm,
}

Create Custom Form

// 1. Create file
export function MyForm({ topicId, topicTitle, onSubmit }: SubmitFormProps) {
  return <div>Your UI</div>;
}

// 2. Import in config
import { MyForm } from "../app/components/submit-forms/MyForm";

// 3. Use in config
"10": {
  formComponent: MyForm,
}

🔧 Component Props

SubmitFormProps

interface SubmitFormProps {
  topicId: string;
  topicTitle: string;
  onSubmit: (data: any) => void;
}

MediaUploadBox

<MediaUploadBox
  type="image" | "video"
  uploadedFile={string | null}
  onUpload={(e) => void}
  onRemove={() => void}
  fileName?: string
  label?: string
  required?: boolean
/>

TeammatesSection

<TeammatesSection
  teammates={string[]}
  onAdd={() => void}
  onRemove={(index: number) => void}
  onChange={(index: number, value: string) => void}
/>

FormInput

<FormInput
  label={string}
  value={string}
  onChange={(value: string) => void}
  placeholder={string}
  multiline?: boolean
  rows?: number
/>

🎨 Styling Constants

const inputStyle = {
  background: "linear-gradient(135deg, rgba(50, 107, 118, 0.6) 0%, rgba(32, 76, 106, 0.6) 100%)",
  border: "1.5px solid rgba(138, 206, 224, 0.3)",
  boxShadow: "0 4px 12px rgba(0, 0, 0, 0.2)",
};

📊 Topic Config Fields

{
  id: string,                           // "1", "2", etc.
  title: string,                        // "تخته سیاه"
  description: string,                  // Short description
  accentColor: string,                  // "#8ACEE0"
  backgroundColor: string,              // "#0a1f2e"
  mediaType: "image" | "video" | "both",// NEW!
  requiresTeammates: boolean,           // NEW!
  formComponent: ComponentType,         // NEW!
  challenges: TopicChallenge[],
  chatbotIntro: string
}

🚀 Common Tasks

Show/Hide Teammates

// In config
requiresTeammates: true  // Shows section
requiresTeammates: false // Hides section

Change Media Type

// In config
mediaType: "image"  // ImageForm recommended
mediaType: "video"  // Create VideoForm
mediaType: "both"   // ImageVideoForm

Custom Validation

// In form component
const handleSubmit = () => {
  if (!title.trim()) {
    alert("عنوان الزامی است");
    return;
  }
  onSubmit(data);
};

Custom Field

// In form component
const [customField, setCustomField] = useState("");

<FormInput
  label="فیلد سفارشی"
  value={customField}
  onChange={setCustomField}
  placeholder="..."
/>

🐛 Common Issues

Issue Solution
Form not showing Check import in topicConfig.ts
TypeScript error Implement SubmitFormProps interface
Teammates always show Set requiresTeammates: false
Wrong form renders Check topicId mapping in config
Styles not applying Check inputStyle is imported

📋 Checklist for New Forms

  • Component implements SubmitFormProps
  • Uses shared components (MediaUploadBox, etc.)
  • Follows RTL pattern (dir="rtl")
  • Has submit button with validation
  • Imports from correct paths
  • Added to topicConfig.ts
  • TypeScript compiles without errors
  • Tested with real topicId

🔍 Testing URLs

/submit/1  → تخته سیاه (ImageForm)
/submit/2  → نیمکت (ImageVideoForm)
/submit/3  → دفترچه یادداشت (ImageForm)
/submit/4  → دیوار حیاط (ImageForm)
/submit/5  → آبخوری (ImageForm)
/submit/6  → زنگ ورزش (ImageForm)
/submit/7  → سه ماه تعطیلی (ImageForm)
/submit/8  → روزنامه دیواری (ImageForm)
/submit/9  → زنگ تفریح (ImageForm)

📚 Documentation Files

File Purpose
REFACTORING.md Detailed technical documentation
REFACTORING_SUMMARY.md High-level overview
MIGRATION_GUIDE.md Step-by-step migration instructions
ARCHITECTURE_DIAGRAM.md Visual architecture diagrams
QUICK_REFERENCE.md This file - quick lookup

💡 Pro Tips

  1. Reuse shared components - Don't create duplicate upload boxes
  2. Follow naming conventions - TopicNameForm.tsx (PascalCase)
  3. Use config first - Try existing forms before creating new
  4. Keep forms simple - Move complex logic to separate hooks
  5. Test with Arabic - Ensure RTL works correctly
  6. Check animations - Use Motion for all interactions
  7. Type everything - Avoid any types
  8. Document custom forms - Add JSDoc comments

🎓 Key Principles

  1. Config-Driven - Data drives UI, not code
  2. Single Responsibility - One job per component
  3. DRY - Don't Repeat Yourself
  4. Composition - Build complex from simple
  5. Type Safety - Full TypeScript coverage
  6. Testability - Easy to unit test

📞 Quick Help

Q: How do I add a new topic? A: Update topicConfig.ts, use existing form or create new

Q: How do I customize a form? A: Edit the form component in /submit-forms/

Q: How do I add a new field? A: Add state and FormInput in the form component

Q: How do I change validation? A: Modify handleSubmit in the form component

Q: Where are styles defined? A: In components using Tailwind + inline styles


Performance

  • Bundle size: Same or smaller (tree-shaking)
  • Load time: Faster (code-splitting)
  • Runtime: Identical performance
  • Memory: Slightly better (less duplication)

Validation Examples

// Required field
if (!title.trim()) {
  alert("عنوان الزامی است");
  return;
}

// Video cover required
if (mediaType === "video" && !videoCover) {
  // Button already disabled
  return;
}

// Min length
if (learnings.length < 10) {
  alert("توضیحات باید حداقل ۱۰ کاراکتر باشد");
  return;
}

🎯 Remember

DO:

  • Use existing components when possible
  • Follow established patterns
  • Update config for new topics
  • Test with RTL
  • Use TypeScript

DON'T:

  • Hardcode topicId checks
  • Duplicate upload logic
  • Mix layout with business logic
  • Forget to import in config
  • Use any types

Keep this file handy for quick reference! 📌