Compare commits

..

10 commits

9 changed files with 152 additions and 40 deletions

17
README.md Normal file
View file

@ -0,0 +1,17 @@
# Coh@mail
Mail cli for Coh@bit.
> [!WARNING] Early preview Much more to come, stay up to date
## Installation
> [!WARNING] Currently bin manually added to [releases](./releases) tab.
## Basic usage
```sh
./cohamail -h
# OR
./cohamail <subcommand> -h
```

View file

@ -47,8 +47,7 @@ export const cmd = new Command()
})
}
if (from.startsWith('!')) {
//@ts-ignore try expand
return expand(from.slice(1))
return Contact.expand(from.slice(1))
}
return Contact.fromString(from)
})()

View file

@ -8,7 +8,7 @@
},
"tasks": {
"compile:send": "deno compile --allow-read --allow-env --allow-sys=osRelease --allow-run=mail,whoami ./cli/send.ts",
"cli": "deno run --allow-read --allow-env --allow-sys=osRelease,networkInterfaces --allow-run=/usr/sbin/sendmail,whoami ./cli.ts",
"cli": "deno run --allow-read --allow-env --allow-net=0.0.0.0 --allow-sys=osRelease,networkInterfaces --allow-run=/usr/sbin/sendmail,whoami ./cli.ts",
"utils:scp": "scp -O -P 55555 -i C:/Users/Julien/.ssh/id_ed25519_cohabit -r $(pwd) julien@cohabit.fr:/home/julien/cohabit_mail"
},
"fmt": {

View file

@ -21,12 +21,12 @@ export class Contact {
const { name, address } = custom[shortName as keyof typeof custom]
if (name !== 'string') {
if (typeof name !== 'string') {
throw new SyntaxError(
`missing key "name" in contact short name config for "${shortName}"`,
)
}
if (address !== 'string') {
if (typeof address !== 'string') {
throw new SyntaxError(
`missing key "address" in contact short name config for "${shortName}"`,
)

View file

@ -13,6 +13,13 @@ export async function send(mail: Mail) {
subject: mail.subject,
text,
html,
attachments: mail.options.attachments.map((path) => ({ path })),
attachments: [
{
cid: 'cohabit_logo.svg',
path: 'https://cohabit.fr/images/logo.svg',
filename: 'cohabit_logo.svg',
},
...mail.options.attachments.map((path) => ({ path })),
],
})
}

View file

@ -1,18 +1,19 @@
import { Body, Html, Markdown, Preview, Section, Text } from 'jsx-email'
import { Signature } from './_Signature.tsx'
import { Body, Container, Html, Markdown, Preview } from 'jsx-email'
import { Signature } from './components/Signature.tsx'
import type { Template } from '../types.ts'
import { BaseStyle, bodyCss, messageCss, textCss } from './styles/base.tsx'
function Message(
{ summary, body }: { summary?: string; body: string },
) {
return (
<Html lang='fr'>
<Html lang='fr' style={{ fontSize: '14px' }}>
<BaseStyle />
<Preview>{summary}</Preview>
<Body>
<Markdown>{body}</Markdown>
<Section>
<Text>Coh@bit</Text>
</Section>
<Body style={bodyCss}>
<Container style={messageCss}>
<Markdown style={textCss}>{body}</Markdown>
</Container>
<Signature />
</Body>
</Html>

View file

@ -4,12 +4,16 @@ import {
Container,
Heading,
Html,
Img,
Preview,
Section,
Text,
} from 'jsx-email'
import { Signature } from './_Signature.tsx'
import { Signature } from './components/Signature.tsx'
import type { Template } from '../types.ts'
import type { JSX } from 'preact'
import { bodyCss, messageCss, rootCss, textCss } from './styles/base.tsx'
import { BaseStyle } from './styles/base.tsx'
function Welcome(
{ firstname, lastname, login }: {
@ -19,23 +23,35 @@ function Welcome(
},
) {
return (
<Html lang='fr'>
<Html lang='fr' style={{ fontSize: '14px' }}>
<BaseStyle />
<Preview>Bienvenue au FabLab Coh@bit</Preview>
<Body>
<Container>
<Body style={bodyCss}>
<Container style={messageCss}>
<Section>
<Heading as='h1'>Bienvenue à Coh@bit</Heading>
<Text>
<Heading as='h1' style={headingCss}>
Bienvenue au<Img
src='cid:cohabit_logo.svg'
alt='FabLab Cohabit'
style={imgCss}
/>
</Heading>
<Text style={textCss}>
Bravo ! Vous avez rejoint le FabLab Coh@bit en tant que{' '}
{firstname} {lastname} (login:{' '}
{login}). Laissez parler votre créativité, vous êtes prêt à
collaborer avec toute une communauté ouverte et accueillante.
{firstname} {lastname}.
</Text>
<Text>
Comment débuter :
<Text style={textCss}>
Votre identifiant est <span style={preCss}>{login}</span>.
</Text>
<Text style={textCss}>
Laissez parler votre créativité, vous êtes prêt à collaborer avec
toute une communauté ouverte et accueillante.
</Text>
<Text style={textCss}>
Par commencer ?
</Text>
<ul>
<ul style={{ fontSize: '1rem' }}>
<li>
Accéder au <a href='https://cohabit.fr'>site de Coh@bit</a>{' '}
et découvrir le FabLab.
@ -69,9 +85,13 @@ function Welcome(
</li>
</ul>
<Button href='https://cohabit.fr/profile'>
Accéder à mon compte
</Button>
<Container
style={{ width: '100%', textAlign: 'center', padding: '1rem' }}
>
<Button href='https://cohabit.fr/profil' style={buttonCss}>
Accéder à mon compte
</Button>
</Container>
</Section>
</Container>
<Signature />
@ -80,6 +100,36 @@ function Welcome(
)
}
const headingCss: JSX.CSSProperties = {
fontFamily: 'Garamond, serif',
color: rootCss.accentColor,
textAlign: 'center',
margin: '-1rem 0 3rem',
fontSize: '2.5rem',
}
const preCss: JSX.CSSProperties = {
fontFamily: 'monospace',
fontSize: '1rem',
padding: '0.2rem',
borderRadius: '0.4rem',
backgroundColor: rootCss.backgroundColor,
}
const buttonCss: JSX.CSSProperties = {
color: 'white',
padding: '1rem',
borderRadius: '0.4rem',
fontSize: '1.2rem',
backgroundColor: rootCss.accentColor,
}
const imgCss: JSX.CSSProperties = {
display: 'inline',
padding: '1rem',
transform: 'translateY(40%)',
}
const template: Template<typeof Welcome, Parameters<typeof Welcome>[0]> = {
props: [
{

View file

@ -1,20 +1,20 @@
import { Container, Section, Text } from 'jsx-email'
import { Column, Container, Row, Text } from 'jsx-email'
export function Signature() {
return (
<Container>
<Section>
<Text>
<Container style={{ textAlign: 'center', fontSize: '12px' }}>
<Row>
<Column>
<a href='https://cohabit.fr'>Accéder au site </a>
</Text>
<Text>
</Column>
<Column>
<a href='tel:0556847961'>Nous téléphoner </a>
</Text>
<Text>
</Column>
<Column>
<a href='mailto:fablab@iut.u-bordeaux.fr'>Nous contacter </a>
</Text>
</Section>
<Text>
</Column>
</Row>
<Text style={{ fontSize: '12px' }}>
Coh@bit, IUT de Bordeaux, Bâtiment 10A, 15 rue Naudet, 33170 GRADIGNAN
</Text>
</Container>

38
templates/styles/base.tsx Normal file
View file

@ -0,0 +1,38 @@
import type { JSX } from 'preact'
export const rootCss = {
accentColor: '#48D200',
backgroundColor: '#F2E6DC',
} satisfies JSX.CSSProperties
export const bodyCss: JSX.CSSProperties = {
fontFamily: 'system-ui, "Trebuchet MS", sans-serif',
accentColor: rootCss.accentColor,
backgroundColor: rootCss.backgroundColor,
padding: '0.5rem 0',
}
export const messageCss: JSX.CSSProperties = {
padding: '1rem',
borderRadius: '0.4rem',
backgroundColor: 'white',
textWrap: 'balance',
}
export const textCss: JSX.CSSProperties = {
fontSize: '1rem',
}
export const rawCss = `
a {
color: ${rootCss.accentColor};
}
h1 {
color: ${rootCss.accentColor};
}
`
export function BaseStyle() {
return <style dangerouslySetInnerHTML={{ __html: rawCss }}></style>
}