<|start_filename|>lib/atom_tweaks_web/controllers/admin/release_note_controller.ex<|end_filename|>
defmodule AtomTweaksWeb.Admin.ReleaseNoteController do
  @moduledoc """
  Handles all admin release notes resource routes.
  """

  use AtomTweaksWeb, :controller

  alias AtomTweaks.Releases
  alias AtomTweaks.Releases.Note

  @doc """
  Creates a new release note.
  """
  @spec create(Plug.Conn.t(), Map.t()) :: Plug.Conn.t()
  def create(conn, params)

  def create(conn, %{"note" => note_params}) do
    %Note{}
    |> Note.changeset(note_params)
    |> Repo.insert()
    |> case do
      {:ok, note} -> redirect(conn, to: Routes.admin_release_note_path(conn, :show, note))
      {:error, changeset} -> render(conn, :new, changeset: changeset)
    end
  end

  def delete(conn, %{"id" => id}) do
    id
    |> Releases.get_note!()
    |> Releases.delete_note()
    |> case do
      {:ok, _note} -> redirect(conn, to: Routes.admin_release_note_path(conn, :index))
      {:error, changeset} -> render(conn, :edit, changeset: changeset)
    end
  end

  @doc """
  Displays the edit form for a release note.
  """
  @spec edit(Plug.Conn.t(), Map.t()) :: Plug.Conn.t()
  def edit(conn, params)

  def edit(conn, %{"id" => id}) do
    note = Releases.get_note!(id)
    changeset = Releases.change_note(note)

    render(conn, "edit.html", changeset: changeset, note: note)
  end

  @doc """
  Renders the list of release notes.
  """
  @spec index(Plug.Conn.t(), Map.t()) :: Plug.Conn.t()
  def index(conn, _params) do
    notes = Releases.list_notes()

    render(conn, "index.html", notes: notes)
  end

  @doc """
  Renders the new form for a release note.
  """
  @spec new(Plug.Conn.t(), Map.t()) :: Plug.Conn.t()
  def new(conn, _params) do
    changeset = Releases.change_note(%Note{})

    render(conn, "new.html", changeset: changeset)
  end

  @doc """
  Renders the release note with the given `id`.
  """
  @spec show(Plug.Conn.t(), Map.t()) :: Plug.Conn.t()
  def show(conn, params)

  def show(conn, %{"id" => id}) do
    note = Releases.get_note!(id)

    render(conn, "show.html", note: note)
  end

  @doc """
  Updates a release note.
  """
  @spec update(Plug.Conn.t(), Map.t()) :: Plug.Conn.t()
  def update(conn, params)

  def update(conn, %{"id" => id, "note" => note_params}) do
    note = Releases.get_note!(id)

    note
    |> Note.changeset(note_params)
    |> Repo.update()
    |> case do
      {:ok, note} ->
        redirect(conn, to: Routes.admin_release_note_path(conn, :show, note))

      {:error, changeset} ->
        render(conn, "edit.html", changeset: changeset, note: note, errors: changeset.errors)
    end
  end
end


<|start_filename|>lib/atom_tweaks.ex<|end_filename|>
defmodule AtomTweaks do
  @moduledoc """
  The AtomTweaks module contains [Phoenix contexts](https://hexdocs.pm/phoenix/contexts.html) that
  define the domain and business logic for the application.

  Contexts are also responsible for managing your data, regardless if it comes from the database, an
  external API or others.
  """
end


<|start_filename|>assets/webpack.config.js<|end_filename|>
const path = require('path')

const CopyWebpackPlugin = require('copy-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const env = process.env.MIX_ENV || 'dev'
const isProduction = (env === 'prod')
const mode = env === 'prod' ? 'production' : 'development'

module.exports = {
  devtool: 'source-map',
  entry: ['./js/app.js', './css/app.scss'],
  mode: mode,
  module: {
    rules: [
      {
        test: /\.scss$/,
        include: /css/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [
            {
              loader: 'css-loader'
            },
            {
              loader: 'sass-loader',
              options: {
                sassOptions: {
                  includePaths: [
                    path.resolve(__dirname, 'node_modules')
                  ],
                  outputStyle: 'compressed'
                },
                sourceMap: !isProduction
              }
            }
          ]
        })
      },
      {
        test: /\.tsx?$/,
        use: [
          {loader: 'ts-loader'}
        ]
      }
    ]
  },
  output: {
    path: path.resolve(__dirname, '../priv/static'),
    filename: 'js/app.js'
  },
  plugins: [
    new CopyWebpackPlugin({
      patterns: [
        {
          from: './static'
        }
      ]
    }),
    new ExtractTextPlugin('css/app.css')
  ],
  resolve: {
    extensions: [
      '.js',
      '.jsx',
      '.ts',
      '.tsx'
    ],
    modules: [
      'node_modules',
      path.resolve(__dirname, './js')
    ]
  }
}


<|start_filename|>mix.exs<|end_filename|>
defmodule AtomTweaks.Mixfile do
  use Mix.Project

  def project do
    [
      app: :atom_tweaks,
      version: "0.1.0",
      name: "Atom Tweaks",
      homepage_url: "https://www.atom-tweaks.com",
      source_url: "https://github.com/lee-dohm/atom-style-tweaks",
      elixir: "~> 1.9",
      elixirc_paths: elixirc_paths(Mix.env()),
      compilers: [:phoenix, :gettext] ++ Mix.compilers(),
      build_embedded: Mix.env() == :prod,
      start_permanent: Mix.env() == :prod,
      aliases: aliases(),
      deps: deps(),
      docs: docs(),
      test_coverage: [tool: ExCoveralls, test_task: "test"],
      preferred_cli_env: [
        coveralls: :test,
        "coveralls.html": :test,
        "coveralls.travis": :test
      ]
    ]
  end

  def application do
    [
      mod: {
        AtomTweaks.Application,
        []
      },
      extra_applications: [:logger]
    ]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  defp deps do
    [
      # Full dependencies
      {:cmark, "~> 0.8"},
      {:ex_debug_toolbar, "~> 0.5"},
      {:gettext, "~> 0.11"},
      {:jason, "~> 1.1"},
      {:navigation_history, "~> 0.2"},
      {:oauth2, "~> 2.0.0"},
      {:phoenix_ecto, "~> 3.0"},
      {:phoenix_html, "~> 2.6"},
      {:phoenix_octicons, "~> 0.6"},
      {:phoenix_pubsub, "~> 1.0"},
      {:phoenix_slime, "~> 0.13.0"},
      {:phoenix, "~> 1.4.6"},
      {:plug_cowboy, "~> 2.0"},
      {:plug_ribbon, "~> 0.2"},
      # Required for ex_debug_toolbar
      {:poison, "~> 3.0"},
      {:postgrex, ">= 0.0.0"},
      {:sentry, "~> 7.2.0"},
      {:timex, "~> 3.1"},

      # Dev dependencies
      {:credo, "~> 1.4.0", only: [:dev, :test], runtime: false},
      {:dotenv, "~> 3.0.0", only: :dev},
      {:ex_doc, "~> 0.16", only: [:dev, :test], runtime: false},
      {:ex_machina, "~> 2.0", only: :test},
      {:excoveralls, "~> 0.6", only: :test},
      {:faker_elixir_octopus, "~> 1.0", only: :test},
      {:floki, "~> 0.23.0", only: [:dev, :test]},
      {:html_entities, "~> 0.4.0", only: [:dev, :test]},
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:pseudoloc, "~> 0.2", only: [:dev, :test]},
      {:uuid, "~> 1.1", only: [:dev, :test]}
    ]
  end

  defp aliases do
    [
      "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
      "ecto.ci": ["ecto.create", "ecto.migrate"],
      "ecto.reset": ["ecto.drop", "ecto.setup"],
      translate: ["gettext.extract", "gettext.merge priv/gettext", "pseudoloc priv/gettext"]
    ]
  end

  defp docs do
    [
      main: "readme",
      extras: [
        "CODE_OF_CONDUCT.md",
        "CONTRIBUTING.md",
        "README.md": [
          filename: "readme",
          title: "README"
        ],
        "LICENSE.md": [
          filename: "license",
          title: "License"
        ]
      ],
      groups_for_modules: [
        Accounts: [
          ~r{^AtomTweaks\.Accounts}
        ],
        Controllers: [
          ~r{^AtomTweaks.*Controller$}
        ],
        "Ecto Types": [
          ~r{^AtomTweaks.Ecto.*}
        ],
        Helpers: [
          ~r{^AtomTweaks.*Helpers$}
        ],
        Localization: [
          AtomTweaksWeb.Gettext
        ],
        Markdown: [
          ~r{Markdown}
        ],
        Notes: [
          ~r{^AtomTweaks.Notes}
        ],
        OAuth: [
          AtomTweaksWeb.GitHub
        ],
        Plugs: [
          AtomTweaksWeb.HerokuMetadata,
          AtomTweaksWeb.PageMetadata,
          AtomTweaksWeb.PageMetadata.Metadata,
          AtomTweaksWeb.SlidingSessionTimeout,
          AtomTweaksWeb.TokenAuthentication
        ],
        Primer: [
          ~r{^AtomTweaksWeb\.Primer}
        ],
        Releases: [
          ~r{^AtomTweaks\.Releases}
        ],
        Sockets: [
          ~r{^AtomTweaksWeb.*Socket$}
        ],
        Test: [
          ~r{^AtomTweaks(Web)?\..*Case$},
          ~r{^AtomTweaks(Web?)\.Shared},
          ~r{^AtomTweaks.Factory$},
          ~r{^AtomTweaks.Support},
          ~r{^Support}
        ],
        Tweaks: [
          ~r{^AtomTweaks\.Tweaks}
        ],
        Views: [
          ~r{^AtomTweaksWeb.*View$}
        ]
      ],
      nest_modules_by_prefix: [
        AtomTweaks,
        AtomTweaksWeb,
        Support
      ]
    ]
  end
end
