7.4 KiB
7.4 KiB
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
- Reuse shared components - Don't create duplicate upload boxes
- Follow naming conventions -
TopicNameForm.tsx(PascalCase) - Use config first - Try existing forms before creating new
- Keep forms simple - Move complex logic to separate hooks
- Test with Arabic - Ensure RTL works correctly
- Check animations - Use Motion for all interactions
- Type everything - Avoid
anytypes - Document custom forms - Add JSDoc comments
🎓 Key Principles
- Config-Driven - Data drives UI, not code
- Single Responsibility - One job per component
- DRY - Don't Repeat Yourself
- Composition - Build complex from simple
- Type Safety - Full TypeScript coverage
- 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
anytypes
Keep this file handy for quick reference! 📌