Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/launch comments #62

Merged
merged 10 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ window.liveSocket = liveSocket
import './launch-cart-additem';
import './launch-cart';
import './launch-form';
import './launch-comments';
import './web-hooks';
import './form-emails';
import './launch-recaptcha';
3 changes: 2 additions & 1 deletion assets/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ import { LaunchCartElement } from "./launch-cart";
import { LaunchCartAddItemElement } from "./launch-cart-additem";
import { LaunchFormElement } from "./launch-form";
import { LaunchRecaptchaElement } from "./launch-recaptcha";
import { LaunchCommentsElement } from "./launch-comments";

export {LaunchCartAddItemElement, LaunchCartElement, LaunchFormElement, LaunchRecaptchaElement};
export {LaunchCartAddItemElement, LaunchCartElement, LaunchFormElement, LaunchRecaptchaElement, LaunchCommentsElement};
5 changes: 4 additions & 1 deletion assets/js/launch-cart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const formatPrice = (price) => {
},
events: {
send: ['checkout', 'remove_cart_item', 'increase_quantity', 'decrease_quantity'],
receive: ['checkout_redirect', 'cart_created', 'checkout_complete', 'livestate-error']
receive: ['checkout_redirect', 'livestate-error', 'cart_created', 'checkout_complete']
}
})
export class LaunchCartElement extends LitElement {
Expand Down Expand Up @@ -90,6 +90,9 @@ export class LaunchCartElement extends LitElement {
console.log('cart created')
window.localStorage.setItem('cart_id', e.detail.cart_id);
});
this.addEventListener('livestate-error', (e: CustomEvent<{ error: string }>) => {
console.error(e);
});
}

itemCount() {
Expand Down
106 changes: 106 additions & 0 deletions assets/js/launch-comments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { html, LitElement, css } from 'lit'
import { customElement, property, query, state } from 'lit/decorators.js'
import { liveState, liveStateConfig } from 'phx-live-state';

type Comment = {
author: string;
inserted_at: Date;
comment: string;
}

@customElement('launch-comments')
@liveState({
properties: ['comments'],
provide: {
scope: window,
name: 'launchCommentsState'
},
events: {
send: ['add_comment'],
receive: ['comment_added']
}
})
export class LaunchCommentsElement extends LitElement {

@property()
@liveStateConfig('url')
url: string = '';

@state()
comments: Array<Comment> = [];

@property({ attribute: 'site-id' })
siteId: string = '';

@liveStateConfig('topic')
get topic() { return `launch_comments:${this.siteId}`; }

@query('input[name="author"]')
author: HTMLInputElement | undefined;

@query('textarea[name="comment"]')
comment: HTMLTextAreaElement | undefined;

dateTimeFormatter = new Intl.DateTimeFormat('default');

addComment(e: Event) {
this.dispatchEvent(new CustomEvent('add_comment', {
detail: {
author: this.author?.value,
comment: this.comment?.value,
url: window.location.href,
comment_site_id: this.siteId
}
}));
e.preventDefault();
}

constructor() {
super();
this.addEventListener("comment_added", (e) => {
console.log(e);
this.clearNewComment();
});
}

clearNewComment() {
this.author!.value = '';
this.comment!.value = '';
}

formatDateTime(dateTime) {
const createdAt = new Date()
createdAt.setTime(Date.parse(dateTime))
return this.dateTimeFormatter.format(createdAt);
}

render() {
return html`
<div part="previous-comments">
${this.comments?.map(comment => html`
<div part="comment">
<div part="comment-text">${comment.comment}</div>
<div part="byline">
<span part="comment-author">${comment.author}</span> on <span
part="comment-created-at">${this.formatDateTime(comment.inserted_at)}</span>
</div>
</div>
`)}
</div>
<div part="new-comment">
<form part="form" @submit=${this.addComment}>
<div part="comment-field-author">
<label part="author-label" for="author">Author</label>
<input part="author-input" id="author" name="author" required>
</div>
<div part="comment-field-text">
<label part="comment-label" for="comment">Comment</label>
<textarea part="comment-input" id="comment" name="comment" required></textarea>
</div>
<button part="add-comment-button">Add Comment</button>
</form>
</div>
`;
}

}
2 changes: 1 addition & 1 deletion assets/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "launch-elements",
"description": "A set of custom elements to add an interactive functionality to your website",
"version": "0.2.0",
"version": "0.3.0",
"main": "dist/index.js",
"author": {
"email": "[email protected]",
Expand Down
18 changes: 18 additions & 0 deletions lib/factory.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ defmodule LaunchCart.Factory do
alias LaunchCart.Carts.Cart
alias LaunchCart.Carts.CartItem
alias LaunchCart.StripeAccounts.StripeAccount
alias LaunchCart.CommentSites.CommentSite
alias LaunchCart.Comments.Comment
alias LaunchCart.Forms.{Form, FormResponse, FormEmail}
alias LaunchCart.WebHooks.WebHook

Expand Down Expand Up @@ -83,4 +85,20 @@ defmodule LaunchCart.Factory do
subject: Lorem.words(2..4)
}
end

def comment_site_factory() do
%CommentSite{
user: build(:user),
name: "My Comment Site",
url: "https://launchscout.com"
}
end

def comment_factory() do
%Comment{
comment_site: build(:comment_site),
author: "Bob",
comment: "I think therefore I am"
}
end
end
109 changes: 109 additions & 0 deletions lib/launch_cart/comment_sites.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
defmodule LaunchCart.CommentSites do
@moduledoc """
The CommentSites context.
"""

import Ecto.Query, warn: false
alias LaunchCart.Repo

alias LaunchCart.CommentSites.CommentSite
alias LaunchCart.Accounts.User

@doc """
Returns the list of comment_sites.

## Examples

iex> list_comment_sites()
[%CommentSite{}, ...]

"""
def list_comment_sites do
Repo.all(CommentSite)
end

def list_comment_sites(%User{id: user_id}) do
Repo.all(from comment_site in CommentSite, where: comment_site.user_id == ^user_id)
end

@doc """
Gets a single comment_site.

Raises `Ecto.NoResultsError` if the Comment site does not exist.

## Examples

iex> get_comment_site!(123)
%CommentSite{}

iex> get_comment_site!(456)
** (Ecto.NoResultsError)

"""
def get_comment_site!(id), do: Repo.get!(CommentSite, id) |> Repo.preload([:comments])

@doc """
Creates a comment_site.

## Examples

iex> create_comment_site(%{field: value})
{:ok, %CommentSite{}}

iex> create_comment_site(%{field: bad_value})
{:error, %Ecto.Changeset{}}

"""
def create_comment_site(attrs \\ %{}) do
%CommentSite{}
|> CommentSite.changeset(attrs)
|> Repo.insert()
end

@doc """
Updates a comment_site.

## Examples

iex> update_comment_site(comment_site, %{field: new_value})
{:ok, %CommentSite{}}

iex> update_comment_site(comment_site, %{field: bad_value})
{:error, %Ecto.Changeset{}}

"""
def update_comment_site(%CommentSite{} = comment_site, attrs) do
comment_site
|> CommentSite.changeset(attrs)
|> Repo.update()
end

@doc """
Deletes a comment_site.

## Examples

iex> delete_comment_site(comment_site)
{:ok, %CommentSite{}}

iex> delete_comment_site(comment_site)
{:error, %Ecto.Changeset{}}

"""
def delete_comment_site(%CommentSite{} = comment_site) do
Repo.delete(comment_site)
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking comment_site changes.

## Examples

iex> change_comment_site(comment_site)
%Ecto.Changeset{data: %CommentSite{}}

"""
def change_comment_site(%CommentSite{} = comment_site, attrs \\ %{}) do
CommentSite.changeset(comment_site, attrs)
end
end
24 changes: 24 additions & 0 deletions lib/launch_cart/comment_sites/comment_site.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule LaunchCart.CommentSites.CommentSite do
use Ecto.Schema
import Ecto.Changeset
alias LaunchCart.Accounts.User
alias LaunchCart.Comments.Comment

@primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id
schema "comment_sites" do
field :name, :string
field :url, :string
belongs_to :user, User
has_many :comments, Comment

timestamps()
end

@doc false
def changeset(comment_site, attrs) do
comment_site
|> cast(attrs, [:name, :url, :user_id])
|> validate_required([:name, :url])
end
end
Loading
Loading