-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add github workflow and basic models
- Loading branch information
1 parent
a351907
commit ee96078
Showing
15 changed files
with
728 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
name: Build and upload docker image | ||
|
||
on: | ||
push: | ||
branches: ["main"] | ||
pull_request: | ||
branches: ["main"] | ||
|
||
env: | ||
REGISTRY: ghcr.io | ||
IMAGE_NAME: ${{ github.repository }} | ||
|
||
jobs: | ||
build-and-push-image: | ||
runs-on: ubuntu-latest | ||
|
||
permissions: | ||
contents: read | ||
packages: write | ||
attestations: write | ||
id-token: write | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Log in to the Container registry | ||
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 | ||
with: | ||
registry: ${{ env.REGISTRY }} | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Extract metadata (tags, labels) for Docker | ||
id: meta | ||
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 | ||
with: | ||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | ||
|
||
- name: Build and push Docker image | ||
id: push | ||
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 | ||
with: | ||
context: . | ||
push: true | ||
tags: ${{ steps.meta.outputs.tags }} | ||
labels: ${{ steps.meta.outputs.labels }} | ||
|
||
- name: Generate artifact attestation | ||
uses: actions/attest-build-provenance@v1 | ||
with: | ||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} | ||
subject-digest: ${{ steps.push.outputs.digest }} | ||
push-to-registry: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
defmodule Mentat.Activities do | ||
@moduledoc """ | ||
The Activities context. | ||
""" | ||
|
||
import Ecto.Query, warn: false | ||
alias Mentat.Repo | ||
|
||
alias Mentat.Activities.ActivityRecord | ||
|
||
@doc """ | ||
Returns the list of activity_records. | ||
## Examples | ||
iex> list_activity_records() | ||
[%ActivityRecord{}, ...] | ||
""" | ||
def list_activity_records do | ||
Repo.all(ActivityRecord) | ||
end | ||
|
||
@doc """ | ||
Gets a single activity_record. | ||
Raises `Ecto.NoResultsError` if the Activity record does not exist. | ||
## Examples | ||
iex> get_activity_record!(123) | ||
%ActivityRecord{} | ||
iex> get_activity_record!(456) | ||
** (Ecto.NoResultsError) | ||
""" | ||
def get_activity_record!(id), do: Repo.get!(ActivityRecord, id) | ||
|
||
@doc """ | ||
Creates a activity_record. | ||
## Examples | ||
iex> create_activity_record(%{field: value}) | ||
{:ok, %ActivityRecord{}} | ||
iex> create_activity_record(%{field: bad_value}) | ||
{:error, %Ecto.Changeset{}} | ||
""" | ||
def create_activity_record(attrs \\ %{}) do | ||
%ActivityRecord{} | ||
|> ActivityRecord.changeset(attrs) | ||
|> Repo.insert() | ||
end | ||
|
||
@doc """ | ||
Updates a activity_record. | ||
## Examples | ||
iex> update_activity_record(activity_record, %{field: new_value}) | ||
{:ok, %ActivityRecord{}} | ||
iex> update_activity_record(activity_record, %{field: bad_value}) | ||
{:error, %Ecto.Changeset{}} | ||
""" | ||
def update_activity_record(%ActivityRecord{} = activity_record, attrs) do | ||
activity_record | ||
|> ActivityRecord.changeset(attrs) | ||
|> Repo.update() | ||
end | ||
|
||
@doc """ | ||
Deletes a activity_record. | ||
## Examples | ||
iex> delete_activity_record(activity_record) | ||
{:ok, %ActivityRecord{}} | ||
iex> delete_activity_record(activity_record) | ||
{:error, %Ecto.Changeset{}} | ||
""" | ||
def delete_activity_record(%ActivityRecord{} = activity_record) do | ||
Repo.delete(activity_record) | ||
end | ||
|
||
@doc """ | ||
Returns an `%Ecto.Changeset{}` for tracking activity_record changes. | ||
## Examples | ||
iex> change_activity_record(activity_record) | ||
%Ecto.Changeset{data: %ActivityRecord{}} | ||
""" | ||
def change_activity_record(%ActivityRecord{} = activity_record, attrs \\ %{}) do | ||
ActivityRecord.changeset(activity_record, attrs) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
defmodule Mentat.Activities.ActivityRecord do | ||
use Ecto.Schema | ||
import Ecto.Changeset | ||
|
||
@required_fields [:start_time, :end_time, :value, :measuring_scale, :user_id, :provider_id] | ||
@optional_fields [:tags, :details] | ||
|
||
@primary_key {:id, :binary_id, autogenerate: true} | ||
@foreign_key_type :binary_id | ||
schema "activity_records" do | ||
field :value, :decimal | ||
field :details, :map | ||
field :start_time, :utc_datetime | ||
field :end_time, :utc_datetime | ||
field :tags, {:array, :string} | ||
|
||
field :measuring_scale, Ecto.Enum, | ||
values: [ | ||
work_min: 1, | ||
side_project_min: 2, | ||
steps: 3, | ||
steps_distance: 4, | ||
floors: 5, | ||
workout_min: 6, | ||
coffees: 7, | ||
alcoholic_drinks: 8, | ||
sleep_min: 9, | ||
sleep_light_min: 10, | ||
sleep_deep_min: 11, | ||
sleep_rem_min: 12, | ||
sleep_awake_min: 13, | ||
sleep_awakenings: 14, | ||
meditation_min: 15, | ||
weight: 16, | ||
heartrate: 17, | ||
heartrate_resting: 18, | ||
heartrate_variability: 19, | ||
reading_min: 20 | ||
] | ||
|
||
belongs_to :user, User | ||
belongs_to :provider, Provider | ||
|
||
timestamps(type: :utc_datetime) | ||
end | ||
|
||
@doc false | ||
def changeset(activity_record, attrs) do | ||
activity_record | ||
|> cast(attrs, @required_fields ++ @optional_fields) | ||
|> validate_required(@required_fields) | ||
end | ||
end |
112 changes: 112 additions & 0 deletions
112
lib/mentat_web/live/activity_record_live/form_component.ex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
defmodule MentatWeb.ActivityRecordLive.FormComponent do | ||
use MentatWeb, :live_component | ||
|
||
alias Mentat.Integrations | ||
alias Mentat.Activities | ||
|
||
@impl true | ||
def render(assigns) do | ||
~H""" | ||
<div> | ||
<.header> | ||
<%= @title %> | ||
<:subtitle>Use this form to manage activity_record records in your database.</:subtitle> | ||
</.header> | ||
<.simple_form | ||
for={@form} | ||
id="activity_record-form" | ||
phx-target={@myself} | ||
phx-change="validate" | ||
phx-submit="save" | ||
> | ||
<.input field={@form[:start_time]} type="datetime-local" label="Start time" /> | ||
<.input field={@form[:end_time]} type="datetime-local" label="End time" /> | ||
<.input field={@form[:value]} type="number" label="Value" step="any" /> | ||
<%!-- <.input --%> | ||
<%!-- field={@form[:tags]} --%> | ||
<%!-- type="select" --%> | ||
<%!-- multiple --%> | ||
<%!-- label="Tags" --%> | ||
<%!-- options={[{"Option 1", "option1"}, {"Option 2", "option2"}]} --%> | ||
<%!-- /> --%> | ||
<.input | ||
field={@form[:measuring_scale]} | ||
type="select" | ||
label="Measuring scale" | ||
prompt="Choose a value" | ||
options={Ecto.Enum.values(Mentat.Activities.ActivityRecord, :measuring_scale)} | ||
/> | ||
<.input | ||
field={@form[:provider_id]} | ||
type="select" | ||
label="Provider" | ||
prompt="Choose a value" | ||
options={Integrations.list_providers() |> Enum.map(&{&1.label, &1.id})} | ||
/> | ||
<:actions> | ||
<.button phx-disable-with="Saving...">Save Activity record</.button> | ||
</:actions> | ||
</.simple_form> | ||
</div> | ||
""" | ||
end | ||
|
||
@impl true | ||
def update(%{activity_record: activity_record} = assigns, socket) do | ||
{:ok, | ||
socket | ||
|> assign(assigns) | ||
|> assign_new(:form, fn -> | ||
to_form(Activities.change_activity_record(activity_record)) | ||
end)} | ||
end | ||
|
||
@impl true | ||
def handle_event("validate", %{"activity_record" => activity_record_params}, socket) do | ||
changeset = | ||
Activities.change_activity_record(socket.assigns.activity_record, activity_record_params) | ||
|
||
{:noreply, assign(socket, form: to_form(changeset, action: :validate))} | ||
end | ||
|
||
def handle_event("save", %{"activity_record" => activity_record_params}, socket) do | ||
save_activity_record(socket, socket.assigns.action, activity_record_params) | ||
end | ||
|
||
defp save_activity_record(socket, :edit, activity_record_params) do | ||
case Activities.update_activity_record(socket.assigns.activity_record, activity_record_params) do | ||
{:ok, activity_record} -> | ||
notify_parent({:saved, activity_record}) | ||
|
||
{:noreply, | ||
socket | ||
|> put_flash(:info, "Activity record updated successfully") | ||
|> push_patch(to: socket.assigns.patch)} | ||
|
||
{:error, %Ecto.Changeset{} = changeset} -> | ||
{:noreply, assign(socket, form: to_form(changeset))} | ||
end | ||
end | ||
|
||
defp save_activity_record(socket, :new, activity_record_params) do | ||
case Activities.create_activity_record( | ||
Map.merge(activity_record_params, %{ | ||
"user_id" => socket.assigns.current_user.id | ||
}) | ||
) do | ||
{:ok, activity_record} -> | ||
notify_parent({:saved, activity_record}) | ||
|
||
{:noreply, | ||
socket | ||
|> put_flash(:info, "Activity record created successfully") | ||
|> push_patch(to: socket.assigns.patch)} | ||
|
||
{:error, %Ecto.Changeset{} = changeset} -> | ||
{:noreply, assign(socket, form: to_form(changeset))} | ||
end | ||
end | ||
|
||
defp notify_parent(msg), do: send(self(), {__MODULE__, msg}) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
defmodule MentatWeb.ActivityRecordLive.Index do | ||
use MentatWeb, :live_view | ||
|
||
alias Mentat.Activities | ||
alias Mentat.Activities.ActivityRecord | ||
|
||
@impl true | ||
def mount(_params, _session, socket) do | ||
{:ok, stream(socket, :activity_records, Activities.list_activity_records())} | ||
end | ||
|
||
@impl true | ||
def handle_params(params, _url, socket) do | ||
{:noreply, apply_action(socket, socket.assigns.live_action, params)} | ||
end | ||
|
||
defp apply_action(socket, :edit, %{"id" => id}) do | ||
socket | ||
|> assign(:page_title, "Edit Activity record") | ||
|> assign(:activity_record, Activities.get_activity_record!(id)) | ||
end | ||
|
||
defp apply_action(socket, :new, _params) do | ||
socket | ||
|> assign(:page_title, "New Activity record") | ||
|> assign(:activity_record, %ActivityRecord{}) | ||
end | ||
|
||
defp apply_action(socket, :index, _params) do | ||
socket | ||
|> assign(:page_title, "Listing Activity records") | ||
|> assign(:activity_record, nil) | ||
end | ||
|
||
@impl true | ||
def handle_info({MentatWeb.ActivityRecordLive.FormComponent, {:saved, activity_record}}, socket) do | ||
{:noreply, stream_insert(socket, :activity_records, activity_record)} | ||
end | ||
|
||
@impl true | ||
def handle_event("delete", %{"id" => id}, socket) do | ||
activity_record = Activities.get_activity_record!(id) | ||
{:ok, _} = Activities.delete_activity_record(activity_record) | ||
|
||
{:noreply, stream_delete(socket, :activity_records, activity_record)} | ||
end | ||
end |
Oops, something went wrong.