Skip to content

Commit

Permalink
feat(ticket-office): add ticket-office instead of scanr contact
Browse files Browse the repository at this point in the history
  • Loading branch information
Mihoub2 committed Oct 7, 2024
1 parent a7e1d0a commit 7412a29
Show file tree
Hide file tree
Showing 5 changed files with 242 additions and 128 deletions.
7 changes: 7 additions & 0 deletions client/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ server {
proxy_set_header Content-Type application/json;
client_max_body_size 10M;
}
location ~ ^/ticket/(.*)$ {
proxy_pass https://ticket-office.staging.dataesr.ovh/$1;
proxy_set_header Authorization 'Basic $TICKET_OFFICE_API_KEY';
proxy_set_header Accept application/json;
proxy_set_header Content-Type application/json;
client_max_body_size 10M;
}
location ~ ^/mistral/(.*)$ {
proxy_pass https://api.mistral.ai/v1/$1;
proxy_set_header Authorization 'Bearer $MISTRAL_KEY';
Expand Down
103 changes: 62 additions & 41 deletions client/src/components/contact-form/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import { Button, ButtonGroup, Notice, TextArea, TextInput, useDSFRConfig } from "@dataesr/dsfr-plus";
import {
Button,
ButtonGroup,
Notice,
TextArea,
TextInput,
useDSFRConfig,
} from "@dataesr/dsfr-plus";
import { useState } from "react";
import useForm from "../../hooks/useForm";
import { useMutation } from "@tanstack/react-query";
import { useNavigate } from "react-router-dom";
import { createIntl, RawIntlProvider } from "react-intl";
import { postHeadersTicketOffice } from "../../config/api";

const modules = import.meta.glob('./locales/*.json', { eager: true, import: 'default' })
const modules = import.meta.glob("./locales/*.json", {
eager: true,
import: "default",
});
const messages = Object.keys(modules).reduce((acc, key) => {
const locale = key.match(/\.\/locales\/(.+)\.json$/)?.[1];
if (locale) {
return { ...acc, [locale]: modules[key] }
return { ...acc, [locale]: modules[key] };
}
return acc;
}, {});
Expand All @@ -22,6 +33,9 @@ type FormState = {
message?: string;
id?: string;
type?: string;
fromApplication?: string;
objectId?: string;
objectType?: string;
};

const validate = (form: FormState) => {
Expand All @@ -36,92 +50,99 @@ const validate = (form: FormState) => {
errors.message = "Ce champ est obligatoire";
}
return errors;
}
};

type Props = {
id?: string;
type?: string;
}


objectId?: string;
objectType?: string;
};

export default function ContactForm({ id, type }: Props) {
export default function ContactForm({ objectId, objectType }: Props) {
const { locale } = useDSFRConfig();
const intl = createIntl({ locale, messages: messages[locale] });
const navigate = useNavigate();
const api = (id && type) ? "contribute" : "contact"
const api = objectId && objectType ? "contribute" : "contacts";
const [thanks, setThanks] = useState(false);
const { isPending, isError, mutate } = useMutation({
mutationFn: async (data: FormState) => {
const resp = await fetch(`https://scanr-api.dataesr.ovh/${api}`, {
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" },
});
if (resp.status !== 201) throw new Error("error");
let payload = { ...data };

if (api === "contacts") {
payload = { ...payload, fromApplication: "scanr" };
}
if (api === "contribute") {
payload = { ...payload, objectId, objectType };
}
const resp = await fetch(
`https://ticket-office.staging.dataesr.ovh/api/${api}`,
{
method: "POST",
body: JSON.stringify(payload),
headers: {
"Content-Type": "application/json",
...postHeadersTicketOffice,
},
}
);

if (resp.status !== 200) throw new Error("error");
return resp.json();
},

onSuccess: () => {
setThanks(true);
},
onError: (e) => {
console.error("error", e)
console.error("error", e);
},
});

const { form, updateForm, errors, } = useForm<FormState, FormState>({ id, type }, validate);
const { form, updateForm, errors } = useForm<FormState, FormState>(
{},
validate
);

if (thanks) {
return (
<RawIntlProvider value={intl}>
<Notice className="fr-mb-2w" type="success" closeMode="disallow">
<span>{intl.formatMessage({ id: "contact.thanks.message" })}</span>
<ButtonGroup className="fr-mt-5w" isInlineFrom="xs">
<Button
variant="secondary"
onClick={() => navigate(-1)}
>
<Button variant="secondary" onClick={() => navigate(-1)}>
{intl.formatMessage({ id: "contact.thanks.return" })}
</Button>
</ButtonGroup>
</Notice>
</RawIntlProvider >
</RawIntlProvider>
);
}
if (isError) {
return (
<RawIntlProvider value={intl}>
<Notice className="fr-mb-2w" type="error" closeMode="disallow">
<span>
{intl.formatMessage({ id: "contact.error.message" })}
</span>
<span>{intl.formatMessage({ id: "contact.error.message" })}</span>
<ButtonGroup className="fr-mt-5w" isInlineFrom="xs">
<Button
onClick={() => {
setThanks(false)
setThanks(false);
}}
>
{intl.formatMessage({ id: "contact.error.retry" })}
</Button>
<Button
variant="secondary"
onClick={() => navigate(-1)}
>
<Button variant="secondary" onClick={() => navigate(-1)}>
{intl.formatMessage({ id: "contact.error.return" })}
</Button>
</ButtonGroup>
</Notice>
</RawIntlProvider >
</RawIntlProvider>
);
}

return (
<RawIntlProvider value={intl}>

<form
onSubmit={(e) => {
e.preventDefault();
mutate(form)
mutate(form);
}}
>
<TextInput
Expand All @@ -133,7 +154,6 @@ export default function ContactForm({ id, type }: Props) {
message={errors?.name}
messageType={errors?.name ? "error" : undefined}
disableAutoValidation

/>
<TextInput
value={form.email}
Expand Down Expand Up @@ -170,9 +190,10 @@ export default function ContactForm({ id, type }: Props) {
messageType={errors?.message ? "error" : undefined}
disableAutoValidation
/>
<Button disabled={isPending} type="submit">Envoyer le message</Button>
<Button disabled={isPending} type="submit">
Envoyer le message
</Button>
</form>
</RawIntlProvider >

</RawIntlProvider>
);
}
}
8 changes: 8 additions & 0 deletions client/src/config/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ const {
VITE_API_URL: API_URL,
VITE_API_KEY: API_KEY,
VITE_TOPICS_URL: TOPICS_URL,
VITE_TICKET_OFFICE_API_KEY: TICKET_OFFICE_API_KEY,
} = import.meta.env;

// Headers
export const headers = API_KEY ? { Authorization: `Basic ${API_KEY}` } : {};
export const postHeaders = { ...headers, "Content-Type": "application/json" };
export const ticketOfficeHeaders = TICKET_OFFICE_API_KEY
? { Authorization: `Basic ${TICKET_OFFICE_API_KEY}` }
: {};
export const postHeadersTicketOffice = {
...ticketOfficeHeaders,
"Content-Type": "application/json",
};

// Indices
export const publicationsIndex = `${API_URL}/scanr-publications`;
Expand Down
41 changes: 26 additions & 15 deletions client/src/pages/bugs/[api]/[id]/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { Breadcrumb, Col, Container, Link, Row, Title, Text, useDSFRConfig } from "@dataesr/dsfr-plus";
import {
Breadcrumb,
Col,
Container,
Link,
Row,
Title,
Text,
useDSFRConfig,
} from "@dataesr/dsfr-plus";
import ContactForm from "../../../../components/contact-form";
import { RawIntlProvider, createIntl } from "react-intl";
import { useParams } from "react-router-dom";
Expand Down Expand Up @@ -28,24 +37,23 @@ const API_MAPPING = {
publications: "publications",
authors: "persons",
patents: "productions",
}
};

const API_LABEL_KEY = {
organizations: ["label", true],
projects: ["label", true],
publications: ["title", true],
authors: ["fullName", false],
patents: ["title", true],
}

};

const API_GETTERS = {
organizations: getOrganizationById,
projects: getProjectById,
publications: getPublicationById,
authors: getAuthorById,
patents: getPatentById,
}
};

export default function BugsReport() {
const { locale } = useDSFRConfig();
Expand All @@ -60,12 +68,13 @@ export default function BugsReport() {
const [displayNameKey, isLangField] = API_LABEL_KEY[api];
if (!messages) return null;


return (
<RawIntlProvider value={intl}>
<Container>
<Breadcrumb>
<Link href="/">{intl.formatMessage({ id: "contribute.breadcrumb.home" })}</Link>
<Link href="/">
{intl.formatMessage({ id: "contribute.breadcrumb.home" })}
</Link>
<Link>
{intl.formatMessage({ id: "contribute.breadcrumb.page" })}
</Link>
Expand All @@ -74,22 +83,24 @@ export default function BugsReport() {
{intl.formatMessage({ id: "contribute.title" })}
</Title>
<Text>
<span className="fr-text--sm">{intl.formatMessage({ id: "contribute.description" })}</span>
<span className="fr-text--sm">
{intl.formatMessage({ id: "contribute.description" })}
</span>
<br />
<em className="fr-text--bold">
{isLangField ? getLangFieldValue(locale)(data?.[displayNameKey]) : data?.[displayNameKey]}
{isLangField
? getLangFieldValue(locale)(data?.[displayNameKey])
: data?.[displayNameKey]}
</em>
<br />
<em className="fr-text-mention--grey">
{data?.id}
</em>
<em className="fr-text-mention--grey">{data?.id}</em>
</Text>
<Row>
<Col xs={12} lg={7}>
<ContactForm id={id} type={API_MAPPING?.[api]} />
<ContactForm objectId={id} objectType={API_MAPPING?.[api]} />
</Col>
</Row>
</Container>
</RawIntlProvider >
</RawIntlProvider>
);
}
}
Loading

0 comments on commit 7412a29

Please sign in to comment.