Skip to content

Commit

Permalink
Create Form
Browse files Browse the repository at this point in the history
  • Loading branch information
Javid Momeni committed Nov 24, 2024
1 parent 804fe4c commit 939c8a0
Show file tree
Hide file tree
Showing 4 changed files with 293 additions and 26 deletions.
6 changes: 3 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<!doctype html>
<html lang="en">
<html dir="rtl" lang="fa_IR">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100;200;300;400;500;600;700;800&display=swap" rel="stylesheet">
<title>قصه گو</title>
</head>
<body>
<div id="root"></div>
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@emotion/react": "^11.13.5",
"@emotion/styled": "^11.13.5",
"@mantine/core": "^7.14.1",
"@mantine/form": "^7.14.1",
"@mantine/hooks": "^7.14.1",
"react": "^18.3.1",
"react-dom": "^18.3.1"
Expand Down
9 changes: 7 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { HomePage } from './components/HomePage';
import { createTheme, MantineProvider } from '@mantine/core';
import { createTheme, DirectionProvider, MantineProvider } from '@mantine/core';

const theme = createTheme({
/** Put your mantine theme override here */
fontFamily: 'Vazirmatn, sans-serif',
headings: {
fontFamily: 'Vazirmatn, sans-serif',
},
});
function App() {
return (
<DirectionProvider>
<MantineProvider theme={theme}>
<HomePage />
</MantineProvider>
</DirectionProvider>
);
}

Expand Down
303 changes: 282 additions & 21 deletions src/components/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,287 @@
import { AppShell, Burger } from '@mantine/core';
import React, { useState } from 'react';

Check failure on line 1 in src/components/HomePage.tsx

View workflow job for this annotation

GitHub Actions / deploy

'React' is declared but its value is never read.
import {
Card,
TextInput,
NumberInput,
Select,
Checkbox,
Button,
Text,
Container,
Stack,
Grid,
Alert,

Check failure on line 13 in src/components/HomePage.tsx

View workflow job for this annotation

GitHub Actions / deploy

'Alert' is declared but its value is never read.
Paper,
AppShell,

Check failure on line 15 in src/components/HomePage.tsx

View workflow job for this annotation

GitHub Actions / deploy

'AppShell' is declared but its value is never read.
Burger

Check failure on line 16 in src/components/HomePage.tsx

View workflow job for this annotation

GitHub Actions / deploy

'Burger' is declared but its value is never read.
} from '@mantine/core';
import { useForm } from '@mantine/form';

export function HomePage() {
const [story, setStory] = useState('');
const [isGenerating, setIsGenerating] = useState(false);

const form = useForm({
initialValues: {
childName: '',
age: '',
environmentalTopic: '',
livingEnvironment: '',
academicApproaches: {
piaget: false,
activeLearning: false,
roleModeling: false,
multipleIntelligences: false,
vygotsky: false,
personalMotivation: false
}
},
validate: {
childName: (value) => value.trim().length === 0 ? 'لطفاً نام کودک را وارد کنید' : null,
age: (value) => (value < 2 || value > 11) ? 'لطفاً سن معتبر بین 2 تا 11 سال وارد کنید' : null,

Check failure on line 41 in src/components/HomePage.tsx

View workflow job for this annotation

GitHub Actions / deploy

Operator '<' cannot be applied to types 'string' and 'number'.

Check failure on line 41 in src/components/HomePage.tsx

View workflow job for this annotation

GitHub Actions / deploy

Operator '>' cannot be applied to types 'string' and 'number'.
environmentalTopic: (value) => !value ? 'لطفاً یک موضوع زیست‌محیطی انتخاب کنید' : null,
}
});

const [formData, setFormData] = useState({
childName: '',
age: '',
environmentalTopic: '',
livingEnvironment: '',
academicApproaches: {
piaget: false,
activeLearning: false,
roleModeling: false,
multipleIntelligences: false,
vygotsky: false,
personalMotivation: false
}
});

const environmentalTopics = [
'حفاظت از حیوانات',
'کاهش زباله',
'صرفه‌جویی در آب',
'حفاظت از درختان',
'کاهش آلودگی هوا'
];

const livingEnvironments = [
'شهر',
'روستا',
'حومه شهر',
'ساحل',
'کوهستان'
];

const academicApproachesData = [
{
id: 'piaget',
label: 'نظریه رشد شناختی پیاژه',
description: 'تطبیق پیام و زبان داستان با سطح شناختی کودک'
},
{
id: 'activeLearning',
label: 'نظریه یادگیری فعال',
description: 'درگیر کردن کودک در تصمیم‌گیری و حل چالش'
},
{
id: 'roleModeling',
label: 'نقش‌پذیری',
description: 'ارائه الگوی مثبت برای کودک'
},
{
id: 'multipleIntelligences',
label: 'هوش‌های چندگانه گاردنر',
description: 'استفاده از انواع مختلف هوش در داستان'
},
{
id: 'vygotsky',
label: 'نظریه منطقه تقریبی رشد ویگوتسکی',
description: 'وجود شخصیت راهنما در داستان'
},
{
id: 'personalMotivation',
label: 'تقویت انگیزه شخصی',
description: 'تقویت حس استقلال و تاثیرگذاری کودک'
}
];

const validateForm = () => {
if (!formData.childName.trim()) {
setError('لطفاً نام کودک را وارد کنید');

Check failure on line 112 in src/components/HomePage.tsx

View workflow job for this annotation

GitHub Actions / deploy

Cannot find name 'setError'.
return false;
}
if (!formData.age || formData.age < 2 || formData.age > 11) {

Check failure on line 115 in src/components/HomePage.tsx

View workflow job for this annotation

GitHub Actions / deploy

Operator '<' cannot be applied to types 'string' and 'number'.

Check failure on line 115 in src/components/HomePage.tsx

View workflow job for this annotation

GitHub Actions / deploy

Operator '>' cannot be applied to types 'string' and 'number'.
setError('لطفاً سن معتبر بین 2 تا 11 سال وارد کنید');

Check failure on line 116 in src/components/HomePage.tsx

View workflow job for this annotation

GitHub Actions / deploy

Cannot find name 'setError'.
return false;
}
if (!formData.environmentalTopic) {
setError('لطفاً یک موضوع زیست‌محیطی انتخاب کنید');
return false;
}
setError('');
return true;
};

const generateStory = () => {
if (!validateForm()) return;
setIsGenerating(true);

// Create story based on selected academic approaches
const ageGroup = formData.age <= 7 ? 'young' : 'older';
let storyElements = [];

// Add story elements based on selected approaches
if (formData.academicApproaches.piaget) {
// Adapt language and concepts based on age
storyElements.push(ageGroup === 'young'
? 'با زبانی ساده و تصویری'
: 'با مفاهیم پیچیده‌تر و منطقی');
}

if (formData.academicApproaches.activeLearning) {
storyElements.push('در طول داستان چند تصمیم مهم برای گرفتن وجود دارد');
}

if (formData.academicApproaches.roleModeling) {
storyElements.push(`${formData.childName} به عنوان یک الگو برای دیگران عمل می‌کند`);
}

if (formData.academicApproaches.multipleIntelligences) {
storyElements.push('از ترکیب هنر، منطق، و ارتباط با طبیعت استفاده می‌شود');
}

if (formData.academicApproaches.vygotsky) {
storyElements.push('یک راهنمای دانا در داستان حضور دارد');
}

if (formData.academicApproaches.personalMotivation) {
storyElements.push('تاکید بر توانایی‌های شخصی و استقلال در تصمیم‌گیری');
}

let generatedStory = '';

if (ageGroup === 'young') {
generatedStory = `
یک روز قشنگ، ${formData.childName} کوچولوی ${formData.age} ساله که در ${formData.livingEnvironment} زندگی می‌کرد،
تصمیم گرفت به طبیعت کمک کند. موضوعی که خیلی براش مهم بود ${formData.environmentalTopic} بود.
${storyElements.map(element => `\n${element}`).join('')}
${formData.childName} با کمک دوست جدیدش، یک سنجاب دانا به نام دانا، یاد گرفت که چطور می‌تونه به حفظ محیط زیست کمک کنه.
اونها با هم تصمیم گرفتن...
`;
} else {
generatedStory = `
${formData.childName} ${formData.age} ساله، که در ${formData.livingEnvironment} زندگی می‌کرد،
یک روز متوجه مشکل مهمی در محیط زیست شد. اون تصمیم گرفت درباره ${formData.environmentalTopic} کاری انجام بده.
${storyElements.map(element => `\n${element}`).join('')}
با کمک دوستاش و راهنمایی معلمش، ${formData.childName} یک برنامه عملی طراحی کرد...
`;
}

setStory(generatedStory);
setIsGenerating(false);
};

const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({
...prev,
[name]: value
}));
};

const handleCheckboxChange = (approachId) => {
setFormData(prev => ({
...prev,
academicApproaches: {
...prev.academicApproaches,
[approachId]: !prev.academicApproaches[approachId]
}
}));
};

return (
<AppShell
header={{ height: 60 }}
navbar={{
width: 300,
breakpoint: 'sm',
}}
padding="md"
>
<AppShell.Header>
<Burger
hiddenFrom="sm"
size="sm"
/>
<div>Logo</div>
</AppShell.Header>

<AppShell.Navbar p="md">Navbar</AppShell.Navbar>

<AppShell.Main>Main</AppShell.Main>
</AppShell>
<Container size="lg" dir="rtl">
<Card shadow="sm" p="lg" radius="md" withBorder>
<Text size="xl" weight={700} align="center" mb="md">
سازنده داستان کودک
</Text>

<form onSubmit={form.onSubmit(generateStory)}>
<Stack spacing="md">
<TextInput
label="نام کودک"
placeholder="نام کودک را وارد کنید"
{...form.getInputProps('childName')}
/>

<NumberInput
label="سن کودک"
placeholder="سن کودک را وارد کنید"
min={2}
max={11}
{...form.getInputProps('age')}
/>

<Select
label="موضوع زیست‌محیطی"
placeholder="انتخاب کنید"
data={environmentalTopics}
{...form.getInputProps('environmentalTopic')}
/>

<Select
label="محیط زندگی"
placeholder="انتخاب کنید"
data={livingEnvironments}
{...form.getInputProps('livingEnvironment')}
/>

<Text weight={500} size="sm">رویکردهای آکادمیک</Text>
<Grid>
{academicApproachesData.map((approach) => (
<Grid.Col span={6} key={approach.id}>
<Checkbox
label={approach.label}
description={approach.description}
{...form.getInputProps(`academicApproaches.${approach.id}`, { type: 'checkbox' })}
/>
</Grid.Col>
))}
</Grid>

<Button
type="submit"
loading={isGenerating}
>
{isGenerating ? 'در حال ساخت داستان...' : 'ساخت داستان'}
</Button>
</Stack>
</form>
</Card>

{story && (
<Paper shadow="sm" p="lg" radius="md" withBorder mt="xl">
<Text size="xl" weight={700} mb="md">
داستان {form.values.childName}
</Text>
<Text>
{story.split('\n').map((paragraph, index) => (
paragraph.trim() && (
<Text key={index} mb="md">
{paragraph}
</Text>
)
))}
</Text>
</Paper>
)}
</Container>
);
}

0 comments on commit 939c8a0

Please sign in to comment.