fix: update dropdown search to use name property and improve UI
- Fix dropdown filter and display to use option.name instead of option.value - Change disabled input opacity from 50 to 100 for better visibility - Remove default fallback in mobile navbar active item detection - Update campaign join route to include school_code parameter - Refactor join-to-campaign page to use classmate nickname API - Add school_code to campaign service and route parameters - Fix various formatting and whitespace issues
This commit is contained in:
parent
d97c1d0fb7
commit
213e865aab
|
|
@ -125,7 +125,7 @@ export const BaseDropdown = forwardRef<HTMLDivElement, BaseDropdownProps>(
|
||||||
};
|
};
|
||||||
|
|
||||||
const filteredOptions = internalOptions.filter((option) =>
|
const filteredOptions = internalOptions.filter((option) =>
|
||||||
option.value.toLowerCase().includes(searchQuery.toLowerCase())
|
option.name.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
const hasError = !!error;
|
const hasError = !!error;
|
||||||
|
|
@ -193,7 +193,7 @@ export const BaseDropdown = forwardRef<HTMLDivElement, BaseDropdownProps>(
|
||||||
onClick={() => handleSelect(option)}
|
onClick={() => handleSelect(option)}
|
||||||
className="cursor-pointer px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
|
className="cursor-pointer px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
|
||||||
>
|
>
|
||||||
{option.value}
|
{option.name}
|
||||||
</li>
|
</li>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const CustomInput = React.forwardRef<HTMLInputElement, CustomInputProps>(
|
||||||
)}
|
)}
|
||||||
<input
|
<input
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-12 w-full rounded-lg border-2 bg-background px-4 py-2 text-sm transition-all duration-200 placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-50",
|
"flex h-12 w-full rounded-lg border-2 bg-background px-4 py-2 text-sm transition-all duration-200 placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-100",
|
||||||
{
|
{
|
||||||
// Primary variant
|
// Primary variant
|
||||||
"border-gray-300 focus-visible:border-blue-600 focus-visible:ring-blue-600":
|
"border-gray-300 focus-visible:border-blue-600 focus-visible:ring-blue-600":
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ export function MobileNavbar({
|
||||||
const matchedItem = items.find((item) =>
|
const matchedItem = items.find((item) =>
|
||||||
location.pathname.startsWith(item.path)
|
location.pathname.startsWith(item.path)
|
||||||
);
|
);
|
||||||
return matchedItem?.id || items[0]?.id;
|
return matchedItem?.id;
|
||||||
}, [location.pathname, items]);
|
}, [location.pathname, items]);
|
||||||
|
|
||||||
const handleNavClick = (path: string) => {
|
const handleNavClick = (path: string) => {
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ export function CampaignsPage() {
|
||||||
|
|
||||||
const handleJoin = (campaign: Campaign) => {
|
const handleJoin = (campaign: Campaign) => {
|
||||||
navigate(
|
navigate(
|
||||||
`${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.joinToCampaing}?id=${campaign.WorkflowID}`,
|
`${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.joinToCampaing}/${campaign.school_code}/${campaign.WorkflowID}`,
|
||||||
{
|
{
|
||||||
replace: true,
|
replace: true,
|
||||||
}
|
}
|
||||||
|
|
@ -185,8 +185,7 @@ export function CampaignsPage() {
|
||||||
<button
|
<button
|
||||||
key={tab.value}
|
key={tab.value}
|
||||||
onClick={() => handleTabChange(tab.value)}
|
onClick={() => handleTabChange(tab.value)}
|
||||||
className={`px-4 py-2 text-sm font-medium whitespace-nowrap rounded-t-lg transition-colors ${
|
className={`px-4 py-2 text-sm font-medium whitespace-nowrap rounded-t-lg transition-colors ${activeTab === tab.value
|
||||||
activeTab === tab.value
|
|
||||||
? "bg-white border-gray-200 border-t border-x text-blue-600"
|
? "bg-white border-gray-200 border-t border-x text-blue-600"
|
||||||
: "text-slate-600 hover:text-slate-800 hover:bg-gray-100"
|
: "text-slate-600 hover:text-slate-800 hover:bg-gray-100"
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -252,7 +251,7 @@ export function CampaignsPage() {
|
||||||
variant="info"
|
variant="info"
|
||||||
className="shrink-0"
|
className="shrink-0"
|
||||||
>
|
>
|
||||||
انتخاب{" "}
|
انتخاب
|
||||||
</CustomButton>
|
</CustomButton>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,20 @@ import { CustomButton } from "@/core/components/base/button";
|
||||||
import { CustomInput } from "@/core/components/base/input";
|
import { CustomInput } from "@/core/components/base/input";
|
||||||
import {
|
import {
|
||||||
createCircleService,
|
createCircleService,
|
||||||
searchUsersService,
|
getclassmateNickName,
|
||||||
} from "@modules/dashboard/service/campaigns.service";
|
} from "@modules/dashboard/service/campaigns.service";
|
||||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
import { X } from "lucide-react";
|
import { X } from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import { DASHBOARD_ROUTE } from "../../routes/route.constant";
|
||||||
import type { User } from "./join-to-campaing";
|
import type { User } from "./join-to-campaing";
|
||||||
|
|
||||||
export const JoinToCampaing = () => {
|
export const JoinToCampaing = () => {
|
||||||
const [circleName, setCircleName] = useState("");
|
const [circleName, setCircleName] = useState("");
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const { scoolId, campId } = useParams();
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
const [selectedMembers, setSelectedMembers] = useState<User[]>([]);
|
const [selectedMembers, setSelectedMembers] = useState<User[]>([]);
|
||||||
const [errors, setErrors] = useState<{
|
const [errors, setErrors] = useState<{
|
||||||
circleName?: string;
|
circleName?: string;
|
||||||
|
|
@ -21,32 +25,41 @@ export const JoinToCampaing = () => {
|
||||||
}>({});
|
}>({});
|
||||||
|
|
||||||
const { data: users } = useQuery({
|
const { data: users } = useQuery({
|
||||||
queryKey: ["users", searchTerm],
|
queryKey: ["users", scoolId],
|
||||||
queryFn: () => searchUsersService(searchTerm),
|
queryFn: () => getclassmateNickName(Number(scoolId)),
|
||||||
enabled: !!searchTerm,
|
enabled: !!scoolId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { mutate: createCircle, isPending: isCreating } = useMutation({
|
|
||||||
|
const { mutate: createCircle, isPending: isCreating } = useMutation<{
|
||||||
|
group_id: number
|
||||||
|
}>({
|
||||||
mutationFn: () =>
|
mutationFn: () =>
|
||||||
createCircleService(
|
createCircleService(
|
||||||
circleName,
|
circleName,
|
||||||
selectedMembers.map((m) => m.user_id)
|
String(campId),
|
||||||
|
selectedMembers.map((m) => m.WorkflowID)
|
||||||
),
|
),
|
||||||
onSuccess: () => {
|
|
||||||
|
onSuccess: ({ group_id }) => {
|
||||||
setCircleName("");
|
setCircleName("");
|
||||||
setSelectedMembers([]);
|
setSelectedMembers([]);
|
||||||
|
navigate(
|
||||||
|
`${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.steps}/${campId}/${group_id}`
|
||||||
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleAddMember = (userId: string) => {
|
const handleAddMember = (userId: number) => {
|
||||||
const user = users?.find((u) => u.user_id === userId);
|
const user = users?.find((u) => u.WorkflowID === userId);
|
||||||
if (user && !selectedMembers.some((m) => m.user_id === userId)) {
|
if (user && !selectedMembers.some((m) => m.WorkflowID === userId)) {
|
||||||
setSelectedMembers([...selectedMembers, user]);
|
setSelectedMembers([...selectedMembers, user]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemoveMember = (userId: string) => {
|
|
||||||
setSelectedMembers(selectedMembers.filter((m) => m.user_id !== userId));
|
const handleRemoveMember = (userId: number) => {
|
||||||
|
setSelectedMembers(selectedMembers.filter((m) => m.WorkflowID !== userId));
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkRequired = () => {
|
const checkRequired = () => {
|
||||||
|
|
@ -91,13 +104,12 @@ export const JoinToCampaing = () => {
|
||||||
placeholder="جستجوی لقب عضو..."
|
placeholder="جستجوی لقب عضو..."
|
||||||
options={
|
options={
|
||||||
users?.map((user) => ({
|
users?.map((user) => ({
|
||||||
value: user.user_id,
|
value: String(user.WorkflowID),
|
||||||
label: user.nickname,
|
name: user.nickname,
|
||||||
})) || []
|
})) ?? []
|
||||||
}
|
}
|
||||||
onInputChange={(inputValue) => setSearchTerm(inputValue)}
|
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
handleAddMember(value);
|
handleAddMember(Number(value));
|
||||||
if (errors.members) {
|
if (errors.members) {
|
||||||
setErrors((prev) => ({ ...prev, members: undefined }));
|
setErrors((prev) => ({ ...prev, members: undefined }));
|
||||||
}
|
}
|
||||||
|
|
@ -117,12 +129,12 @@ export const JoinToCampaing = () => {
|
||||||
<ul className="space-y-2">
|
<ul className="space-y-2">
|
||||||
{selectedMembers.map((member) => (
|
{selectedMembers.map((member) => (
|
||||||
<li
|
<li
|
||||||
key={member.user_id}
|
key={member.WorkflowID}
|
||||||
className="flex items-center justify-between bg-gray-100 p-2 rounded-md"
|
className="flex items-center justify-between bg-gray-100 p-2 rounded-md"
|
||||||
>
|
>
|
||||||
<span>{member.nickname}</span>
|
<span>{member.nickname}</span>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleRemoveMember(member.user_id)}
|
onClick={() => handleRemoveMember(member.WorkflowID)}
|
||||||
className="text-red-500 hover:text-red-700"
|
className="text-red-500 hover:text-red-700"
|
||||||
>
|
>
|
||||||
<X size={18} />
|
<X size={18} />
|
||||||
|
|
@ -138,7 +150,7 @@ export const JoinToCampaing = () => {
|
||||||
<CustomButton
|
<CustomButton
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
disabled={isCreating}
|
disabled={isCreating || selectedMembers.length < 2 || circleName.length === 0}
|
||||||
>
|
>
|
||||||
تایید و ایجاد محفل
|
تایید و ایجاد محفل
|
||||||
</CustomButton>
|
</CustomButton>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
export type User = {
|
|
||||||
user_id: string;
|
export interface User {
|
||||||
|
ValueP1224S1943StageID: number;
|
||||||
|
ValueP1224S1943ValueID: number;
|
||||||
|
WorkflowID: number;
|
||||||
nickname: string;
|
nickname: string;
|
||||||
};
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ export function RegisterPage() {
|
||||||
image: undefined,
|
image: undefined,
|
||||||
nationalcode: data?.nationalcode || "",
|
nationalcode: data?.nationalcode || "",
|
||||||
base: data?.base || "",
|
base: data?.base || "",
|
||||||
|
group: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -53,6 +54,7 @@ export function RegisterPage() {
|
||||||
invitor: data.invitor || "",
|
invitor: data.invitor || "",
|
||||||
nationalcode: data.nationalcode || "",
|
nationalcode: data.nationalcode || "",
|
||||||
base: data.base || "",
|
base: data.base || "",
|
||||||
|
group: data.group
|
||||||
}));
|
}));
|
||||||
if (data.name)
|
if (data.name)
|
||||||
setPreviewImage(getContactImageUrl((data as any).stageID) ?? "");
|
setPreviewImage(getContactImageUrl((data as any).stageID) ?? "");
|
||||||
|
|
@ -150,7 +152,7 @@ export function RegisterPage() {
|
||||||
queryKey: ["userProfile"],
|
queryKey: ["userProfile"],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onError: (error: any) => {
|
onError: (error: Error) => {
|
||||||
console.error("Registration error:", error);
|
console.error("Registration error:", error);
|
||||||
toast.error(
|
toast.error(
|
||||||
"خطا در ثبت نام: " + (error?.message || "لطفاً دوباره تلاش کنید")
|
"خطا در ثبت نام: " + (error?.message || "لطفاً دوباره تلاش کنید")
|
||||||
|
|
@ -289,7 +291,6 @@ export function RegisterPage() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
{/* مقطع تحصیلی */}
|
|
||||||
<BaseDropdown
|
<BaseDropdown
|
||||||
label="مقطع تحصیلی"
|
label="مقطع تحصیلی"
|
||||||
name="education_level"
|
name="education_level"
|
||||||
|
|
@ -362,6 +363,15 @@ export function RegisterPage() {
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
<CustomInput
|
||||||
|
label="گروه"
|
||||||
|
name="group"
|
||||||
|
type="text"
|
||||||
|
disabled={true}
|
||||||
|
value={formData.group || ""}
|
||||||
|
/>
|
||||||
|
|
||||||
<ImageUploader
|
<ImageUploader
|
||||||
label="عکس پروفایل "
|
label="عکس پروفایل "
|
||||||
previewImage={previewImage}
|
previewImage={previewImage}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
export interface RegistrationFormData {
|
export interface RegistrationFormData {
|
||||||
ValueP1224S1943StageID?: Number;
|
ValueP1224S1943StageID?: number;
|
||||||
username?: string;
|
username?: string;
|
||||||
WorkflowID?: string;
|
WorkflowID?: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -11,6 +11,7 @@ export interface RegistrationFormData {
|
||||||
image?: File | null;
|
image?: File | null;
|
||||||
nationalcode: string;
|
nationalcode: string;
|
||||||
base: string;
|
base: string;
|
||||||
|
group: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RegistrationResponse {
|
export interface RegistrationResponse {
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,10 @@ import {
|
||||||
saveFormService,
|
saveFormService,
|
||||||
} from "@modules/dashboard/service/dynamic-form.service";
|
} from "@modules/dashboard/service/dynamic-form.service";
|
||||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
import { useSearchParams } from "react-router-dom";
|
import { MoveLeft } from "lucide-react";
|
||||||
|
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
|
import { DASHBOARD_ROUTE } from "../../routes/route.constant";
|
||||||
import { getCampaignStepsService } from "../../service/campaigns.service";
|
import { getCampaignStepsService } from "../../service/campaigns.service";
|
||||||
import DynamicForm from "./dynamic-form";
|
import DynamicForm from "./dynamic-form";
|
||||||
import type { CampaignProcess, FilterData, GroupedCampaign } from "./step-form.type";
|
import type { CampaignProcess, FilterData, GroupedCampaign } from "./step-form.type";
|
||||||
|
|
@ -18,9 +20,13 @@ import type { CampaignProcess, FilterData, GroupedCampaign } from "./step-form.t
|
||||||
const StepFormPage: FC = () => {
|
const StepFormPage: FC = () => {
|
||||||
const [fields, setFields] = useState<LocalFieldDefinition[]>([]);
|
const [fields, setFields] = useState<LocalFieldDefinition[]>([]);
|
||||||
const [params] = useSearchParams();
|
const [params] = useSearchParams();
|
||||||
|
// const { campaignId, groupId } = useParams();
|
||||||
|
|
||||||
|
const navigate = useNavigate()
|
||||||
const stageID = params.get("stageID");
|
const stageID = params.get("stageID");
|
||||||
const processID = params.get("processID");
|
const processID = params.get("processID");
|
||||||
|
const campaignId = params.get("campaignId")
|
||||||
|
const groupId = params.get("groupId")
|
||||||
|
|
||||||
|
|
||||||
const { data, isLoading, error } = useQuery<WorkflowResponse>({
|
const { data, isLoading, error } = useQuery<WorkflowResponse>({
|
||||||
|
|
@ -34,7 +40,7 @@ const StepFormPage: FC = () => {
|
||||||
|
|
||||||
const { data: steps } = useQuery({
|
const { data: steps } = useQuery({
|
||||||
queryKey: ["dynamic-step"],
|
queryKey: ["dynamic-step"],
|
||||||
queryFn: () => getCampaignStepsService(),
|
queryFn: () => getCampaignStepsService(Number(campaignId), Number(groupId)),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -243,6 +249,9 @@ const StepFormPage: FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
toast.success("ثبت نام با موفقیت انجام شد");
|
toast.success("ثبت نام با موفقیت انجام شد");
|
||||||
|
navigate(
|
||||||
|
`${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.steps}/${campaignId}/${groupId}`
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onError: (error: any) => {
|
onError: (error: any) => {
|
||||||
console.error("Registration error:", error);
|
console.error("Registration error:", error);
|
||||||
|
|
@ -262,6 +271,11 @@ const StepFormPage: FC = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
navigate(
|
||||||
|
`${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.steps}/${campaignId}/${groupId}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
|
|
@ -282,9 +296,16 @@ const StepFormPage: FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container mx-auto p-4">
|
<div className="container mx-auto p-4">
|
||||||
<h1 className="text-2xl font-bold mb-6 text-right font-vazir">
|
<div className="mb-6">
|
||||||
فرم پویا
|
<button
|
||||||
</h1>
|
onClick={handleBack}
|
||||||
|
className="flex items-center gap-2 text-blue-600 hover:text-blue-800 transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50 rounded-md p-2"
|
||||||
|
>
|
||||||
|
<MoveLeft className="rotate-180" size={20} />
|
||||||
|
بازگشت به صفحه قبل
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-row justify-center gap-10">
|
<div className="flex flex-row justify-center gap-10">
|
||||||
{currentStep?.map((el, idx) => {
|
{currentStep?.map((el, idx) => {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,11 @@ import type {
|
||||||
} from "./step.type";
|
} from "./step.type";
|
||||||
|
|
||||||
const StepsPage: FC = () => {
|
const StepsPage: FC = () => {
|
||||||
const { campaignId } = useParams<{ campaignId: string }>();
|
const { campaignId, groupId } = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { data, isLoading, error } = useQuery({
|
const { data, isLoading, error } = useQuery({
|
||||||
queryKey: ["dynamic-step"],
|
queryKey: ["dynamic-step"],
|
||||||
queryFn: () => getCampaignStepsService(),
|
queryFn: () => getCampaignStepsService(Number(campaignId), Number(groupId)),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -82,7 +82,7 @@ const StepsPage: FC = () => {
|
||||||
|
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
navigate(
|
navigate(
|
||||||
`${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.campaigns}/${campaignId}`
|
`${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.campaigns}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -90,19 +90,20 @@ const StepsPage: FC = () => {
|
||||||
|
|
||||||
const handleStepClick = (step: GroupedCampaign) => {
|
const handleStepClick = (step: GroupedCampaign) => {
|
||||||
const filteIncompleteProcess = step.processes.filter(el => el.status === 'انجام نشده')
|
const filteIncompleteProcess = step.processes.filter(el => el.status === 'انجام نشده')
|
||||||
|
// `${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.steps}/${campId}/${group_id}`
|
||||||
|
|
||||||
if (filteIncompleteProcess.length > 0) {
|
if (filteIncompleteProcess.length > 0) {
|
||||||
const firstItem = filteIncompleteProcess[0]
|
const firstItem = filteIncompleteProcess[0]
|
||||||
if (firstItem.stageId) {
|
if (firstItem.stageId) {
|
||||||
navigate(
|
navigate(
|
||||||
`${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.dynamicForm}?stageID=${firstItem.stageId}`,
|
`${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.dynamicForm}?stageID=${firstItem.stageId}&campaignId=${campaignId}&groupId=${groupId}`,
|
||||||
{
|
{
|
||||||
replace: true,
|
replace: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (firstItem.processId) {
|
if (firstItem.processId) {
|
||||||
navigate(
|
navigate(
|
||||||
`${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.dynamicForm}?processID=${firstItem.processId}`,
|
`${DASHBOARD_ROUTE.sub}/${DASHBOARD_ROUTE.dynamicForm}?processID=${firstItem.processId}&campaignId=${campaignId}&groupId=${groupId}`,
|
||||||
{
|
{
|
||||||
replace: true,
|
replace: true,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ export const dashboardRoutes: AppRoute[] = [
|
||||||
element: <CampaignDetailPage />,
|
element: <CampaignDetailPage />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: `${DASHBOARD_ROUTE.joinToCampaing}/:id`,
|
path: `${DASHBOARD_ROUTE.joinToCampaing}/:scoolId/:campId`,
|
||||||
element: <JoinToCampaing />,
|
element: <JoinToCampaing />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +39,7 @@ export const dashboardRoutes: AppRoute[] = [
|
||||||
element: <StepFormPage />,
|
element: <StepFormPage />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: `${DASHBOARD_ROUTE.steps}`,
|
path: `${DASHBOARD_ROUTE.steps}/:campaignId/:groupId`,
|
||||||
element: <StepsPage />,
|
element: <StepsPage />,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ import type {
|
||||||
CreateCampaignData,
|
CreateCampaignData,
|
||||||
SignatureItem,
|
SignatureItem,
|
||||||
} from "@modules/dashboard/pages/campaigns/campaigns.type";
|
} from "@modules/dashboard/pages/campaigns/campaigns.type";
|
||||||
import type { User } from "@modules/dashboard/pages/join-to-campaing/join-to-campaing";
|
|
||||||
import to from "await-to-js";
|
import to from "await-to-js";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
|
import type { User } from "../pages/join-to-campaing/join-to-campaing";
|
||||||
|
|
||||||
export const getCampaignsService = async (): Promise<Campaign[]> => {
|
export const getCampaignsService = async (): Promise<Campaign[]> => {
|
||||||
const userStr = userInfoService.getUserInfo();
|
const userStr = userInfoService.getUserInfo();
|
||||||
|
|
@ -165,6 +165,63 @@ export const getSelectedCampaignsService = async (
|
||||||
return data[0];
|
return data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getCampaignStepsService = async (campId: number, groupId: number) => {
|
||||||
|
const query = {
|
||||||
|
ProcessName: "run_process",
|
||||||
|
OutputFields: ["*"],
|
||||||
|
conditions: [
|
||||||
|
["campaign_id", "=", campId, "and"],
|
||||||
|
["group_id", "=", groupId],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const [err, res] = await to(api.post(API_ADDRESS.select, query));
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.data.resultType !== 0) {
|
||||||
|
toast.error("خطا در دریافت مراحل کارزار");
|
||||||
|
throw new Error("خطا در دریافت مراحل کارزار");
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = JSON.parse(res.data.data);
|
||||||
|
if (!data || Object.keys(data).length === 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getclassmateNickName = async (schoolId: number): Promise<Array<User>> => {
|
||||||
|
const query = {
|
||||||
|
ProcessName: "user",
|
||||||
|
OutputFields: ["nickname"],
|
||||||
|
"conditions": [
|
||||||
|
[
|
||||||
|
"school_code",
|
||||||
|
"=",
|
||||||
|
schoolId
|
||||||
|
]
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const [err, res] = await to(api.post(API_ADDRESS.select, query));
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.data.resultType !== 0) {
|
||||||
|
toast.error("خطا در دریافت مراحل کارزار");
|
||||||
|
throw new Error("خطا در دریافت مراحل کارزار");
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = JSON.parse(res.data.data);
|
||||||
|
if (!data || Object.keys(data).length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
export const createCampaignService = async (
|
export const createCampaignService = async (
|
||||||
data: CreateCampaignData
|
data: CreateCampaignData
|
||||||
): Promise<Campaign> => {
|
): Promise<Campaign> => {
|
||||||
|
|
@ -245,6 +302,41 @@ export const addCommentService = async (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const createCircleService = async (
|
||||||
|
circleName: string,
|
||||||
|
campId: string,
|
||||||
|
memberIds: number[]
|
||||||
|
): Promise<{ group_id: number }> => {
|
||||||
|
|
||||||
|
const members = Object.fromEntries(
|
||||||
|
Array.from({ length: memberIds.length }, (_, i) => [`member_id${i + 1}`, memberIds[i]])
|
||||||
|
);
|
||||||
|
const body = {
|
||||||
|
"group_save_function": {
|
||||||
|
...members,
|
||||||
|
"title": circleName,
|
||||||
|
"campaign_id": campId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const [err, res] = await to(api.post(API_ADDRESS.save, body));
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
toast.error("خطا در ایجاد محفل");
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.data.resultType !== 0) {
|
||||||
|
toast.error(res.data.message || "خطا در ایجاد محفل");
|
||||||
|
throw new Error("خطا در ایجاد محفل");
|
||||||
|
}
|
||||||
|
toast.success("محفل با موفقیت ایجاد شد");
|
||||||
|
|
||||||
|
const parsed = JSON.parse(res.data.data);
|
||||||
|
return { group_id: Number(parsed.group_id) };
|
||||||
|
};
|
||||||
|
|
||||||
export const removeCommentService = async (
|
export const removeCommentService = async (
|
||||||
commentId: number
|
commentId: number
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
|
|
@ -264,89 +356,3 @@ export const removeCommentService = async (
|
||||||
throw new Error("خطا در حذف نظر");
|
throw new Error("خطا در حذف نظر");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const searchUsersService = async (nickname: string): Promise<User[]> => {
|
|
||||||
if (!nickname) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const query = {
|
|
||||||
ProcessName: "users",
|
|
||||||
OutputFields: ["nickname", "user_id"],
|
|
||||||
conditions: [["nickname", "like", `%${nickname}%`]],
|
|
||||||
};
|
|
||||||
|
|
||||||
const [err, res] = await to(api.post(API_ADDRESS.select, query));
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
toast.error("خطا در جستجوی کاربر");
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.data.resultType !== 0) {
|
|
||||||
toast.error("خطا در جستجوی کاربر");
|
|
||||||
throw new Error("خطا در جستجوی کاربر");
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = JSON.parse(res.data.data);
|
|
||||||
return data || [];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createCircleService = async (
|
|
||||||
circleName: string,
|
|
||||||
memberIds: string[]
|
|
||||||
)=> {
|
|
||||||
const user = userInfoService.getUserInfo();
|
|
||||||
|
|
||||||
const body = {
|
|
||||||
ProcessName: "circle",
|
|
||||||
circle: {
|
|
||||||
circle_name: circleName,
|
|
||||||
creator_id: user.username,
|
|
||||||
status: "فعال",
|
|
||||||
},
|
|
||||||
members: memberIds.map((id) => ({ user_id: id })),
|
|
||||||
};
|
|
||||||
|
|
||||||
const [err, res] = await to(api.post(API_ADDRESS.save, body));
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
toast.error("خطا در ایجاد محفل");
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.data.resultType !== 0) {
|
|
||||||
toast.error(res.data.message || "خطا در ایجاد محفل");
|
|
||||||
throw new Error("خطا در ایجاد محفل");
|
|
||||||
}
|
|
||||||
|
|
||||||
toast.success("محفل با موفقیت ایجاد شد");
|
|
||||||
return res.data;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getCampaignStepsService = async () => {
|
|
||||||
const query = {
|
|
||||||
ProcessName: "run_process",
|
|
||||||
OutputFields: ["*"],
|
|
||||||
conditions: [
|
|
||||||
["campaign_id", "=", "18909", "and"],
|
|
||||||
["group_id", "=", "18950"],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const [err, res] = await to(api.post(API_ADDRESS.select, query));
|
|
||||||
if (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.data.resultType !== 0) {
|
|
||||||
toast.error("خطا در دریافت مراحل کارزار");
|
|
||||||
throw new Error("خطا در دریافت مراحل کارزار");
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = JSON.parse(res.data.data);
|
|
||||||
if (!data || Object.keys(data).length === 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ export const fetchUserProfile = async () => {
|
||||||
"school_code.title",
|
"school_code.title",
|
||||||
"invitor",
|
"invitor",
|
||||||
"nationalcode",
|
"nationalcode",
|
||||||
|
"user_group.title"
|
||||||
|
,
|
||||||
],
|
],
|
||||||
conditions: [["username", "=", person.ID ? person.ID : person.username]],
|
conditions: [["username", "=", person.ID ? person.ID : person.username]],
|
||||||
};
|
};
|
||||||
|
|
@ -44,6 +46,7 @@ export const fetchUserProfile = async () => {
|
||||||
schoolCode: user?.school_code,
|
schoolCode: user?.school_code,
|
||||||
invitor: user?.invitor,
|
invitor: user?.invitor,
|
||||||
nationalcode: user?.nationalcode,
|
nationalcode: user?.nationalcode,
|
||||||
|
group: user.user_group_title
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user