Compare commits
10 commits
e1237a6fa5
...
7239578f95
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7239578f95 | ||
|
|
628f9eefc3 | ||
|
|
62cdb0b745 | ||
|
|
cb4abfa38e | ||
|
|
1d0f08d3f0 | ||
|
|
b3c5bbba5a | ||
|
|
aa325d3d04 | ||
|
|
5805020cc1 | ||
|
|
c7188688e9 | ||
|
|
24f6886128 |
|
|
@ -11,7 +11,7 @@ COPY . .
|
|||
# Will build and cache the binary and dependent crates in release mode
|
||||
RUN --mount=type=cache,target=/usr/local/cargo,from=rust:latest,source=/usr/local/cargo \
|
||||
--mount=type=cache,target=target \
|
||||
cargo build --release --features datastore-adaptor && mv ./target/release/crabfit-api ./api
|
||||
cargo build --release --features sql-adaptor && mv ./target/release/crabfit-api ./api
|
||||
|
||||
# Runtime image
|
||||
FROM debian:bullseye-slim
|
||||
|
|
|
|||
|
|
@ -180,11 +180,22 @@ async fn get_stats_row(db: &DatabaseConnection) -> Result<stats::ActiveModel, Db
|
|||
})
|
||||
}
|
||||
|
||||
impl SqlAdaptor {
|
||||
pub async fn new() -> Self {
|
||||
fn get_connection_string() -> String {
|
||||
let connection_string =
|
||||
env::var("DATABASE_URL").expect("Expected DATABASE_URL environment variable");
|
||||
|
||||
if let Some(password_file_location) = env::var("DATABASE_PASSWORD_FILE") {
|
||||
|
||||
} else {
|
||||
connection_string
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl SqlAdaptor {
|
||||
pub async fn new() -> Self {
|
||||
let connection_string = get_connection_string();
|
||||
|
||||
// Connect to the database
|
||||
let db = Database::connect(&connection_string)
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
{
|
||||
"name": "How to Crab Fit",
|
||||
"name": "Como usar Crab Fit",
|
||||
|
||||
"p1": "Crab Fit is a tool that helps you when planning events with friends or coworkers. You just create an event, enter your availability, send it out, and see when everyone is free!",
|
||||
"p2": "See below for detailed steps of how to Crab Fit your event.",
|
||||
|
||||
"s1": "Step 1",
|
||||
"s1": "Paso 1",
|
||||
|
||||
"p3": "Use the form at <1>crab.fit</1> to make a new event. You only need to put in the rough time period for when your event occurs here, not your availability.",
|
||||
"p4": "For example, we'll use \"Jenny's Birthday Lunch\". Jenny wants her birthday lunch to happen on the same week as her birthday, the 15th of April, but she knows that not all of her friends are available on the 15th. She also doesn't want to do it on the weekend.",
|
||||
"p5": "Jenny also knows that since it's a lunch event, it can't start before 11am or go any later than 5pm.",
|
||||
|
||||
"s2": "Step 2",
|
||||
"s2": "Paso 2",
|
||||
|
||||
"p6": "Enter your availability for the event you just created.",
|
||||
"p7": "In our example, Jenny now puts in her availability for her birthday lunch. She is free all week, except after 3pm on Tuesday and Wednesday, and before 1pm on Friday.",
|
||||
|
||||
"s3": "Step 3",
|
||||
"s3": "Paso 3",
|
||||
|
||||
"p8": "Send the link to everyone you want to come.",
|
||||
"p9": "After Jenny has sent the link to her friends and waited for them to also fill out their availabilities, she can now easily see them all on the heatmap below and choose the darkest area for a time that suits everyone!",
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
"content": {
|
||||
"p1": "Crab Fit te ayuda a adaptar tu evento a los horarios de todos. Simplemente cree un evento arriba y envíe el enlace a todos los participantes. Los resultados se actualizan en vivo y podrá ver un mapa de calor de cuándo todos están libres.<1/><2>Obtenga más información sobre cómo Crab Fit.</2>",
|
||||
"p3": "Creado por <1>Ben Grant</1>, Crab Fit es la solución moderna para sus debates de planificación de eventos grupales.",
|
||||
"p4": "El código de Crab Fit es de código abierto, si encuentra algún problema o desea contribuir, puede visitar el <1>repositorio</1>. Al utilizar Crab Fit, acepta la <3>política de privacidad</3>.",
|
||||
"p4": "Crab Fit es de código abierto, si encuentra algún problema o desea contribuir, puede visitar el <1>repositorio</1>. Al utilizar Crab Fit, acepta la <3>política de privacidad</3>.",
|
||||
"p6": "Para proteger su privacidad, los eventos se eliminan después de 3 meses de inactividad y todas las contraseñas tienen un cifrado seguro.",
|
||||
"p5": "Considere hacer una donación a continuación si lo ayudó para que pueda ser gratuito para todos. 🦀"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ import { Temporal } from '@js-temporal/polyfill'
|
|||
*/
|
||||
export const calculateColumns = (dates: Temporal.ZonedDateTime[]): (Temporal.PlainDate | null)[] => {
|
||||
// Dedupe dates by date and sort
|
||||
const sortedDates = [...new Map(dates.map(d => {
|
||||
const sortedDates = Array.from(new Map(dates.map(d => {
|
||||
const plain = d.toPlainDate()
|
||||
return [plain.toString(), plain]
|
||||
})).values()]
|
||||
})).values())
|
||||
.sort(Temporal.PlainDate.compare)
|
||||
|
||||
// Partition by distance
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export const convertTimesToDates = (times: string[], timezone: string): Temporal
|
|||
|
||||
return times.map(time => isSpecificDates ?
|
||||
parseSpecificDate(time).withTimeZone(timezone)
|
||||
: parseWeekdayDate(time).withTimeZone(timezone)
|
||||
: parseWeekdayDate(time, timezone).withTimeZone(timezone)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ export const parseSpecificDate = (str: string): Temporal.ZonedDateTime => {
|
|||
}
|
||||
|
||||
// Parse from UTC `HHmm-d` format into a ZonedDateTime in UTC based on the current date
|
||||
const parseWeekdayDate = (str: string): Temporal.ZonedDateTime => {
|
||||
const parseWeekdayDate = (str: string, timezone: string): Temporal.ZonedDateTime => {
|
||||
if (str.length !== 6) {
|
||||
throw new Error('String must be in HHmm-d format')
|
||||
}
|
||||
|
|
@ -43,9 +43,20 @@ const parseWeekdayDate = (str: string): Temporal.ZonedDateTime => {
|
|||
|
||||
// Construct PlainDateTime from today
|
||||
const today = Temporal.Now.zonedDateTimeISO('UTC').round('day')
|
||||
const currentDayOfWeek = today.dayOfWeek
|
||||
return today.with({
|
||||
hour, minute,
|
||||
day: today.day + (dayOfWeek - currentDayOfWeek), // Set day of week
|
||||
const dayDelta = dayOfWeek - today.dayOfWeek
|
||||
const resultDay = today.add({ days: dayDelta })
|
||||
|
||||
let resultDate = resultDay.with({
|
||||
hour, minute
|
||||
})
|
||||
|
||||
// If resulting day (in target timezone) is in the next week, move it back to this week
|
||||
// TODO: change data representation instead
|
||||
const dayInTz = resultDate.withTimeZone(timezone)
|
||||
const todayInTz = today.withTimeZone(timezone)
|
||||
if (dayInTz.weekOfYear > todayInTz.weekOfYear) {
|
||||
resultDate = resultDate.subtract({ days: 7 })
|
||||
}
|
||||
|
||||
return resultDate
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue